我JMOD用这样的jmod工具创建了一个简单的文件
$JAVA_HOME/bin/jmod create --class-path classes test/samples.jmod
Run Code Online (Sandbox Code Playgroud)
接下来,我尝试通过运行以下命令在该模块中执行一个类:
java -mp test -m de.mypackage/de.mypackage.Test
Run Code Online (Sandbox Code Playgroud)
这导致以下异常:
Error occurred during initialization of VM
java.lang.module.ResolutionException: JMOD files not supported: test/samples.jmod
at java.lang.module.Resolver.findWithBeforeFinder(java.base@9-ea/Resolver.java:729)
at java.lang.module.Resolver.resolveRequires(java.base@9-ea/Resolver.java:86)
at java.lang.module.Configuration.resolveRequiresAndUses(java.base@9-ea/Configuration.java:370)
at java.lang.module.ModuleDescriptor$1.resolveRequiresAndUses(java.base@9-ea/ModuleDescriptor.java:1986)
at jdk.internal.module.ModuleBootstrap.boot(java.base@9-ea/ModuleBootstrap.java:263)
at java.lang.System.initPhase2(java.base@9-ea/System.java:1928)
Run Code Online (Sandbox Code Playgroud)
如果我只是将我的classes目录(我用来创建JMOD文件)设置为模块路径,那么一切都按预期工作.
通常不可能JMOD在模块路径上有文件吗?如果是这种情况,有什么理由吗?
当我通过java -cp(没有--add-modules或--limit-modules)运行应用程序时,某些Java系统模块是可观察的,而其他的则不是.
例如,所有java.se模块都是可观察的.所有java.se.ee模块都无法观察到.我知道javafx.*模块是可观察的.jdk.unsupported并且jdk.shell也是可观察的.
所以,我的假设是正确的:如果没有--add-modules并且--limit-modules被指定,那么可观察的系统模块集包括所有系统模块,除了java.se.ee?
有没有可靠的方法来了解默认的可观察系统模块的确切列表?我知道有一个--list-modules选项,但它列出了所有模块,包括java.se.ee.
为了理解我们的类别:
类路径中的所有类和jar都将是未命名模块的一部分.但为什么我们需要什么呢?自动模块的优势在哪里?我可以"要求"那些该死的传统罐子,使它们成为一个自动模块.我没有把它包括在内吗?
我安装了Version:Oxygen.1a Release(4.7.1a)Build id:20171005-1200,支持Java 9.
在eclipse.ini上建议配置
-vm
C:\Program Files\Java\jdk-9\bin\javaw.exe
--add-modules=ALL-SYSTEM
Run Code Online (Sandbox Code Playgroud)
我已经开发了java 9(java 9模块化)代码项目来测试依赖注入作为来自eclipse的纯Java prject,但是当我集成Maven运行我的eclipse时我系统地得到以下错误
初始化引导期间发生错误layerjava.lang.module.FindException:找不到模块com.my.module.hello.test
唯一的解决方案是添加VM参数
--module-path target/classes;../my-module-api/target/classes;../my-module-it/target/classes --module com.my.module.hello.test/com.my.module.hello.Reflection
Run Code Online (Sandbox Code Playgroud)
实际上,如果添加到Vm参数,我可以在加载期间看到详细参数
... [0.694s] [info] [class,load] java.lang.NamedPackage source:jrt:/java.base [0.697s] [info] [class,load] com.my.module.hello.MyHello source :file:/ C:/ Users/212442540/workspace-training/my-module-prj/my-module/target/classes/[0.698s] [info] [class,load] java.lang.module.ModuleDescriptor $$ Lambda $ 24/2114889273来源:java.lang.module.ModuleDescriptor ...
当我删除"--module-path"参数时,此行消失.
注意:Eclipse能够在编译或编辑期间正常工作.查看completition等等.
我还将modpath依赖项添加到我的项目中
所以似乎Eclipse能够编译java 9模块,但如果与maven集成则无法运行模块.
强制依赖Configratin Run
我也手动添加了依赖项
图1
但是eclipse继续删除它们.
之前:
图2
运行eclipse后恢复:
如果与maven集成,eclipse似乎系统地重置配置.
我有三个模块的多模块Maven项目core,utils以及test-utils
Core具有以下依赖项定义
<dependency>
<groupId>my.project</groupId>
<artifactId>utils</artifactId>
</dependency>
<dependency>
<groupId>my.project</groupId>
<artifactId>test-utils</artifactId>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我module-info.java为所有三个模块添加了Java 9 定义,它们core看起来像这样:
module my.project.core {
requires my.project.utils;
}
Run Code Online (Sandbox Code Playgroud)
但是我无法弄清楚如何让core测试类能够test-utils在测试执行期间看到类.当maven-surefire-plugin尝试测试运行时,我找不到课程.
如果我添加一个requires my.project.testutils;到core的module-info.java:
module my.project.core {
requires my.project.utils;
requires my.project.testutils; //test dependency
}
Run Code Online (Sandbox Code Playgroud)
然后在编译时我得到一个错误,my.project.testutils模块无法找到(大概是因为它只是作为测试依赖项引入).
如何在Java 9模块化世界中使用测试依赖项?出于显而易见的原因,我不希望我的主代码引入测试依赖项.我错过了什么吗?
java maven java-platform-module-system maven-surefire-plugin java-9
我有一个使用Kotlin Gradle插件的Gradle项目.我想构建一个Java 9模块,所以我的目录结构如下所示:
src/main/java/
- module-info.java
src/main/kotlin/
- Foo.kt
- Bar.kt
build.gradle
...
Run Code Online (Sandbox Code Playgroud)
我build.gradle声明了以下依赖项:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.10"
compile "org.jetbrains.kotlin:kotlin-reflect:1.2.10"
compile "org.junit.jupiter:junit-jupiter-api:5.0.2"
}
Run Code Online (Sandbox Code Playgroud)
我用所有这些依赖于我的科特林源(Foo.kt,Bar.kt,...).
如果我module-info.java这么写,那么一切都很有效:
module my.module {
requires kotlin.stdlib;
exports my.module.pkg;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用这种技术javac在compileJava任务期间提供所有编译时依赖项.
但是,如果我-Xlint:all在compileJava任务期间(编译module-info.java)打开Java编译器,我会收到以下警告:
/path/to/my.module/src/main/java/module-info.java:26: warning: requires directive for an automatic module
requires kotlin.stdlib;
^
Run Code Online (Sandbox Code Playgroud)
所以这里我们有Java编译器,javac抱怨这kotlin.stdlib是一个自动模块,所以我不应该有requires它的子句.
但是,如果我删除该requires条款以使其变得javac快乐,那么它就会kotlinc变得更加愤怒 …
我正在将我的项目从Java 8迁移到Java 9.我的项目是mavenised.现在,为了迁移到Java 9,我计划创建一个单独的模块目录,其中模块的所有必需依赖项都将用于此目录.
为了通过maven这样做,我知道的唯一方法是使用maven的复制插件来复制模块目录中所有必需的依赖项.因此,在为模块运行maven安装后,依赖的jar将被复制到repository文件夹(默认情况下),并且还会复制到此模块目录文件夹中.
因此,将会有一个jar副本以及pom.xml中的硬编码,用于复制模块目录中的特定依赖项.
这种方法似乎并不干净,是否有任何出路是自动maven可以读取我的module-info.java文件并复制所需的依赖项不在类路径中但在指定的目录中
这是我的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.aa.bb</groupId>
<artifactId>cc</artifactId>
<version>0.0.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>dd</artifactId>
<name>dd</name>
<groupId>com.aa.cc</groupId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>10</maven.compiler.source>
<maven.compiler.target>10</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>10</release>
<compilerArgs>
<arg>--module-path</arg>
<arg>./moduledir</arg>
</compilerArgs>
</configuration>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
Run Code Online (Sandbox Code Playgroud)
module-info.java
module com.some_module_name {
requires …Run Code Online (Sandbox Code Playgroud) 有没有办法让Java类公开但只公开一个JAR文件?AKA,它不是私有包,而是公共包,但它不是公共JAR?
说我有这样的结构:
project/
package1/
One.java
package2/
Two.java
package3/
Three.java
Run Code Online (Sandbox Code Playgroud)
由于3 .java文件在不同的包中,我需要公开.但有没有办法让它们只对包含该项目的JAR公开?这样如果另一个项目导入JAR,它就看不到某些公共类/字段?
我想创建hello world java 9应用程序,并以intellij的想法启动它。
内部模块-info.java的内容:
module my.module.Second {
requires my.module.First;
}
Run Code Online (Sandbox Code Playgroud)
外部模块-info.java的内容:
module my.module.First {
exports my.pack;
}
Run Code Online (Sandbox Code Playgroud)
但是idea抱怨我的项目:
Error:(1, 1) java: too many module declarations found
Run Code Online (Sandbox Code Playgroud)
我不明白为什么会这样以及真正的错误是什么。所以
我的问题是如何强迫思想接受我的世界。
PS 乍一看,错误似乎很明显,但是我有从github下载的具有相同结构的项目,但是它可以正常工作,并且想法没有抱怨:
java intellij-idea java-platform-module-system java-9 java-module
java ×10
java-platform-module-system ×10
java-9 ×6
maven ×5
eclipse ×2
java-module ×2
module-path ×2
gradle ×1
java-10 ×1
java-11 ×1
kotlin ×1
openjfx ×1