класс SomeClass в пакете x недоступен в com.a.y.x

Я пытаюсь отключить Spring IoC для нескольких классов Java и загрузить их непосредственно в какой-либо код Scala. Естественно, я обнаружил, что существуют конфликты пространств имен между пакетами, такими как

com.a.x.SomeClass

и

com.a.y.x.SomeClass

Я пытался использовать преобразователи пространства имен импорта, такие как

import com.a.y.x.{ SomeClass => YYYSomeClass }
import com.a.x{ SomeClass => XXXSomeClass }

Это очищает импорт, но обращение к этим классам позже в классах показывает ошибку при наведении курсора в Typesafe ScalaIDE и после чистых компиляций.

Когда я компилирую из плагина gradle scala или через Typesafe ScalaIDE со scala 2.10.2 или 2.10.3, я получаю следующий тип бесполезных сообщений об ошибках:

class SomeClass in package x cannot be accessed in com.a.y.x

Проблема возникает, если я пытаюсь использовать класс из com.a.y.x, у которого нет конфликта пространства имен. Если я попробую некоторые из флагов scalac, я также смогу получить предупреждение, которое немного отличается (на этапе ввода):

class SomeClass in package x cannot be accessed in y.this.x

Я действительно хотел бы знать, есть ли способ расширить первую ссылку на пакет. У меня возникли проблемы с настройкой проекта Eclipse для отладки компилятора scalac, и я не нашел флаг scalac, добавляющий полезную информацию к ошибке.

Ошибка возникает, когда я пытаюсь выполнить ctx.getBean("someClass").asInstanceOf[XXXSomeClass] или new XXXSomeClass.

Ссылка this из предупреждения заставляет меня думать, что происходит некоторая путаница с объектами. Я не думаю, что это проблема пути к классам в более крупном проекте, над которым я работаю, потому что удаление одного jar-файла лишает возможности разрешать импорт, однако я не могу воспроизвести его с помощью простых примеров классов в отдельном проекте.

Еще немного информации о классах Java — разные, конфликтующие пакеты Java находятся в отдельных jar-файлах, которые были скомпилированы версией Java версии 1.6. Это общедоступные классы верхнего уровня, хотя два из них являются синглтонами с частными конструкторами и соответствующими общедоступными статическими методами getInstance().


person n0741337    schedule 06.02.2014    source источник
comment
В таких случаях я бы оставил пакет x или y и использовал x.SomeClass или y.SomeClass (но, скорее всего, только для одного).   -  person user2864740    schedule 06.02.2014
comment
@user2864740 user2864740 - я пробовал полные пути без импорта и получал те же ошибки. Я думаю, что я также пробовал импортировать из одного пакета и полный путь к другому, но я проверю еще раз завтра.   -  person n0741337    schedule 06.02.2014
comment
@som-snytt - отношения классов в некоторых случаях сложнее - завтра я опубликую больше. Пакет класса scala по сравнению с java похож на package totally.unrelated. Не могли бы вы уточнить, какие аннотации, по вашему мнению, мне следует попробовать?   -  person n0741337    schedule 06.02.2014
comment
@som-snytt - хорошая идея - попробую завтра.   -  person n0741337    schedule 06.02.2014
comment
@som-snytt - К сожалению, это не сработало. Я даже зашел так далеко, что попробовал x: com.a.x.SomeClass = new com.a.x.SomeClass для всего в каждом из конфликтующих пакетов (а также удалил соответствующий импорт). Та же ошибка сохраняется.   -  person n0741337    schedule 06.02.2014
comment
@som-snytt - спасибо за ваше время. Я думаю, что это просто ужасное сообщение об ошибке от scalac и некоторая невнимательность с моей стороны со слишком большим количеством движущихся частей.   -  person n0741337    schedule 07.02.2014


Ответы (1)


Это действительно ошибка доступа. Я думаю, что это просто плохое сообщение об ошибке. Java был скомпилирован отдельно и доступен из файлов jar. Я не уделил должного внимания package private природе классов, которые я хотел создать (я видел перед некоторыми из них "public" и не проверял их все тщательно). В этом случае конфликты пространств имен были отвлекающим маневром и фактически не влияют на вывод сообщения об ошибке.

В некоторых случаях вместо этого я могу использовать общедоступные интерфейсы с небольшим количеством Spring-клея для создания экземпляров объектов и загрузки их в класс Scala.

Сообщение об ошибке scalac было бы более полезным, если бы оно имело вид:

class SomeClass in package com.a.y.x cannot be accessed in totally.unrelated

где первая ссылка на пакет — это пакет класса Java, а завершающий пакет — это пакет класса Scala, пытающийся создать экземпляр класса Java.

Напомним, что класс Java был таким:

package com.a.y.x.SomeClass

class SomeClass extends SomeOtherClass implements SomeInterface

и должно быть так:

package com.a.y.x.SomeClass

public class SomeClass extends SomeOtherClass implements SomeInterface

чтобы не получить эти ошибки доступа.

Поскольку здесь у меня больше контроля над Scala, по прихоти я попытался изменить пакет класса Scala с totally.unrelated на com.a.x.y, который затем компилируется чисто. Как вы могли догадаться, это просто откладывает ошибку до ошибки времени выполнения -> java.lang.IllegalAccessError. Однако IllegalAccessError из Java имеет порядок описания/пакета, который, как я думаю, должен произойти при ошибке компиляции из scalac:

...java.lang.IllegalAccessError: tried to access class com.a.y.x.SomeClass from class s.Trouble$delayedInit$body
person n0741337    schedule 06.02.2014