HK Agarwal
HK Agarwal

Reputation: 71

how to load same class from different jars

I have a class Client.java in two different jars jar1 & jar2 Now at run time i want to decide which Client.class loaded like

if (country==india){
         // load Client class of jar1
) else{
        load client class from jar2 
}

can i do that...

Upvotes: 7

Views: 8999

Answers (4)

bmargulies
bmargulies

Reputation: 100013

If you really have two copies a class, with exactly the same fully-qualified name, in two jars, then ...

If you want to be safe, you should not put either of them in the classpath of your default class loader. You will need to create two additional class loaders, and put one of the jars in each. You will need to obtain a Class for the two classes, and you will need to use reflection to create the instance of the one you want..

Upvotes: 5

Photoy Song
Photoy Song

Reputation: 1

I think you have 2 ways:

1) Define an Interface Client, and implements diferent classes, for example: IndiaClient and Country2Client; Then


    interface Client {...}
    class IndiaClient implements Client {...}
    class Country2Client implements Client {...}

    Client client;
    if (country==india){
        client = new IndiaClient();
    ) else{
        client = new Country2Client();
    }

2) Keep your way with the same class name in 2 different jar files, but you still need a interface or super class, and to use different ClassLoaders to load your Client classes:


    interface IClient {...}
    class Client implements IClient {...} // in jar1
    class Client implements IClient {...} // in jar2

    Class<IClient> clientClass;
    if (country==india){
        clientClass = classLoader1.loadClass("package.Client");
    ) else{
        clientClass = classLoader2.loadClass("package.Client");
    }
    IClient client = clientClass.newInstance();

  • As for how to get the classLoaders, you can refer to JDK documents.

Upvotes: 0

Jeff Storey
Jeff Storey

Reputation: 57192

If the 2 classes have the same package name, i.e. com.mycompany.Client, then you end up in a situation where it is somewhat arbitrary which version of Client is loaded. It comes down to which is on the classpath first. This is a JAR hell situation http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell.

This is a good situation to avoid but if you absolutely must have different versions of the same class, there are ways to do it. One way is to use a custom classloader and the classloader will know which version you need to do. This is not a trivial thing to do and can be difficult to manage. The OSGi framework is an alternative to help manage this (it uses custom classloaders under the hood), but I wouldn't use that if you just have one instance of a class as it is another framework that takes time and maintenance.

Bottom line: avoid the situation if you can and take the path of least resistance if you cannot.

If the classes do have different package names, @Casidiablo has provided a good answer.

Upvotes: 7

Cristian
Cristian

Reputation: 200080

You will have to use the "complete" name of the path. For example:

if (country==india){
         name.first.package.Client client = new name.first.package.Client();
} else{
         name.second.package.Client client = new name.second.package.Client();
}

Anyway... I'd try to avoid doing things like that... that make your code difficult to read and mantain.

Upvotes: 4

Related Questions