Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Важен ли порядок загрузки jar-ов?


Автор: Dims 16.2.2009, 16:50
У меня есть библиотека, в которой происходит загрузка ресурса вот при помощи такого кода в статической функции:

Код

ObjectInputStream in =
            new ObjectInputStream(new BufferedInputStream(input));
        Object obj = in.readObject();
        in.close();


Во время выполнения строки in.readObject ИНОГДА (в зависимости от того, в какой программе я использую библиотеку), возникает исключительная ситуация 

java.lang.ClassNotFoundException

При этом, тот класс, который она не может найти, вроде бы, присутствует в наборе используемых библиотек.

Такое впечатление, что в тот момент, когда выполняется указанная строка, джар с нужным классом просто ещё не подгрузился.

Может ли такое быть? Или она просто обязана искать класс в тот момент, когда это требуется?

Автор: ivg 16.2.2009, 19:18
Смотрите javadoc для метода http://java.sun.com/javase/6/docs/api/java/io/ObjectInputStream.html#resolveClass(java.io.ObjectStreamClass)
Цитата

The default implementation of this method in ObjectInputStream returns the result of calling

     Class.forName(desc.getName(), false, loader)
 
where loader is determined as follows: if there is a method on the current thread's stack whose declaring class was defined by a user-defined class loader (and was not a generated to implement reflective invocations), then loader is class loader corresponding to the closest such method to the currently executing frame; otherwise, loader is null.
 Т. е. происходит попытка загрузить
Цитата(Dims @  16.2.2009,  18:50 Найти цитируемый пост)
тот класс, который она не может найти
 ClassLoader'ом, которым был загружен класс, из метода которого, был вызван in.readObject();, т. е. в данном случае класс вашей библиотеки. Если класс сериализованного объекта находится в другом месте, таким образом, что класс-лоадер библиотеки не может его загрузить, то, конечно, такое исключение вылетает.
1. Можно держать классы библиотеки и сериализуемых объектов в одном месте (неудобно).
2. Расширить класс java.io.ObjectInputStream и переопределить метод(ы) загрузки классов, чтобы можно было использовать определённый класс-лоадер. В качестве примера класс https://fisheye.springframework.org/browse/spring-framework/trunk/org.springframework.core/src/main/java/org/springframework/core/ConfigurableObjectInputStream.java?r=148

Автор: Dims 16.2.2009, 20:10
А как-то можно определить лоадер, который не может сработать, чтобы объективно сравнить работу в версии, когда библиотека работает и когда нет?

Автор: ivg 16.2.2009, 20:24
Цитата(Dims @  16.2.2009,  22:10 Найти цитируемый пост)
А как-то можно определить лоадер, который не может сработать,

В классе вашей библиотеки
Код

ThisLibraryClass.class.getClassLoader();

Автор: Dims 25.2.2009, 20:29
Цитата(ivg @  16.2.2009,  19:18 Найти цитируемый пост)
1. Можно держать классы библиотеки и сериализуемых объектов в одном месте (неудобно).

А что означает "в одном месте"?

Автор: Dims 25.2.2009, 22:37
Вот я трассирую происходящее. Иду по вызовам функций. Везде один и тот же класслоадер. И вдруг -- бац -- в каком-то классе совершенно другой. 

Конкретно у меня везде WebappClassLoader, а в нужном месте вдруг StandardClassLoader.

Почему?


Автор: LSD 25.2.2009, 22:59
Скорее всего потому, что используется класс из библиотек веб контейнера, а не из веб приложения.

Что за класс?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)