Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Muting Java 9 split package errors on IntelliJ

I have a JDK 9 project. When running mvn install, everything works fine. When using IntelliJ 2017.2.6 with JDK 9.0.4 I come up with dozens of compilation errors due to split packages. For example, in my POM I set a dependency on org.apache.solr:solr-core:7.2.1. One of the errors displayed by IntelliJ is:

Error:java: module solr.core reads package org.apache.lucene.search from both lucene.misc and lucene.sandbox

The rationale for the compilation error issued by IntelliJ is:

  1. solr-core has Maven dependencies on artifacts lucene-misc and lucene-sandbox
  2. Both lucene-misc.jar and lucene-sandbox.jar define classes in package org.apache.lucene.search
  3. IntelliJ considers that lucene-misc.jar and lucene-sandbox.jar are JDK 9 modules (if fact, they are not modules, they have no module-info.java file). As two JDK 9 modules cannot participate to the same package, IntelliJ issues a compilation error.

By contrast, the Maven compiler pluging issues no error, because it considers lucene-misc.jar and lucene-sandbox.jar as belonging to the class path, not to the module path.

I obviously don't want to re-package the Lucene stuff.

So my problem boils down to the following: how can I mute IntelliJ errors Error:java: module Mod1 reads package P from both Mod2 and Mod3?

like image 454
Ivan dal Bosco Avatar asked Feb 19 '18 17:02

Ivan dal Bosco


1 Answers

[Short]

It's impossible if you want to run your application from a module code. You have to migrate your code which depend on collision JARs to non-module code and add your collitions jar on the class path. (as suggested in comments)

[Long]

Behind the scene the Intellij try to run the JVM, so the Intellij can run your application only if the JVM can do that.

When you run an application from module jar, that means that you run your application from named module. The module must require all of its dependencies which should be name modules. Note that even automatic modules which are created from your non-module JARs are indeed named. Java 9 does not allow split-packages for the reason of the reliable configuration, only unnamed modules are excepted from this rule.

The only way to make it works it move your collision jars to unnamed module, but named module cannot depend on unnamed module

A named module cannot, in fact, even declare a dependence upon the unnamed module. This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.

so if you don't want repackage collision jars you have to move your modules which require collision jars to non-module jar.

Your maven plugin done with it, because as @Nicolai said:

Maven places them on the class path (where split packages don't matter), whereas IntelliJ places them on the module path (leading to the problems you observe).

See also this answer about running the application from non-module code.

like image 157
Andrew Sasha Avatar answered Sep 17 '22 15:09

Andrew Sasha