我目前正在测试使用 jdk9-ea+147 和 maven-compiler-plugin 3.6.0 将现有的 Java 8 (Maven) 项目迁移到 Java 9 / Jigsaw。
我已将src
目录转换为模块并将test
目录保留为非模块化。
在testCompile
我收到意外错误期间:
错误:ExtractedArtifactStoreBuilder 中的 build() 定义在不可访问的类或接口中
当然,我已经检查过两者ExtractedArtifactStoreBuilder
都是公开的。build()
继承自它的(公共)超类和公共的。代码在 JDK 8 中编译并运行良好。
ExtractArtifactStoreBuilder
在与其超类不同的 3rd 方 JAR 中定义,但 Maven 正确地将两者都放在类路径中。令人困惑的是,超类具有相同的类名(但位于不同的包中)
据我所知,我应该能够在我的测试代码中访问公共继承方法。那么这是jdk9抢先体验版的bug吗?
编辑:希望更好地理解,这里是所涉及的 JAR 和类的一点抽象,命名和不重要的东西更少混淆(对于实际的依赖关系,见下文):
进程.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
我已经能够以最小的设置重现该行为:
pom.xml(摘录)
<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(摘录)
@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();
}