Чтобы понять это, вам нужно понять, как классы и классная загрузка действительно работают на Java. Часто мы думаем о загрузке в терминах «classpath», но это массовое упрощение того, как все работает. Во многих Java SE envrionments это работает, но в многоуровневых средах, таких как OSGi, это усложняется.
По существу в классах Java находятся в области видимости три вещи:
- Имя
- Пакет
- ClassLoader
Вполне возможно иметь два экземпляра myPackage.MyClass загруженных в JVM не один раз, вам просто нужно несколько загрузчиков классов. Несмотря на то, что эти классы могут быть загружены из идентичных файлов .class, во время выполнения они будут разными. Это может вызвать большую путаницу при написании кода, как это:
MyClass c = (MyClass)obj;
и получить ClassNotFoundException: MyClass
.
Классы существуют в пакетах, и с этим существуют специальные правила видимости. Типы, методы и поля без видимой видимости видны для всех типов в одном пакете. Когда класс загружается, он ассоциируется с java.lang.reflect.Package, и правила видимости разрешаются, по существу, проверяя, что классы связаны с одним и тем же экземпляром java.lang.reflect.Package. Поэтому в случае mypackage.MyClass, если вы загружаете его дважды, используя два разных загрузчика классов, вы получите два экземпляра пакета для mypackage.
OSGi предназначен для поддержки многоуровневой загрузки классов, это позволяет одновременно иметь две разные версии класса или пакета в одной JVM. Это решает много проблем, вызванных, если у вас разные зависимости от версий. Он реализует это, используя другой Classloader для каждого пакета. Фрагменты работают по-разному, что связки в том, что они связаны с пакетом, а классы в них загружаются загрузчиком Classloader пакета, а не имеют свой собственный.
Чтобы связать это с исходным вопросом, если вы поместите свои тесты юнита в пакет (а не фрагмент), ваш класс будет загружен другим загрузчиком классов, поэтому он будет связан с другим экземпляром java. lang.reflect.Пакет, поэтому, когда JVM проверяет доступность элемента, он не удастся.
Я был бы очень заинтересован в хорошем ответе на эту тему! этот вопрос беспокоит меня также .... –
Если у вас есть пакет «my.awesome.plugin» в плагине MyAwesomePlugin и пакет «my.awesome.plugin» в плагине MyAwesomePluginTests, это полностью отдельные пакеты, которые просто одно и то же имя. – immibis