2

I am developing plugins for a platform that loads plugin classes at runtime, and this platform uses old versions of the javax.persistence API (specifically version 1.0) whereas my plugin requires version 2.1 because it uses hibernate 4.3.5.Final.

I am looking for a way to remove all the classes in the current package 'javax.persistence' and load the newer javax.peristence classes built in my plugin jar at runtime. The platform my plugin runs on is built as a single jar and has all of its dependencies (including javax.persistence) built in the jar using the shade maven plugin, and this is the same for all the dependencies for a plugin.

So is it possible to accomplish this? to be able to replace a dependency on the classpath with a newer version at runtime? If it is not possible, or very hard, I could always fork the platform, and change the pom.xml to exclude javax.peristence classes from being shaded... but that is not preferable...

EDIT: another option is to write a small script to replace the class files in the jar before deploying. At least that will make it so I wouldn't have to manually replace the classes every time I need to update the platform

thanks.

Jon McPherson
  • 2,495
  • 4
  • 23
  • 35
  • 1
    I‘m not sure with your such deep question.Some advice:If the old javax.persistence's class loader is the same as your new apis,It seems OK.Another similar question in SO -> http://stackoverflow.com/questions/14316996/how-to-replace-classes-in-a-running-application-in-java – Ninja Jun 29 '14 at 17:05

1 Answers1

1

If you need to load classes at runtime you can use:

URLClassLoader child = new URLClassLoader (myJar.toURL(), this.getClass().getClassLoader());
Class classToLoad = Class.forName ("com.MyClass", true, child);
Method method = classToLoad.getDeclaredMethod ("myMethod");
Object instance = classToLoad.newInstance ();
Object result = method.invoke (instance);

But of course this will introduce a problem controlling your jars and of course a lack of security.

I fully recommend controlling your dependencies through maven.

By the way, if you have class conflicts you always can use the very useful maven goal dependency-tree to see what jar depends on other jar. Even if you need a deep analysis you can use dependency-analyze.

For further details about these very useful goals you can check this link:

http://maven.apache.org/plugins/maven-dependency-plugin/plugin-info.html

EDIT: as an update to this answer you can try JCL (java class loader framework) that looks interesting. Its description says:

JCL is a configurable, dynamic and extensible custom classloader that loads java classes directly from Jar files and other sources. The motivation was to create isolated classloaders, which can be easily integrated with IoC frameworks like Spring and with web applications.

And an example:

  JarClassLoader jcl = new JarClassLoader();

  //Loading classes from different sources
  jcl.add("myjar.jar");
  jcl.add(new URL("http://myserver.com/myjar.jar"));
  jcl.add(new FileInputStream("myotherjar.jar"));
  jcl.add("myclassfolder/");

  //Recursively load all jar files in the folder/sub-folder(s)
  jcl.add("myjarlib/");

  JclObjectFactory factory = JclObjectFactory.getInstance();

  //Create object of loaded class
  Object obj = factory.create(jcl, "mypack.MyClass");

Hope to help

Federico Piazza
  • 30,085
  • 15
  • 87
  • 123
  • The problem is that the platform as a maven dependency for my plugin uses the maven shade plugin to build its dependencies in the jar itself, so I cannot use maven to remove the conflicting classes from the built jar (that I know of). In other words, the javax.peristence package is already bundled in the platform jar that I use as a dependency. – Jon McPherson Jun 29 '14 at 17:05
  • This looks like a very useful library. It looks like this should do the job! However, I am currently looking into whether or not upgrading to javax.persistence 2.1 will break things... Anyways, thanks for the help! I will try this out. – Jon McPherson Jun 29 '14 at 17:13
  • @Waesel You can control what is going into the resulting jar with [maven-shade-plugin](http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html) – khmarbaise Jun 30 '14 at 07:29