Bug 541403 - running tests with Import-Package:javax.annotation using JDK 11 fails
Summary: running tests with Import-Package:javax.annotation using JDK 11 fails
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Tycho (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: noteworthy
: 534074 (view as bug list)
Depends on:
Blocks: 541433 541435
  Show dependency tree
 
Reported: 2018-11-21 09:19 EST by Jan Sievers CLA
Modified: 2021-04-28 16:52 EDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Sievers CLA 2018-11-21 09:19:53 EST
test bundles with BREE < JavaSE-11 and Import-Package: javax.annotation currently fail with many unresolved requirements like

Unresolved requirement: Import-Package: javax.annotation



sample project:

http://git.eclipse.org/c/tycho/org.eclipse.tycho-demo.git/log/?h=bug_532302_sample

steps tor reproduce: 

export JAVA_HOME=/path/to/jdk-11
mvn clean install -X


here is my understanding of what goes wrong:

* tycho uses the (test) bundle's BREE to resolve its dependencies
* in this case, it's JavaSE-1.8 which provides package javax.annotation as system package (it's part of JDK 8)
* at (test) runtime however, JDK 11 no longer provides this package and equinox resolution fails


Up to JDK 11, it was fine to use the bundle's BREE for dependency resolution because it defined the "minimum" JDK required to run it, and newer JDKs would only provide more API (not less)

this changed with JDK 11 because for the first time, packages were removed from the JDK


current workaround: 

force test bundle's BREE to JavaSE-11 e.g.

      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>target-platform-configuration</artifactId>
        <version>${tycho-version}</version>
        <configuration> 
          <!--workaround bug 532302: set EE to JavASE-11 to make sure we resolve Import-Package: javax.annoation against bundle javax.annotation 
          (as opposed to system package from bundle's BREE JavaSE-1.8) -->
         <executionEnvironment>JavaSE-11</executionEnvironment> 
        </configuration>
      </plugin>


this will make sure both the p2 resolver and equinox resolver will use the bundle javax.annotation to satisfy the package dependency


One idea I have would be that for test bundles, maybe we should rather use (or offer to use) the 
execution environment of the currently running JDK for dependency resolution (as opposed to the test bundle's BREE)
Comment 1 Mickael Istria CLA 2018-11-21 09:24:54 EST
Another workaround: in test bundle, put

	<plugin>
		<groupId>org.eclipse.tycho</groupId>
		<artifactId>target-platform-configuration</artifactId>
		<version>${tycho-version}</version>
		<configuration>
			<dependency-resolution>
				<extraRequirements>
					<requirement>
						<type>eclipse-plugin</type>
						<id>javax.annotation</id>
						<versionRange>0.0.0</versionRange>
					</requirement>
				</extraRequirements>
			</dependency-resolution>
		</configuration>
	</plugin>
Comment 2 Alexander Kurtakov CLA 2018-11-21 10:31:02 EST
(In reply to Mickael Istria from comment #1)
> Another workaround: in test bundle, put
> 
> 	<plugin>
> 		<groupId>org.eclipse.tycho</groupId>
> 		<artifactId>target-platform-configuration</artifactId>
> 		<version>${tycho-version}</version>
> 		<configuration>
> 			<dependency-resolution>
> 				<extraRequirements>
> 					<requirement>
> 						<type>eclipse-plugin</type>
> 						<id>javax.annotation</id>
> 						<versionRange>0.0.0</versionRange>
> 					</requirement>
> 				</extraRequirements>
> 			</dependency-resolution>
> 		</configuration>
> 	</plugin>

Adding this to many many test bundles is just not feasible.
Comment 3 Alexander Kurtakov CLA 2018-11-21 10:37:18 EST
Can't we have some (optional?) requires on modules that are removed in Java 11 injected by Tycho? That way if available in the target platform they should be used without changes to test bundles. Does it make sense?
Comment 4 Mickael Istria CLA 2018-11-21 10:45:52 EST
(In reply to Jan Sievers from comment #0)
> One idea I have would be that for test bundles, maybe we should rather use
> (or offer to use) the 
> execution environment of the currently running JDK for dependency resolution
> (as opposed to the test bundle's BREE)

We probably need to take into account tycho-surefire-plugin useJDK parameter.
Maybe the tycho-surefire-plugin should verify that current EE matches the one used by default dependency resolution, and in case it doesn't, retrigger a different dependency resolution with the EE that's going to be used.
Would it be possible to trigger another dependency resolution from inside the tycho-surefire-plugin?
Comment 5 Jan Sievers CLA 2018-11-22 03:08:00 EST
(In reply to Mickael Istria from comment #4)
> (In reply to Jan Sievers from comment #0)
> > One idea I have would be that for test bundles, maybe we should rather use
> > (or offer to use) the 
> > execution environment of the currently running JDK for dependency resolution
> > (as opposed to the test bundle's BREE)
> 
> We probably need to take into account tycho-surefire-plugin useJDK parameter.
> Maybe the tycho-surefire-plugin should verify that current EE matches the
> one used by default dependency resolution, and in case it doesn't, retrigger
> a different dependency resolution with the EE that's going to be used.
> Would it be possible to trigger another dependency resolution from inside
> the tycho-surefire-plugin?

IIRC there is another dependency resolution already happening just before test execution in TestMojo.createEclipseInstallation() (this is for things like the extradependencies for tests)

maybe we can find a way to configure the execution environment used by this dependency resolution to use the EE of the currently running JDK

I'm not into the deatils right now but here are some pointers to possibly  relevant code:
 
OsgiBundleProject.readExecutionEnvironmentConfiguration()
Comment 6 Jan Sievers CLA 2018-11-22 03:11:09 EST
(In reply to Mickael Istria from comment #4)
> (In reply to Jan Sievers from comment #0)
> > One idea I have would be that for test bundles, maybe we should rather use
> > (or offer to use) the 
> > execution environment of the currently running JDK for dependency resolution
> > (as opposed to the test bundle's BREE)
> 
> We probably need to take into account tycho-surefire-plugin useJDK parameter.


for useJDK=BREE, we shouldn't have a problem. useJDK=BREE means to use the JDK corresponding to the MANIFEST BREE to run the tests. Since we use the MANIFEST BREE execution environment for dependency resolution, we should be fine as MANIFEST BREE and JDK used to execute tests match in this case.
Comment 7 Alexander Kurtakov CLA 2018-11-22 07:56:04 EST
So if I hook a logic to check if running JVM is Java 11 or newer in " if (manifestBREEs.length > 0) {" block in readExecutionEnvironmentConfiguration will it affect useBREE ? If not making it the test run with running JVM instead of the BREE should be simpler and less errorprone.
Comment 8 Eclipse Genie CLA 2018-11-23 11:11:17 EST
New Gerrit change created: https://git.eclipse.org/r/132992
Comment 9 Jan Sievers CLA 2018-11-23 11:12:38 EST
(In reply to Alexander Kurtakov from comment #7)
> So if I hook a logic to check if running JVM is Java 11 or newer in " if
> (manifestBREEs.length > 0) {" block in readExecutionEnvironmentConfiguration
> will it affect useBREE ? If not making it the test run with running JVM
> instead of the BREE should be simpler and less errorprone.

I pushed some (very) initial code to gerrit but do not have time to continue working on it now

https://git.eclipse.org/r/#/c/132992/

you may want to take this as a starting point
Comment 10 Mickael Istria CLA 2018-11-23 11:17:55 EST
(In reply to Jan Sievers from comment #9)
> I pushed some (very) initial code to gerrit but do not have time to continue
> working on it now
> 
> https://git.eclipse.org/r/#/c/132992/
> 
> you may want to take this as a starting point

One (minor) issue with this patch is that it also changes the behavior when running with -DskipTests or when tycho-surefire-plugin:test isn't invoked in general, whereas there is no real reason to change the resolution strategy in that case.
To me, the problem is really at test execution, so it would be more consistent to fix this only in tycho-surefire-plugin.
Comment 11 Jan Sievers CLA 2018-11-26 05:14:12 EST
(In reply to Mickael Istria from comment #10)
> One (minor) issue with this patch is that it also changes the behavior when
> running with -DskipTests or when tycho-surefire-plugin:test isn't invoked in
> general, whereas there is no real reason to change the resolution strategy
> in that case.
> To me, the problem is really at test execution, so it would be more
> consistent to fix this only in tycho-surefire-plugin.

I agree. I just didn't find an easy way to do this with the current codebase that throws an exception if you try to change the execution environment after the initial dependency resolution before the start of the build.
Comment 12 Marco Descher CLA 2018-12-19 05:56:07 EST
I see the error with

The import javax.activation cannot be resolved

on a multi-release bundle, where javax.activation is added via

META-INF/versions/9/OSGI-INF/MANIFEST.MF
> Manifest-Version: 1.0
> Bundle-ManifestVersion: 2
> Import-Package: javax.activation
>
Comment 13 Eclipse Genie CLA 2018-12-21 05:46:55 EST
New Gerrit change created: https://git.eclipse.org/r/134380
Comment 14 Alexander Kurtakov CLA 2018-12-21 08:12:46 EST
(In reply to Jan Sievers from comment #11)
> (In reply to Mickael Istria from comment #10)
> > One (minor) issue with this patch is that it also changes the behavior when
> > running with -DskipTests or when tycho-surefire-plugin:test isn't invoked in
> > general, whereas there is no real reason to change the resolution strategy
> > in that case.
> > To me, the problem is really at test execution, so it would be more
> > consistent to fix this only in tycho-surefire-plugin.
> 
> I agree. I just didn't find an easy way to do this with the current codebase
> that throws an exception if you try to change the execution environment
> after the initial dependency resolution before the start of the build.

For the record it's not only test. If you try to compile a bundle that needs e.g. javax.annotation and has BREE 1.8 with Java 11 runtime jvm it will fail to resolve too. https://git.eclipse.org/r/134380 fixes both compile and test issue for me.
Comment 15 Alexander Kurtakov CLA 2018-12-21 08:13:34 EST
(In reply to Marco Descher from comment #12)
> I see the error with
> 
> The import javax.activation cannot be resolved
> 
> on a multi-release bundle, where javax.activation is added via
> 
> META-INF/versions/9/OSGI-INF/MANIFEST.MF
> > Manifest-Version: 1.0
> > Bundle-ManifestVersion: 2
> > Import-Package: javax.activation
> >

Do you run with Java 11? if yes would you please try whether https://git.eclipse.org/r/134380 fixes the issue for you?
Comment 17 Jan Sievers CLA 2019-01-08 03:49:23 EST
To summarize what has changed:

Before, Tycho used to use the bundle's Bundle-RequiredExecutionEnvironment for dependency resolution.
Now, if you are using JDK >=11 for your Tycho build, Tycho will use the execution environment of the currently running JDK for dependency resolution.

Lengthy version:

An execution environment (EE) provides so-called system packages which come with the corresponding JDK. Newer JDK versions used to be compatible in the sense that packages were added but none removed. It made sense to use the bundle's BREE as a minimal list of system packages for dependency resolution.

This changed since JDK 11 where packages like javax.annotation were removed from the JDK. E.g. dependency resolution of a bundle with BREE JavaSE-1.8 would provide a system package javax.annotation which was actually no longer there in JDK 11 and the build would fail with JDK 11. We are now using the EE of the currently running JDK for dependency resolution if JDK >=11 is used for the build. This will make sure package dependencies like javax.annotation will be resolved from bundles in the target platform instead of from system packages.

On the other hand you may want to be strict and make sure your build fails if you are using new API that has been added in a JDK later than the bundle's BREE. In this case the useJDK=BREE compiler option [1] can be used (same as before). 

[1] https://www.eclipse.org/tycho/sitedocs/tycho-compiler-plugin/compile-mojo.html#useJDK
Comment 18 Alexander Kurtakov CLA 2019-01-08 03:51:33 EST
Jan, do you think the patch should be backported to 1.3 and 1.3.1 version released? It would be really nice to be able to use Tycho and Java 11 .
Comment 19 Alexander Kurtakov CLA 2019-01-08 03:52:34 EST
Released Tycho version and Java 11 I mean.
Comment 20 Mickael Istria CLA 2019-01-08 03:55:31 EST
Thanks a lot for this works and for the explanation (that will be good in the N&N)

I'd like to add some comments about the potential impact of this change:
* Changing dependency-resolution strategy here may result in builds behaving differently from a version of Java to another
* But in all cases, most built artifacts (bundles, features, p2 IUs) should be identical whichever version of Java is used to build them.
* if building with JDK >= 11, then the content of a p2 repository when includeAllDependencies=true or of a product may now contain extra dependencies such as javax.annoatation compared to building with previous version of Java. In general, it shouldn't affect negatively the result as it expands the compatibility range of the p2 repo or product.
Comment 21 Jan Sievers CLA 2019-01-08 04:02:39 EST
(In reply to Alexander Kurtakov from comment #18)
> Jan, do you think the patch should be backported to 1.3 and 1.3.1 version
> released? It would be really nice to be able to use Tycho and Java 11 .

Maybe try this out in the wild some more before doing a patch release.
It probably makes sense if we find no regressions but personally I don't have the time for creating the release.
You can create a branch tycho-1.3.x based on the tycho-1.3.0 tag and cherry-pick the change. Then follow https://wiki.eclipse.org/Releasing_Tycho . Let me know if you need help.
Comment 22 Alexander Kurtakov CLA 2019-02-26 15:04:19 EST
*** Bug 534074 has been marked as a duplicate of this bug. ***
Comment 23 Mickael Istria CLA 2019-03-05 04:13:17 EST
Alex, would you mind to add a note about it to https://wiki.eclipse.org/Tycho/Release_Notes/1.4 ?
Comment 24 Phil Beauvoir CLA 2019-06-14 11:17:17 EDT
I'm seeing this issue with "unresolved requirement: Import-Package: javax.annotation"
 using AdoptOpenJDK 10.0.2 with Tycho 1.3.0 and 1.4.0.

Is there something extra I need to do?
Comment 25 Alexander Kurtakov CLA 2019-06-14 11:24:35 EDT
(In reply to Phil Beauvoir from comment #24)
> I'm seeing this issue with "unresolved requirement: Import-Package:
> javax.annotation"
>  using AdoptOpenJDK 10.0.2 with Tycho 1.3.0 and 1.4.0.
> 
> Is there something extra I need to do?

You must ensure javax.annotation bundle e.g. https://download.eclipse.org/tools/orbit/downloads/drops/R20181102183712/repository/plugins/javax.annotation_1.2.0.v201602091430.jar is available in the target platform.
Comment 26 Phil Beauvoir CLA 2019-06-14 12:23:16 EDT
(In reply to Alexander Kurtakov from comment #25)
> (In reply to Phil Beauvoir from comment #24)
> > I'm seeing this issue with "unresolved requirement: Import-Package:
> > javax.annotation"
> >  using AdoptOpenJDK 10.0.2 with Tycho 1.3.0 and 1.4.0.
> > 
> > Is there something extra I need to do?
> 
> You must ensure javax.annotation bundle e.g.
> https://download.eclipse.org/tools/orbit/downloads/drops/R20181102183712/
> repository/plugins/javax.annotation_1.2.0.v201602091430.jar is available in
> the target platform.

Thanks, though I couldn't figure out how to add that to my maven pom.xml file. I did succeed with the workaround in Comment #1

Am I right in thinking that the fix in Tycho 1.4 only works for JDK 11 and not for JDK 10? Or has it always been the case that one manually needs to add javax.annotation for JDK 10?
Comment 27 Phil Beauvoir CLA 2019-06-14 12:44:36 EDT
More info:

I'm running JUnit tests with Maven and Tycho for an RCP application.

This works:

Target Eclipse 4.7.
JDK 10.
Tycho 1.3 and 1.4.

This does not work:
Target Eclipse 4.11.
JDK 10.
Tycho 1.3 and 1.4.


Did something change in Eclipse 4.11 that broke this?
Comment 28 Alexander Kurtakov CLA 2019-11-08 06:33:14 EST
(In reply to Phil Beauvoir from comment #27)
> More info:
> 
> I'm running JUnit tests with Maven and Tycho for an RCP application.
> 
> This works:
> 
> Target Eclipse 4.7.
> JDK 10.
> Tycho 1.3 and 1.4.
> 
> This does not work:
> Target Eclipse 4.11.
> JDK 10.
> Tycho 1.3 and 1.4.
> 
> 
> Did something change in Eclipse 4.11 that broke this?

The fix is effective only for Java 11+. The change is probably that deps changed in 4.11 so javax.annotation is no longer pulled for you.