как загрузить один и тот же класс из разных банок - PullRequest
6 голосов
/ 18 мая 2010

У меня есть класс Client.java в двух разных jar jar1 & jar2 Теперь во время выполнения я хочу решить, какой Client.class загружен как

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

могу я это сделать ...

Ответы [ 4 ]

7 голосов
/ 18 мая 2010

Если 2 класса имеют одинаковое имя пакета, то есть com.mycompany.Client, то вы попадаете в ситуацию, когда несколько произвольно выбирается какая версия клиента загружена. Это сводится к тому, что находится на пути к классу первым. Это JAR адская ситуация http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell.

Это хорошая ситуация, которую следует избегать, но если вам абсолютно необходимы разные версии одного и того же класса, есть способы сделать это. Одним из способов является использование пользовательского загрузчика классов, и загрузчик классов будет знать, какую версию вам нужно сделать. Это не тривиальная вещь, и с ней может быть трудно справиться. Каркас OSGi является альтернативой, помогающей справиться с этим (он использует собственные загрузчики классов под капотом), но я бы не стал использовать это, если у вас есть только один экземпляр класса, поскольку это другой каркас, который требует времени и обслуживания.

Итог: избегайте ситуации, если можете, и выбирайте путь наименьшего сопротивления, если не можете.

Если классы имеют разные имена пакетов, @Casidiablo предоставил хороший ответ.

4 голосов
/ 18 мая 2010

Вам нужно будет использовать «полное» имя пути. Например:

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

В любом случае ... Я бы старался избегать подобных вещей, которые затрудняют чтение и поддержание вашего кода.

3 голосов
/ 18 мая 2010

Если у вас действительно есть две копии класса с абсолютно одинаковым полным именем в двух банках, то ...

Если вы хотите быть в безопасности, вы не должны помещать из них в путь к классам загрузчика классов по умолчанию. Вам нужно будет создать два дополнительных загрузчика классов и поставить один из jar в каждый. Вам нужно будет получить класс для этих двух классов, и вам нужно будет использовать отражение, чтобы создать экземпляр того, который вы хотите ..

0 голосов
/ 04 ноября 2011

Я думаю, у вас есть 2 способа:

1) Определить клиент интерфейса и реализовать разные классы, например: IndiaClient и Country2Client; Тогда


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

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

2) Сохраняйте свой путь с одним и тем же именем класса в 2 разных jar-файлах, но вам все еще нужен интерфейс или суперкласс, и используйте разные ClassLoaders для загрузки ваших клиентских классов:


    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();

  • Что касается того, как получить classLoaders, вы можете обратиться к документам JDK.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...