Commit e3c881bf authored by Vít Kabele's avatar Vít Kabele

ClassLoader loads classes from ClassNode instance.

parent 1f42ec56
......@@ -33,14 +33,15 @@ class IsolatedDislClasses extends DislClasses {
IsolatedDislClasses(
final Set<DiSL.CodeOption> options,
final List<ClassNode> classNodes,
final Map<String, byte[]> allClasses
final Map<String, byte[]> allClasses,
final ClassLoader classLoader
)
throws ParserException,
ProcessorException,
ReflectionException
{
super( new IsolatedSnippetParser ( allClasses ) );
super( new IsolatedSnippetParser ( allClasses, classLoader ) );
InitMethod (snippetParser, options, classNodes);
......
......@@ -26,13 +26,19 @@ class IsolatedSnippetParser extends SnippetParser {
*/
private final Map<String, Class<?>> guardCache = new ConcurrentHashMap<> ();
private final ClassLoader classLoader;
/**
* Creates new instance of {@link IsolatedSnippetParser} class.
* @param allClasses
*/
IsolatedSnippetParser(final Map<String, byte[]> allClasses){
IsolatedSnippetParser(
final Map<String, byte[]> allClasses,
final ClassLoader classLoader
){
this.allClasses = allClasses;
this.classLoader = classLoader;
}
......@@ -47,7 +53,6 @@ class IsolatedSnippetParser extends SnippetParser {
Class<?> getGuard (final Type guardType) throws Reflection.MissingClassException {
if(guardType == null) return null;
final DiSLClassLoader bacl = new DiSLClassLoader ();
final String guardName = guardType.getClassName ();
// If the class definition is already in cache, return the cached value
......@@ -58,7 +63,7 @@ class IsolatedSnippetParser extends SnippetParser {
if ( !allClasses.containsKey (guardName + ".class") )
throw new Reflection.MissingClassException ("Requested class not found %", guardName);
final Class<?> c = bacl.createClass (guardName, allClasses.get(guardName + ".class"));
final Class<?> c = classLoader.createClass (guardName, allClasses.get(guardName + ".class"));
guardCache.put (guardName, c);
......
......@@ -8,15 +8,19 @@
*/
package ch.usi.dag.disl;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.ClassWriter;
/**
* This class is responsible for loading classes related to one {@link DiSL} instance.
*/
class DiSLClassLoader extends ClassLoader {
class ClassLoader extends java.lang.ClassLoader {
/**
* Create new instance of the {@link DiSLClassLoader} class.
* Create new instance of the {@link ClassLoader} class.
*/
DiSLClassLoader (){
ClassLoader (){
super();
}
......@@ -45,4 +49,19 @@ class DiSLClassLoader extends ClassLoader {
return defineClass (name,classBytes,0,classBytes.length);
}
/**
* Returns an class definition from given {@link ClassNode} instance.
* @param classNode Class node.
* @return Class definition.
*/
Class<?> createClass(final ClassNode classNode){
ClassWriter classWriter = new ClassWriter (ClassWriter.COMPUTE_FRAMES);
classNode.accept (classWriter);
return createClass ( classNode.name, classWriter.toByteArray () );
}
}
......@@ -54,7 +54,7 @@ public final class DiSL {
* Note that all classes loaded within the instance will keep the reference to this particular
* class loader instance and vice versa.
*/
private final DiSLClassLoader __classLoader = new DiSLClassLoader ();
private final ClassLoader __classLoader = new ClassLoader ();
/**
......@@ -195,8 +195,8 @@ public final class DiSL {
.flatMap (Collection::stream)
.collect ( Collectors.toMap (Map.Entry::getKey, Map.Entry::getValue) );
__dislClasses = new IsolatedDislClasses (__codeOptions, classNodes, allClasses);
__transformers = new IsolatedTransformers ( transformerList );
__dislClasses = new IsolatedDislClasses (__codeOptions, classNodes, allClasses, __classLoader);
__transformers = new IsolatedTransformers ( transformerList, __classLoader );
__excludedScopes = ExclusionSetFactory.prepare ( instrumentationJars );
}
......@@ -403,7 +403,7 @@ public final class DiSL {
final Set <String> changedMethods;
public InstrumentedClass (
InstrumentedClass (
final ClassNode classNode, final Set <String> changedMethods
) {
this.classNode = classNode;
......
......@@ -64,39 +64,56 @@ final class InstrumentationJar {
/**
* Returns the Class nodes of the DiSL classes.
* Complexity is O(n^2), but small sets are expected.
*
* @return ClassNodes of the DiSL classes specified in manifest file
* @throws InitializationException On input error
*/
List<ClassNode> getDislClasses() {
List<ClassNode> ClassNodes = new ArrayList<> ();
JarEntry je = null;
List<ClassNode> ClassNodes = allClasses ();
List<String> dislClasses = diSLManifest
.getDiSLClasses ()
.stream ()
.map( s -> s += ".class" )
.map( s -> s.replace ('.','/') )
.collect(Collectors.toList());
return ClassNodes
.stream ()
.filter ( s -> dislClasses.contains (s.name) )
.collect(Collectors.toList());
}
/**
* Gets all classes from the instrumentation.
*
* @return List of all classes in instrumentation.
*/
List<ClassNode> allClasses(){
List<ClassNode> classNodes = new ArrayList<> ();
JarEntry jarEntry = null;
try(JarInputStream jis = new JarInputStream ( new ByteArrayInputStream (JarBytes) ))
{
while((je = jis.getNextJarEntry ()) != null){
while((jarEntry = jis.getNextJarEntry ()) != null){
if(
!je.isDirectory () &&
dislClasses.contains (je.getName().replace("/",".") )
!jarEntry.isDirectory () &&
jarEntry.getName ().endsWith (".class")
){
ClassNodes.add ( ClassNodeHelper.SNIPPET.unmarshal (jis));
classNodes.add ( ClassNodeHelper.SNIPPET.unmarshal (jis) );
}
}
} catch( final Exception e){
throw new InitializationException (
e,
"failed to load DiSL class %s",
(je == null) ? "" : je.getName ()
(jarEntry == null) ? "" : jarEntry.getName ()
);
}
return ClassNodes;
return classNodes;
}
......
......@@ -19,14 +19,18 @@ import java.util.stream.Collectors;
*/
class IsolatedTransformers extends Transformers {
private final DiSLClassLoader classLoader = new DiSLClassLoader ();
private final ClassLoader classLoader;
/**
* Create new instance of {@link IsolatedTransformers} class.
* @param transformersList List of name, classBytes of transformer class
*/
IsolatedTransformers(List<Pair<String,byte[]>> transformersList){
IsolatedTransformers(
final List<Pair<String,byte[]>> transformersList,
final ClassLoader classLoader
){
this.classLoader = classLoader;
transformers = transformersList
.stream ()
.map (this::createTransformer)
......
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