I am currently testing to migrate an existing Java 8 (Maven) project to Java 9 / Jigsaw, using jdk9-ea+147 and maven-compiler-plugin 3.6.0.
I have converted the src
directory to a module and left the test
directory non-modular.
During testCompile
I get an unexpected error:
error: build() in ExtractedArtifactStoreBuilder is defined in an inaccessible class or interface
Of course I have checked that both the ExtractedArtifactStoreBuilder
is public. build()
is inherited from its (public) superclass and public as well. The code compiles and runs fine in JDK 8.
ExtractArtifactStoreBuilder
is defined in a different 3rd partry JAR than its superclass, but Maven correctly puts both in the classpath. Confusingly, the superclass has the same classname (but resides in a different package)
As far as I can see, I should be able to access public inherited methods in my test code. So is this a bug in the jdk9 early access version?
Edit: hoping for better comprehensibility, here is a little abstraction of the involved JARs and classes, with less confusing naming and unimportant stuff left out (for the actual dependencies, see below):
process.jar
public ProcessStoreBuilder
public ProcessStoreBuilder download(...) // returns "this"
public ... build()
mongo.jar
public MongoStoreBuilder extends ProcessStoreBuilder
src/test/java/ExampleTest
mongoStoreBuilder.download(...).build()
// ^ breaks at compile time, saying that
// ProcessStoreBuilder#build() is not accessible
I have been able to reproduce the behavior in a minimal setup:
pom.xml (excerpt)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>9</source>
<target>9</target>
<debug>true</debug>
<optimize>true</optimize>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>1.50.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.process</artifactId>
<version>1.50.0</version>
<scope>test</scope>
</dependency>
</dependencies>
src/main/java/module-info.java
module com.mycompany.example.testdependencyexample {}
src/test/java/ExampleTest.java (excerpt)
@Before
public void setUp() throws Exception {
// both `download` and `build` are inherited from the superclass
// the following does work
// de.flapdoodle.embed.mongo.config.ExtractedArtifactStoreBuilder
ExtractedArtifactStoreBuilder easb = new ExtractedArtifactStoreBuilder();
easb.download(new DownloadConfigBuilder().build());
easb.build();
// but this does not
// download returns the same instance but has the superclass as return type
// de.flapdoodle.embed.process.store.ExtractedArtifactStoreBuilder
// the compiler can't see the `build` method of the superclass
new ExtractedArtifactStoreBuilder()
.download(new DownloadConfigBuilder().build())
.build();
}