Bug 550376 - [JUnit 5] Cannot run Jupiter tests in a project with module-info.java after upgrade to JUnit 5.5.1
Summary: [JUnit 5] Cannot run Jupiter tests in a project with module-info.java after u...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.13   Edit
Hardware: All All
: P3 critical (vote)
Target Milestone: 4.13 RC1   Edit
Assignee: Noopur Gupta CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 550458
Blocks: 548964
  Show dependency tree
 
Reported: 2019-08-23 06:46 EDT by Noopur Gupta CLA
Modified: 2019-08-28 15:13 EDT (History)
8 users (show)

See Also:
daniel_megert: pmc_approved+
rgrunber: review+


Attachments
Sample project (2.24 KB, application/x-zip-compressed)
2019-08-23 06:46 EDT, Noopur Gupta CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Noopur Gupta CLA 2019-08-23 06:46:42 EDT
Created attachment 279666 [details]
Sample project

I20190821-1800

After upgrade to JUnit 5.5.1, running a Jupiter test in a Java project having module-info.java does not run and gives the following error in Console view:

java.lang.LayerInstantiationException: Package about_files in both module org.junit.platform.engine and module org.junit.jupiter.engine
	at java.base/jdk.internal.module.ModuleBootstrap.checkSplitPackages(ModuleBootstrap.java:470)
	at java.base/jdk.internal.module.ModuleBootstrap.boot(ModuleBootstrap.java:384)
	at java.base/java.lang.ClassLoader.initializeClassLoaders(ClassLoader.java:210)
	at java.base/java.lang.Thread.initialize(Thread.java:428)
	at java.base/java.lang.Thread.<init>(Thread.java:153)

It runs fine if no module-info.java is present in the Java project.
Comment 1 Noopur Gupta CLA 2019-08-23 06:51:23 EDT
Not sure what the error indicates:

java.lang.LayerInstantiationException: Package about_files in both module org.junit.platform.engine and module org.junit.jupiter.engine


Re-running the test gives the same error with different module names like:

java.lang.LayerInstantiationException: Package about_files in both module org.junit.jupiter.api and module org.apiguardian.api

I see that all the modules in JUnit 5.5.1 have about_files.
Comment 2 Noopur Gupta CLA 2019-08-23 06:55:08 EDT
When JUnit 5 container is on the modulepath of the Java project then running a Java application also fails with the same error.
Comment 3 Noopur Gupta CLA 2019-08-23 07:24:31 EDT
One difference in JUnit 5.5.1 compared to the previously used JUnit 5.4 is that now the JARs contain a module-info.class. 

The Orbit bundles still contain Automatic-Module-Name in MANIFEST.MF.

@Roland, is Automatic-Module-Name added by Orbit? Do you know if this is the case for other Orbit bundles also which already contain a module-info?

@Sarika, can this error be caused by having the module name specified at two places i.e. in module-info and MANIFEST? Both the names won't be conflicting though.
Comment 4 Noopur Gupta CLA 2019-08-23 07:27:37 EDT
Command line arguments of the failed launch taken via Show Command Line button:

C:\Program Files\AdoptOpenJDK\jdk-11.0.4.11-openj9\bin\javaw.exe -ea --add-opens test/p=org.junit.platform.commons,ALL-UNNAMED --add-modules=ALL-MODULE-PATH -Dfile.encoding=Cp1252 -p "C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\ws\Test\bin;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.jupiter.api_5.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.jupiter.engine_5.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.jupiter.migrationsupport_5.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.jupiter.params_5.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.platform.commons_1.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.platform.engine_1.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.platform.launcher_1.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.platform.runner_1.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.platform.suite.api_1.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit.vintage.engine_5.5.1.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.opentest4j_1.2.0.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.apiguardian_1.1.0.v20190812-1854.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.junit_4.12.0.v201504281640\junit.jar;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\plugins\org.hamcrest.core_1.3.0.v20180420-1519.jar" -classpath "C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\configuration\org.eclipse.osgi\176\0\.cp;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\configuration\org.eclipse.osgi\174\0\.cp;C:\Eclipse\Builds\eclipse-SDK-I20190821-1800\eclipse\configuration\org.eclipse.osgi\268\0\.cp" org.eclipse.jdt.internal.junit.runner.RemoteTestRunner -version 3 -port 52118 -testLoaderClass org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader -loaderpluginname org.eclipse.jdt.junit5.runtime -classNames p.T
Comment 5 Roland Grunberg CLA 2019-08-23 10:38:43 EDT
(In reply to Noopur Gupta from comment #3)
> One difference in JUnit 5.5.1 compared to the previously used JUnit 5.4 is
> that now the JARs contain a module-info.class. 
> 
> The Orbit bundles still contain Automatic-Module-Name in MANIFEST.MF.
> 
> @Roland, is Automatic-Module-Name added by Orbit? Do you know if this is the
> case for other Orbit bundles also which already contain a module-info?

Yes, for a while now, Orbit adds this manifest header ( https://git.eclipse.org/r/111718 ) . It should be possible to disable for JUnit5 if that is required.
Comment 6 Stephan Herrmann CLA 2019-08-23 15:56:40 EDT
(In reply to Noopur Gupta from comment #0)
> java.lang.LayerInstantiationException: Package about_files in both module
> org.junit.platform.engine and module org.junit.jupiter.engine
> 	at
> java.base/jdk.internal.module.ModuleBootstrap.
> checkSplitPackages(ModuleBootstrap.java:470)
> 	at
> java.base/jdk.internal.module.ModuleBootstrap.boot(ModuleBootstrap.java:384)
> 	at
> java.base/java.lang.ClassLoader.initializeClassLoaders(ClassLoader.java:210)
> 	at java.base/java.lang.Thread.initialize(Thread.java:428)
> 	at java.base/java.lang.Thread.<init>(Thread.java:153)

Do any classes exist that declare package about_files?? Legally, without such classes that package doesn't 'exist', even if the jar contains that folder.

Ergo there would be no conflict according to JPMS rules, in which case this would be a bug in ModuleBootstrap.checkSplitPackages() that should perhaps be discussed on jigsaw-dev.
Comment 7 Sarika Sinha CLA 2019-08-24 09:34:34 EDT
about_files existed before as well but now JUnit has provided named modules.

@Noopur, can we try removing about_files from the jar and it's mention in Manifest.MF to confirm?
Comment 8 Stephan Herrmann CLA 2019-08-24 15:07:31 EDT
I revisited more information what is a package a compile time vs. what is a package at runtime. Confusion abound.

- JLS only considers package declared by a compilation unit

- JPMS doesn't care much about packages

Apparently, the truth about the above exception can only be found in javadoc & sources of java.lang.module.* and related.

In particular jdk.internal.module.ModulePath.jarPackages(JarFile) traverse all files in a jar and tries to interpret the containing directory as a package. This implies that
   about_files/ECLIPSE_PUBLIC_LICENSE_V2.0.html
creates the package about_files.

Then in java.lang.Module.getResourceAsStream(String) I found an interesting distinction into encapsulated / not encapsulated resources, depending on their _packageName_. The javadoc of the method gives the example of META-INF/MANIFEST.MF as not being encapsulated because "META-INF" is not a legal package name.

Naively, I would conclude that the resource in about_files *is* encapsulated and hence no illegal package split occurs. Apparently, the opposite is the case: a resource must not be encapsulated in order to legally appear in different modules.

=> Can you try renaming about_files to about-files?
Comment 9 Stephan Herrmann CLA 2019-08-24 19:05:16 EDT
I asked for clarification: https://mail.openjdk.java.net/pipermail/jigsaw-dev/2019-August/014279.html
Comment 10 Noopur Gupta CLA 2019-08-26 04:08:19 EDT
Adding Sam, as this may be of interest to him.
Comment 11 Noopur Gupta CLA 2019-08-26 04:28:03 EDT
(In reply to Stephan Herrmann from comment #9)
> I asked for clarification:
> https://mail.openjdk.java.net/pipermail/jigsaw-dev/2019-August/014279.html
Thanks for following up on this, Stephan.

(In reply to Stephan Herrmann from comment #8)
> Then in java.lang.Module.getResourceAsStream(String) I found an interesting
> distinction into encapsulated / not encapsulated resources, depending on
> their _packageName_. The javadoc of the method gives the example of
> META-INF/MANIFEST.MF as not being encapsulated because "META-INF" is not a
> legal package name.
> 
> => Can you try renaming about_files to about-files?
Interesting! Yes, we can try that. I need to do the setup to build Orbit JARs locally on my newly formatted system. I'll do that and update.

Note that the JUnit 5.4 JARs used earlier and the org.hamcrest.core JAR also contain about_files folder with the license. And a project using JUnit 5.4 or JUnit 4 (having just junit.jar and org.hamcrest.core.jar) don't face this issue. The difference is the presence of module-info file in the JAR.
Comment 12 Sam Brannen CLA 2019-08-26 08:18:33 EDT
Thanks for adding me, Noopur.

Since `about_files` is not something present in the JARs published by JUnit, I suppose you're on the right track with finding a solution within Eclipse and Orbit.
Comment 13 Christian Stein CLA 2019-08-26 08:33:28 EDT
All Jupiter artifacts are explicit Java modules since 5.5.x, this also goes for JUnit 5 Platform 1.5.x modules. This applies all Java module system rules at compile and runtime -- when running on the module-path.

> Cannot run Jupiter tests in a project with module-info.java after upgrade to JUnit 5.5.1

As Sam already stated -- it should read: "[...] after upgrade to _modified_ JUnit 5.5.1"
Comment 14 Noopur Gupta CLA 2019-08-26 09:18:59 EDT
Thanks for your comments, Sam and Christian.
Agreed, it's an issue with the usage of generated Eclipse Orbit JARs in modular projects, and not with the JARs published by JUnit.
Comment 15 Noopur Gupta CLA 2019-08-26 09:31:29 EDT
(In reply to Noopur Gupta from comment #11)
> (In reply to Stephan Herrmann from comment #8)
> > Then in java.lang.Module.getResourceAsStream(String) I found an interesting
> > distinction into encapsulated / not encapsulated resources, depending on
> > their _packageName_. The javadoc of the method gives the example of
> > META-INF/MANIFEST.MF as not being encapsulated because "META-INF" is not a
> > legal package name.
> > 
> > => Can you try renaming about_files to about-files?
> Interesting! Yes, we can try that.
Renaming about_files to about-files works! :-)

Let us know if you get a solution for this from the openjdk mailing list.
Comment 16 Noopur Gupta CLA 2019-08-26 09:32:28 EDT
Roland, I'll upload the patch with renamed folders. I hope that won't be an issue with Orbit.

Also, this will be a generic problem with all Orbit JARs having about_files folder and module-info file when used on the modulepath of a Java project.

Should Orbit start creating about-files instead of about_files now?
Comment 17 Eclipse Genie CLA 2019-08-26 09:34:32 EDT
New Gerrit change created: https://git.eclipse.org/r/148350
Comment 18 Roland Grunberg CLA 2019-08-26 10:07:41 EDT
@Gunnar, this can be changed in ebr-maven-plugin (AboutFilesUtil) right ?
Comment 19 Gunnar Wagenknecht CLA 2019-08-26 10:27:44 EDT
(In reply to Roland Grunberg from comment #18)
> @Gunnar, this can be changed in ebr-maven-plugin (AboutFilesUtil) right ?

Yes. It needs a bit of refactoring, though. We currently don't have it in one place.
https://github.com/eclipse/ebr/search?l=Java&q=about_files

Based on the answer:
https://mail.openjdk.java.net/pipermail/jigsaw-dev/2019-August/014280.html

It sounds like it's more appropriate to define the list of packages in modules-info.jar at packaging time.
Comment 21 Sarika Sinha CLA 2019-08-26 12:26:27 EDT
@Roland,
When do we have the next Orbit build to be consumed by Platform for RC1?
Comment 22 Stephan Herrmann CLA 2019-08-26 14:00:45 EDT
(In reply to Gunnar Wagenknecht from comment #19)
> Based on the answer:
> https://mail.openjdk.java.net/pipermail/jigsaw-dev/2019-August/014280.html
> 
> It sounds like it's more appropriate to define the list of packages in
> modules-info.jar at packaging time.

I don't think this will solve the issue of about_files, see this part of the answer:

"As an optimization [...]. This means the set of packages in the module may be determined at packaging time rather than other phases and the scanning done at packaging time needs to exactly match the scanning that would be done when the ModulePackages attribute is not present"

IOW, the class file attribute (potentially updated during jarring) is only an optimization, it should not change what is or is not a package.
Comment 23 Roland Grunberg CLA 2019-08-26 16:53:16 EDT
(In reply to Sarika Sinha from comment #21)
> @Roland,
> When do we have the next Orbit build to be consumed by Platform for RC1?

I'll generate the build tuesday so it's ready for wednesday.
Comment 24 Stephan Herrmann CLA 2019-08-27 15:14:54 EDT
We have something like a recommendation from Alan Bateman in [1]

Forging the list of packages to exclude a given folder doesn't seem to be supported without hacking the jar tool, but:

"The top-level directory or a location such as META-INF/legal will work of course."

So, we have some kind of blessing also for "about-files". It solves the problem, because this folder is not seen as a package, hence JPMS has nothing to check and hence the boot layer has no reason to blow up.

Conversely, by saying "about_files/EPL.html" we create an "encapsulated" package "about_files", where "encapsulated" doesn't live up to its promise in a single-classloader runtime, which will and does blow up.


[1] https://mail.openjdk.java.net/pipermail/jigsaw-dev/2019-August/014284.html
Comment 25 Noopur Gupta CLA 2019-08-28 15:13:11 EDT
Verified as fixed in I20190828-0600.