Compilation failure on custom class with package java.util

124 views Asked by At

I have a custom class, whose package is given as java.util. The code was compiling fine before java version 9, but when I have changed java version to 11, I am facing package exists in another module: java.base. I need the class to get compiled with the same package java.util, so that it gets bootstraped as part of rt.jar. Can someone please help to rectify this issue. Thanks in advance.

I have tried adding --patch-module java.base=java.util in .mvn/jvm.config, but that didn't fix the issue.

3

There are 3 answers

0
CodexPro On

The error you're encountering suggests that you have a class in your codebase with a package name that conflicts with a package in the java.base module, which is part of the Java Standard Library. Specifically, java.util is a well-known package in java.base that contains various utility classes. Here's the thing I can suggest:

  • Avoid Conflicting Package Names
  • Use a Unique Package Name

After making the necessary changes, recompile your code and test it again.

3
dan1st might be happy again On

java.util is a package reserved for classes provided by the JDK. You should not put any classes in any package starting with java/javax/jdk/etc.

The only situation where this should be done is if you are contributing to the JDK in which case you woukd change the JDK itself and not run into that error.

Since modules were introduces, you cannot have split packages (packages where the code is provided by different modules). The java.util package is provided by the java.base module and you shouldn't change that module, it is part of the JDK.

So, just put the class somewhere else. You would typically start your packages with something like com.yourdomain.yourproject.

1
rzwitserloot On

rt.jar ceased to exist in java9. When you say "I need it to be part of rt.jar", that means there's only thing to do, which is, to stick to JDK8, where this problem doesn't exist.

There are ways (very hacky ways) to get a class into the base module (which is no longer rt.jar - rt.jar no longer exists, its java.base.jmod - this is where the usual classes in the java util package live (you can check this: $JAVA_HOME/bin/jmod list $JAVA_HOME/jmods/java.base.jmod will list a whole bunch of stuff, including classes/java/util/ArrayList.class.

You can use the jmod tool to inject your class into there, at which point you have a modified (i.e. forked) JDK distribution. You can also just straight up clone the openjdk project (its open source), make your change in a branch, and then compile all that, as you're effectively forking the JDK at this point.

I don't think it's possible to ship your update as a separate, runtime-invokable patch. i.e. you can't invoke a stock java JDK9+ such that your code runs as if it was in the java.base.jmod.

If you insist on going down that right, what I'd try next is to make an agent, at least, if what you're doing is overwriting an existing java class. If you're trying to add a new one, I'd just fix whatever tool expects your class to be in rt.jar - that tool must be updated anyway, given that rt.jar no longer exists. While you're at it, might as well fix it. And if its update now looks only in the jmods, well, if you're going to patch something, its probably a lot simpler to patch that project than the OpenJDK itself.