Как получить доступ к java-классам в пакете по умолчанию?

Сейчас я работаю вместе с другими в проекте grails. Я должен написать некоторые Java-классы. Но мне нужен доступ к поисковому объекту, созданному с помощью groovy. Кажется, что этот объект должен быть помещен в пакет по умолчанию.

Мой вопрос: Есть ли способ получить доступ к этому объекту в пакете по умолчанию из Java-класса в именованном пакете?

Ответ 1

Вы не можете использовать классы в пакете по умолчанию из именованного пакета.
(Технически вы можете, как показано в Sharique Abdullah, ответить через API отражения, но классы из безымянного пространства имен не входят в область действия в объявлении импорта)

До J2SE 1.4 вы могли импортировать классы из пакета по умолчанию, используя такой синтаксис:

import Unfinished;

Это больше не разрешено. Поэтому для доступа к классу пакета по умолчанию из упакованного класса необходимо переместить класс пакета по умолчанию в собственный пакет.

Если у вас есть доступ к источнику, сгенерированному groovy, потребуется некоторая постобработка, чтобы переместить файл в выделенный пакет и добавить эту директиву "package" в начале.


Обновление 2014: ошибка 6975015, для JDK7 и JDK8, описывает еще более строгий запрет на импорт из неназванного пакета.

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


Андреас указывает в комментариях:

"почему [пакет по умолчанию] существует в первую очередь? ошибка проектирования?"

Нет, это умышленно.
JLS 7.4.2. Неназванные пакеты гласят: "Неназванные пакеты предоставляются платформой Java SE главным образом для удобства при разработке небольших или временных приложений или только в начале разработки".

Ответ 2

На самом деле вы можете.

Используя API отражений, вы можете получить доступ к любому классу. По крайней мере, я смог:)

Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");

Ответ 3

Используйте jarjar, чтобы переупаковать файл jar со следующим правилом:

rule * <target package name>[email protected]

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

Ответ 4

Вы можете использовать пакеты в коде Groovy, и все будет работать нормально.

Это может означать небольшую реорганизацию кода под grails-app и немного боль сначала, но в проекте с большими граалями просто имеет смысл организовывать вещи в пакетах. Мы используем стандартное соглашение об именовании пакетов com.foo.<app>.<package>.

Наличие всего в пакете по умолчанию становится препятствием для интеграции, как вы находите.

Контроллеры кажутся одним из артефактов Grails (или артефакта), которые не могут быть помещены в пакет Java. Наверное, я пока еще не понял Convention.; -)