Question

I'm attempting to un-Spring IoC several Java classes and load them directly in some Scala code. Naturally I'm finding that there are name space conflicts between a package like

com.a.x.SomeClass

and

com.a.y.x.SomeClass

I've tried using the import name space resolvers like

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

That cleans up the imports, but referring to those classes later in the classes show the error as hovers in the Typesafe ScalaIDE, and after clean compilations.

When I compile from the gradle scala plugin, or via the Typesafe ScalaIDE with scala 2.10.2 or 2.10.3, I get the following type of un-useful error messages:

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

The problem occurs if I try to use a class from com.a.y.x that doesn't have a name space conflict. If I try some of the scalac flags, I've also been able to get a Warning out that's slightly different ( during the typer stage ):

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

I'd really like to know if there's a way to expand the first package reference. I'm having trouble setting up an Eclipse project to debug the scalac compiler and I haven't found a scalac flag that adds useful information to the error.

The error occurs when I either try to ctx.getBean("someClass").asInstanceOf[XXXSomeClass] or new XXXSomeClass.

The this reference from the warning makes me think there's some object confusion going on. I don't think it's classpath issue in the larger project I'm working on because removing one jar removes the ability to resolve imports, however I can't reproduce it with simple example classes in a separate project.

A little more information on the java classes - the different, conflicting java packages are in separate jars that were compiled by a 1.6 flavor of Java. They are top level, public classes although two are singletons with private constructors and corresponding public static getInstance() methods.

Was it helpful?

Solution

It really is an access error. I think this is just a poor error message. The java was compiled separately and accessed from jar files. I hadn't paid enough attention to the package private nature of the classes I wanted to instantiate( I had seen "public" in front of some of them and not carefully checked all of them ). The name space collisions were a red-herring in this case and actually don't affect the output of the error message.

In some cases, there are public interfaces I can use instead with a little bit of Spring-glue to instantiate the objects and load them into the Scala class.

The scalac error message would have been more helpful if it had the form:

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

where the first package reference is the Java class's package and the trailing package is the package of the Scala class trying to instantiate the Java class.

To recap - the Java class was like:

package com.a.y.x.SomeClass

class SomeClass extends SomeOtherClass implements SomeInterface

and needs to be like:

package com.a.y.x.SomeClass

public class SomeClass extends SomeOtherClass implements SomeInterface

to not get these access errors.

Since I have more control of the Scala here, on a whim I tried changing the package of a Scala class from totally.unrelated to com.a.x.y which then compiles cleanly. As you might guess, that merely defers the error to a run time error -> java.lang.IllegalAccessError. However, the IllegalAccessError from the Java has the description/package order that I think should happen in the compilation error from scalac:

...java.lang.IllegalAccessError: tried to access class com.a.y.x.SomeClass from class s.Trouble$delayedInit$body
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top