简体   繁体   中英

What classloader does Play use when compiling classes with the JDT compiler?

I'm trying to write a Play plugin that adds jar files to the Play classpath at runtime. When onLoad is called it needs to load up a set of jars so that the JDT compiler can use them to resolve dependencies in the application classes. These jar files are not in the standard lib/ directory and therefore are not loaded up into the system classpath when Play starts.

Actually loading the jar file is not a problem, I'm going to specify each jar file I need as a URL and then pass those to an instance of URLClassLoader .

After a lot of research I've made the assumption that the classloader that Play uses is in Play.classloader and my initial plan was to create my own classloader that extends Play.ApplicationClassloader . This classloader would use an instance of URLClassLoader to find classes before delegating to the standard functionality in Play.ApplicationClassloader . I was then going to replace the Play classloader with my new instance:

Play.classloader = new MyExtensionClassLoader();

The problem I'm hitting is that the JDT compiler doesn't seem to use the Play.classloader instance to load it's classes.

So I have two questions:

What classpath is the JDT compiler actually using if it's not using the Play.classloader instance?

More generally, does anyone have any suggestions how I load a jar into Play at runtime so that the JDT compiler can use it?

I don't think that will work.

Play has its own classloader which first checks if a class is "a managed play application class" (the one that gets compiled with the JDT compiler runtime), then it fallbacks to the parent classloader which is the default jvm-one..

So all playframework-core classes and other libraries like Hibernate-classes are all loaded as regular classes from the default jvm-classloader.

I hope you understand me :)

-morten

I think your problem is that you cannot modify which java.lang.Classloader is parent-classloader for ApplicationClassloader.

If you look in the constructor you see that it always picks the classloader which ApplicationClassloader.class was loaded from.

If you could send parent-classloader as param to ApplicationClassloader's constructor, then you could do this:

create new ClassloaderA extends java.lang.Classloader with parent-classloader as JVM-default. Then in ClassloaderA, override findClass and getResourceAsStream to look in your jar-files before looking in parent. then you could give Play.classloader a new instance of ApplicationClassloader with an instance of ClassloaderA as its parent classloader.

I think this will make the Classloader-hirarchy correct..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM