aspose file tools*
The moose likes Java in General and the fly likes Dynamic class loading Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Dynamic class loading" Watch "Dynamic class loading" New topic
Author

Dynamic class loading

surlac surlacovich
Ranch Hand

Joined: Mar 12, 2013
Posts: 296

I have a factory method, that returns concrete Factories. These factories create Products.
I want to put factory method to separate jar, so it won't depend on concrete factories.
To instantiate concrete Factory I pass prefix (like "First", "Second"), by this prefix I want to load class ("FirstFactory") from different jar, then create Product from it.
Will it work in my case and will it load all dependent classes for concrete factory? Maybe there is a better approach.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42292
    
  64
What are you trying to achieve by separating the code into individual jar files?


Ping & DNS - my free Android networking tools app
surlac surlacovich
Ranch Hand

Joined: Mar 12, 2013
Posts: 296

Ability to support additional Product without modifying jar with Factory.
So I just add new jar to the classpath, supply Factory with argument "NewProduct" it instantiates a new Concrete Factory from new jar and creates new type of Product.
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2409
    
  28

There are several ways of doing this, each one has it's complications and pitfalls. There is a lot more to this that you have to think through. THe whole idea of "being able to deploy a new product by just dropping a jar" is an awesome awesome idea, but it's much more complicated than it ooks at first glance

a) You can use reflection to load the concrete class

you need to define an interfac which is the contract between your main code and the deployed jar. The jar contains a concrete implementation. The class name of the concrete class is in a configuration file somewhere. You can use reflection to load the class, instantiate the object, and use it via the interface

This is simple enough. The problem is that what happens when the jar that contains the concrete implementation needs other jar files (like hibernate.. or capache commons etc). You need to put those dependency jar files in your classpath soemwhow. SO, you have to figure out to deploy a package of jar files into your application, not just one jar file. Also, what happens if this jar needs other jars that are not compatible with the jars you have already deployed. Let's say you are using Hibernate 4, and it needs Hibernate 3. You have entered another dimension, a dimension not just of class loading and garbage collection, a journey into a bug infested land whose boundaries are only limited by how late you can work. That's the signpost up ahead - Welcome to JAR Hell When the same class file appears twice in the classpath, the JVM doesn't guarantee which one it will load. So, it might start loading Hibernate 3 classes, and your whole thing will go to shit. Worse yet, it might load some version 4 classes and some version 3 classes for the same library. You will pull your hair out when that happens

b) Use custom classloader
You could isolate the classes that you load for the "drop-in" jar using your own custom classloader. This will solve JAR hell.. somewhat..but this is a little difficult to implement. You still have the problem of deploying apackage of jars

c) OSGi
OSGi provides a lot of services that allow you to do this. But, it's a bigger learning curve.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42292
    
  64
Yes, this sounds like a typical use case for OSGi. Containers like Apache Karaf try to make it easy, but as Jayesh said, there's a non-trivial learning curve involved.
surlac surlacovich
Ranch Hand

Joined: Mar 12, 2013
Posts: 296

Jayesh A Lalwani wrote:
a) You can use reflection to load the concrete class

you need to define an interfac which is the contract between your main code and the deployed jar. The jar contains a concrete implementation. The class name of the concrete class is in a configuration file somewhere. You can use reflection to load the class, instantiate the object, and use it via the interface
...
c) OSGi
OSGi provides a lot of services that allow you to do this. But, it's a bigger learning curve.


Thanks a lot, Jayesh! I use 1'st approach and load with reflection right now, and it works quite well. But I'm moving towards OSGi, because it looks like I can create OSGI-related code without intervention to application code in the jar, and gain all benefits of OSGi, but it's really a lot of thinks to learn. As you mentioned the configuration file should be located somewhere, right now I put in the same Factory method jar as properties file, but if I will add new concrete factory with a new jar I will need to modify this properties file in Factory method jar, which is not very convenient.
Where can I store these config files if I use OSGi? I've heard it is possible to define <key,value> pairs in console (Equinox, Felix), but not sure how.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Dynamic class loading