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.