Eclipse, Java 17, and JUnit testen

II regularly run into issues with launching JUnit tests in Eclipse. I try to compile my open source code as much as possible on Java 8 to increase compatibility. However, more and more projects move to later versions.

In Eclipse, there are a shitload of preferences and settings that do something in this area. I found the selection of the VM quite trick.

Launching VM

First you need to install the the needed VMs in the Java/Installed JREs Preferences entry. Although there is a default JRE, it seems JUnit finds the VM to use by looking at the compile version of the project. It treats this as an Execution Environment. There is a (for me new) Panel under the Java/Installed JREs/Exeecution Environments.

In this panel, you can define what JRE should be used for a project that is compiled against the Execution Environment. I am setting the Java 1.8 projects to JRE 19.

JPMS is a PITA

I run an older version of the Felix Framework, 6.0.2, again for for compatibility reasons. I use the org.osgi.framework 1.9 version. I should upgrade but not yet. However, if you run this version on a Java 17 VM it yells rather violently at you that you should not touch its java.net package. Felix seems to survive this violence. However, the 2 exceptions in the console look awful and there are issues with Launchpad.

The only way to open a package in JPMS is to add a command line option.

 --add-opens java.base/java.net=ALL-UNNAMED

You can add this in the Debug/Run configuration but those are pretty fertile. Eclipse seems to be love creating lots of automatic configurations and they proliferate quickly. It turns out you can also set a command line option in the JRE editor:

Thoughts

It feels bad to put all this information in Eclipse, where it is not shared between the CI and other project users. I’d love to be able to set this information in the bnd workspace.

A few random thoughts…

If I am understanding correctly, this problem happens with ordinary JUnit tests, not with Bnd/OSGi-based JUnit tests.

At the moment, we don’t have any way to specify the launch VM version in a .bnd file for plain JUnit tests - this decision is left up to the driver. Nor is it clear to me that Bnd should have such a thing - Bnd is about building bundles and launching frameworks. To achieve what you are after would require a new Bnd property (eg, -testvm), and integrate this with the Gradle and Maven plugins.

I understand that Bnd has a command line driver which can also launch tests. How does the command line tool decide which VM to use? I am guessing it simply uses whatever VM the command line tool itself is launched with. The best it could probably do in the face of such an option is warn if the running VM version is not high enough to meet the -testvm minimum.

If you really want to share this information with CI without adding anything to Bnd, perhaps you could do also some trick like what we do in the Bndtools workspace where the relevant Eclipse configuration is extracted direct from the Eclipse settings files, where it is subsequently used in Bnd/CI?

And perhaps a -testvmargs parameter too, where you could specify your --add-opens parameter and others.

I added my -add-opens stuff into the .bndrun files I use for testing:

-runvm: --add-opens=java.base/java.nio=ALL-UNNAMED,\
  --add-opens=java.base/sun.nio.ch=ALL-UNNAMED,\
  --add-opens=java.base/java.util.regex=ALL-UNNAMED,\
  --add-opens=java.base/java.lang=ALL-UNNAMED,\
  ${def;argLine}

… and also into my Maven POM - only for JUnit tests running in Eclipse, I need to add it manually / unmanaged.

1 Like