You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在JDK9模块中引入JDK7编译库的问题求助

Is This Feasible?

Absolutely yes! Java 9’s module system was explicitly built to support interoperability with legacy non-modular JARs (dubbed automatic modules). Your issue right now is just that your module doesn’t know it needs to depend on these automatic modules—hence why removing module-info.java (which drops you back to classpath mode) fixes the problem.

Step-by-Step Fix

Here’s how to get your JDK7 libraries working seamlessly with your Java 9 module:

1. Find the Automatic Module Name

First, you need to know what module name Java 9 assigns to your JDK7 JAR. There are three reliable ways to get this:

  • Check the JAR’s manifest: Some well-maintained legacy JARs already have an Automatic-Module-Name entry in their MANIFEST.MF file—this is the official name to use.
  • Generate it from the filename: If there’s no manifest entry, Java converts the JAR filename to a module name by stripping version numbers, replacing hyphens/underscores with dots, and making it lowercase. For example, legacy-utils-2.3.jar becomes legacy.utils.
  • Use the jar command: For 100% certainty, run this command on your dependency JAR:
    jar --file path/to/your/legacy-library.jar --describe-module
    
    This will print the exact module name Java uses, along with other module details.

2. Update Your module-info.java

In your Java 9 module’s module-info.java, add a requires statement for each legacy automatic module. For example, if your library’s module name is com.oldcompany.tools, update your module descriptor like this:

module your.module.name {
    requires com.oldcompany.tools;
    // Add similar lines for all other JDK7 dependencies
}

This tells your module to depend on the automatic module, making its classes accessible during compilation and runtime.

3. Verify Maven Configuration

Make sure your Maven setup is handling modules correctly:

  • Use Maven Compiler Plugin 3.8.0 or newer: Older versions don’t support Java 9 modules properly. Update your plugin config in pom.xml:
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
        <configuration>
            <release>9</release>
        </configuration>
    </plugin>
    
  • Double-check dependencies: Ensure all JDK7 libraries are listed as <dependency> entries in your pom.xml—Maven will automatically place them on the module path (not classpath) when building a modular project.

Troubleshooting Common Issues

  • "Cannot find symbol" errors: Double-check the module name in your requires statement—typos are a common culprit. Re-run the jar --describe-module command to confirm the exact name.
  • Access to internal JDK APIs: Some very old libraries might use internal JDK classes (like sun.* packages). Java 9 restricts access to these, so you’ll need to explicitly allow it with compiler arguments. For example, in your Maven plugin:
    <compilerArgs>
        <arg>--add-exports java.base/sun.nio.ch=com.oldcompany.tools</arg>
    </compilerArgs>
    
    Note: This is a workaround—avoid using internal APIs long-term, as they’re not guaranteed to exist in future Java versions.

Alternative Solutions (If Automatic Modules Aren’t Working)

If you run into edge cases with automatic modules, here are two reliable backups:

1. Wrap Legacy JARs as Explicit Modules

You can manually add a module-info.java to your JDK7 libraries to turn them into explicit modules. Tools like Moditect make this easy via Maven:

  • Add the Moditect plugin to your pom.xml to generate module-info files for your dependencies during the build. This gives you full control over module names, exports, and dependency rules.

2. Fall Back to Classpath Mode (Last Resort)

If you need a quick fix but still want to deliver a modular JAR, you can keep your module-info.java but place legacy dependencies on the classpath. To make your module access classpath classes, update your module descriptor:

module your.module.name {
    // Allow access to unnamed classpath modules
    requires transitive java.base;
}

And when running your app, use the --add-modules=ALL-UNNAMED flag to include classpath content. However, this defeats many of the module system’s benefits (like encapsulation), so only use it if automatic modules aren’t an option.


内容的提问来源于stack exchange,提问作者Meilun Sheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:15:52