Commit 98e36e86 authored by Vít Kabele's avatar Vít Kabele

Fixed the issue when guard methods were loaded using system class loader.

parent 79facd5f
Pipeline #3285 passed with stages
in 3 minutes and 49 seconds
......@@ -37,11 +37,16 @@ public class IsolatedDislClasses implements DislClasses {
*
* @param options Code options.
* @param classNodes ASM Class nodes containing information about instrumentation classes.
* @param allClasses Map of all classes available in received jar files.
* @throws ParserException
* @throws ProcessorException
* @throws ReflectionException
*/
IsolatedDislClasses(final Set<DiSL.CodeOption> options, List<ClassNode> classNodes)
IsolatedDislClasses(
final Set<DiSL.CodeOption> options,
final List<ClassNode> classNodes,
final Map<String, byte[]> allClasses
)
throws ParserException, ProcessorException, ReflectionException {
if (classNodes.isEmpty ()) {
......@@ -54,7 +59,7 @@ public class IsolatedDislClasses implements DislClasses {
//
final SnippetParser sp = new SnippetParser ();
final SnippetParser sp = new IsolatedSnippetParser ( allClasses );
final ArgProcessorParser app = new ArgProcessorParser ();
for (final ClassNode classNode : classNodes) {
......
/**
* This file is part of disl project
* Author: Vit Kabele <vit@kabele.me>
* Created on the 02/11/2018
*/
package ch.usi.dag.disl;
import org.objectweb.asm.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Load snippets using provided class bytes list.
*/
class IsolatedSnippetParser extends SnippetParser {
/**
* Provided class bytes list
*/
private final Map<String, byte[]> allClasses;
/**
* Guard cache to prevent attempts to reload a class multiple times.
*/
private final Map<String, Class<?>> guardCache = new ConcurrentHashMap<> ();
/**
* Creates new instance of {@link IsolatedSnippetParser} class.
* @param allClasses
*/
IsolatedSnippetParser(final Map<String, byte[]> allClasses){
this.allClasses = allClasses;
}
/**
* Gets the guard by type.
*
* @param guardType
* @return
* @throws Reflection.MissingClassException
*/
@Override
Class<?> getGuard (final Type guardType) throws Reflection.MissingClassException {
if(guardType == null) return null;
final ByteArrayClassLoader bacl = new ByteArrayClassLoader ();
final String guardName = guardType.getClassName ();
// If the class definition is already in cache, return the cached value
if ( guardCache.containsKey (guardName) )
return guardCache.get (guardName);
if ( !allClasses.containsKey (guardName + ".class") )
throw new Reflection.MissingClassException ("Requested class not found %", guardName);
final Class<?> c = bacl.createClass (guardName, allClasses.get(guardName + ".class"));
guardCache.put (guardName, c);
return c;
}
}
......@@ -61,10 +61,13 @@ class SnippetParser extends AbstractParser {
try {
final String className = AsmHelper.typeName (dislClass);
snippets.addAll (dislClass.methods.parallelStream ().unordered ()
.filter (this::__isSnippetCandidate)
.map (m -> __parseSnippetWrapper (className, m))
.collect (Collectors.toList ())
snippets.addAll (
dislClass
.methods
.stream ()
.filter (this::__isSnippetCandidate)
.map (m -> __parseSnippetWrapper (className, m))
.collect (Collectors.toList ())
);
} catch (final ParserRuntimeException e) {
......@@ -125,8 +128,10 @@ class SnippetParser extends AbstractParser {
final Marker marker = getMarker (data.marker, data.args);
final Scope scope = ScopeMatcher.forPattern (data.scope);
final Class<?> g = getGuard (data.guard);
final Method guard = GuardHelper.findAndValidateGuardMethod (
getGuard (data.guard), GuardHelper.snippetContextSet ()
g,
GuardHelper.snippetContextSet ()
);
final SnippetUnprocessedCode template = new SnippetUnprocessedCode (
......
......@@ -178,7 +178,14 @@ public final class DiSL {
.flatMap ( i -> i.getTransformers ().stream () )
.collect (Collectors.toList ());
final DislClasses dislClasses = new IsolatedDislClasses (codeOptions, classNodes);
final Map<String, byte[]> allClasses = instrumentationJars
.stream ()
.map (InstrumentationJar::getAllClasses)
.map (Map::entrySet)
.flatMap (Collection::stream)
.collect ( Collectors.toMap (Map.Entry::getKey, Map.Entry::getValue) );
final DislClasses dislClasses = new IsolatedDislClasses (codeOptions, classNodes, allClasses);
final Transformers transformers = new IsolatedTransformers ( transformerList );
final Set<Scope> excludedScopes = ExclusionSetFactory.prepare ( instrumentationJars );
......
......@@ -15,10 +15,7 @@ import org.objectweb.asm.tree.ClassNode;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
......@@ -103,6 +100,43 @@ final class InstrumentationJar {
}
/**
* Gets map of all classes available in jar file.
*
* @return Map of all classes, where key is in the format with dots and ends with .class
*/
Map<String, byte[]> getAllClasses(){
HashMap<String, byte[]> classes = new HashMap<> ();
JarEntry je = null;
try ( JarInputStream jis = new JarInputStream ( new ByteArrayInputStream (JarBytes)) ){
while( (je = jis.getNextJarEntry ()) != null ){
if(
!je.isDirectory () &&
je.getName ().endsWith (".class")
){
byte[] classbytes = new byte[ (int)je.getSize () ];
jis.read (classbytes, 0, (int)je.getSize ());
classes.put (je.getName ().replace ('/', '.'), classbytes);
}
}
} catch (final Exception e){
throw new InitializationException (
e,
"failed to load DiSL class %s",
(je == null) ? "" : je.getName ()
);
}
return classes;
}
/**
* Returns the transformer classes.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment