Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to contribute artifacts directly? #4

Open
HannesWell opened this issue Apr 7, 2023 · 30 comments
Open

How to contribute artifacts directly? #4

HannesWell opened this issue Apr 7, 2023 · 30 comments

Comments

@HannesWell
Copy link

For eclipse-xtext/xtext#2056 I would like to add com.google.inject:guice:5.1.0 to the simrel-orbit, but no other project that uses maven-targets contributes it.

Can add it directly here? My first guess was to add it to the original.target in the suplement folder, but I'm not sure about that.
Can I just create a PR in this repo to add it?

@merks
Copy link
Owner

merks commented Apr 7, 2023

Some investigation is required...

It fails like this:

[ERROR] Cannot resolve project dependencies:
[ERROR]   Software being installed: org.eclipse.oomph.maven.site raw:1.0.0.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):1.0.0-SNAPSHOT
[ERROR]   Missing requirement: com.google.inject 5.1.0 requires 'java.package; com.google.common.base [30.1.0,31.0.0)' but it could not be found
[ERROR]   Cannot satisfy dependency: org.eclipse.oomph.maven.all.feature.group 4.28.0.qualifier depends on: org.eclipse.equinox.p2.iu; com.google.inject [5.1.0,5.1.0]
[ERROR]   Cannot satisfy dependency: org.eclipse.oomph.maven.site raw:1.0.0.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):1.0.0-SNAPSHOT depends on: org.eclipse.equinox.p2.iu; org.eclipse.oomph.maven.all.feature.group 0.0.0

I'd expect that to come from this which is present.

        <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>31.1-jre</version>
          <type>jar</type>
        </dependency>

I'll investigate tomorrow.

The stuff still lives git.eclipse.org...

https://git.eclipse.org/c/oomph/org.eclipse.oomph.incubator.git/plain/OomphIncubator.setup

@HannesWell
Copy link
Author

HannesWell commented Apr 7, 2023

Guice 5.1.0 indeed still requires Guava 30.1, this is a longer standing issue that did not get much attention from the guice devs yet :/

There was even the suggestion to remove the need for guava from guice, but that was also not answered:

@merks
Copy link
Owner

merks commented Apr 7, 2023

Yes, it needs this old thing:

        <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>30.1-jre</version>
          <type>jar</type>
        </dependency>

Then it misses this:

[ERROR] Cannot resolve project dependencies:
[ERROR]   Software being installed: org.eclipse.oomph.maven.site raw:1.0.0.'SNAPSHOT'/format(n[.n=0;[.n=0;[-S]]]):1.0.0-SNAPSHOT
[ERROR]   Missing requirement: com.google.inject 5.1.0 requires 'java.package; com.google.errorprone.annotations 0.0.0' but it could not be found
[ERROR]   Cannot satisfy dependency: org.eclipse.oomph.maven.all.feature.group 4.28.0.qualifier depends on: org.eclipse.equinox.p2.iu; com.google.inject [5.1.0,5.1.0]

And then I don't think there is a maven artifact that is also an OSGi library for this...

What a mess....

@HannesWell
Copy link
Author

I hope that is available in https://mvnrepository.com/artifact/com.google.errorprone/error_prone_annotations

But yes that's all not so nice...
It also Looks like that the google-devs are not eager to Update their own deps.

Maybe you could also try to include compile dependencies in the Maven Location automatically? Then it should be simpler to set up and since only the required deps are in included in the repo we cannot avoid it anyway.

@merks
Copy link
Owner

merks commented Apr 8, 2023

These are not OSGi bundles:

https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotation/2.9.0/
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.9.0/

In general, I want to avoid using implicit dependencies because I want to know explicitly what is being pulled in and what version is being pulled in so that I can check those versions and report on them.

I could generate bundle information for those, but that's no longer a direct-from-maven dependency where we simply reuse the jar (maybe even keep the PGP signature). It's pretty much what Orbit does with its BND recipes to repackage the jars.

It seems to me that if we're not careful, everyone will happily repackage such things slightly differently, pulling in transitive dependencies without actually knowing what those are, producing multiple different artifacts with the same artifact key. That appears to be what this is doing:

https://github.com/eclipse/tm4e/blob/84c448f4d75b314f2fda8ae4b29ae07667a8e1de/target-platform/tm4e-target.target#L35-L54

There's also an aopalliance dependency, which is not an OSGi bundle, but that a least is available in Orbit.

image

It seems the m2e resolution is only considering the explicit pom dependencies:

https://repo1.maven.org/maven2/com/google/inject/guice/5.1.0/guice-5.1.0.pom

So it doesn't care that the package requirements of the OSGi bundle don't resolve:

Import-Package: com.google.common.base;version="[30.1,31)",com.google.
 common.cache;version="[30.1,31)",com.google.common.collect;version="[
 30.1,31)",com.google.common.primitives;version="[30.1,31)",com.google
 .errorprone.annotations,javax.annotation;version="[3.0,4)",javax.inje
 ct,org.aopalliance.intercept

That's going to be a problem when you try to actually use the bundle though isn't it?

@HannesWell
Copy link
Author

These are not OSGi bundles:

https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotation/2.9.0/ https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.9.0/

Oh man, that's really a mess.

In general, I want to avoid using implicit dependencies because I want to know explicitly what is being pulled in and what version is being pulled in so that I can check those versions and report on them.

Yes, that's understandable. But from my experience not every Maven dependency pulled into the TP by a Maven-TargetLocation is eventually required in an OSGi runtime. Especially Annotations are sometimes not needed. So altough they might be in the TP, they don't end up in a product or repo since P2 then only considers OSGi metadata and not maven-dependencies.

I could generate bundle information for those, but that's no longer a direct-from-maven dependency where we simply reuse the jar (maybe even keep the PGP signature). It's pretty much what Orbit does with its BND recipes to repackage the jars.

I agree that its bad, but I'm a bit hopeless that it would work without.

As a side note, what do you think about migrating the BND-recipes in Orbit to use maven targets with explict BND-instructions that generated the OSGi metadata? That would also be an opportunity to sort out what's already available as OSGi-compatible jar on Maven-Central.

It seems to me that if we're not careful, everyone will happily repackage such things slightly differently, pulling in transitive dependencies without actually knowing what those are, producing multiple different artifacts with the same artifact key. That appears to be what this is doing:

https://github.com/eclipse/tm4e/blob/84c448f4d75b314f2fda8ae4b29ae07667a8e1de/target-platform/tm4e-target.target#L35-L54

Yes, in such cases we will probably need a central repo forever that manages how such dependencies are OSGi-ified.

It seems the m2e resolution is only considering the explicit pom dependencies:

https://repo1.maven.org/maven2/com/google/inject/guice/5.1.0/guice-5.1.0.pom

Yes the target-location can only pull in all (transitive) Maven dependencies if configured accordingly. Since that Target-location only knows about maven, that's the only thing it can do.

So it doesn't care that the package requirements of the OSGi bundle don't resolve:

Import-Package: com.google.common.base;version="[30.1,31)",com.google.
 common.cache;version="[30.1,31)",com.google.common.collect;version="[
 30.1,31)",com.google.common.primitives;version="[30.1,31)",com.google
 .errorprone.annotations,javax.annotation;version="[3.0,4)",javax.inje
 ct,org.aopalliance.intercept

That's going to be a problem when you try to actually use the bundle though isn't it?

That's right and that's indeed likely a problem. Funny enough that the Maven dependency to errorprone.annotations only comes transitively through guava, which does not require it at runtime (at least according to its OSGi metadata).

I looked a bit into the guice code and wonder if the com.google.errorprone.annotations.Keep annotation really needs to have a runtime retention policy from its doc I would say that SOURCE source should be sufficient for the described purpose of static code analysis.
The com.google.errorprone.annotations.CheckReturnValue annotation could have better reasons to be kept since callers of annotation methods/classes should be checked with that.
It's a mess.

@merks
Copy link
Owner

merks commented Apr 14, 2023

I think it's very interesting to consider using the m2e target location for simple BND recipes and I'd like to explore that further, time permitting. But that time is not available until after next week at the earliest...

@HannesWell
Copy link
Author

I think it's very interesting to consider using the m2e target location for simple BND recipes and I'd like to explore that further, time permitting. But that time is not available until after next week at the earliest...

I just created an issue to discuss that in Orbit: eclipse-orbit/orbit#8

@merks
Copy link
Owner

merks commented Apr 17, 2023

I got the first thing, error_prone_annotations, working:

		  <dependencies>
			  <dependency>
				  <groupId>com.google.errorprone</groupId>
				  <artifactId>error_prone_annotations</artifactId>
				  <version>2.18.0</version>
				  <type>jar</type>
			  </dependency>
			  <dependency>
				  <groupId>com.google.guava</groupId>
				  <artifactId>guava-base</artifactId>
				  <version>r30</version>
				  <type>jar</type>
			  </dependency>
		  </dependencies>
		  <instructions><![CDATA[
Bundle-Name:           Bundle derived from maven artifact ${mvnGroupId}:${mvnArtifactId}:${mvnVersion}
version:               ${version_cleanup;${mvnVersion}}
Bundle-SymbolicName:   ${mvnGroupId}.${mvnArtifactId}
Bundle-Version:        ${version}
Import-Package:        *;resolution:=optional
Export-Package:        *;version="${version}";-noimport:=true
DynamicImport-Package: *
]]></instructions>

But the guava-base dependency doesn't work. Maybe because it's kind of a weird version number? The error is

Could not resolve artifact com.google.guava:guava-base:jar:r30

That definitely exists though:

https://repo1.maven.org/maven2/com/google/guava/guava-base/r03/

I also wonder about the details of the BND instructions. E.g., does it make sense to consider all package imports optional? I have my doubts about that. In general, will each artifact need specialized instructions? I kind of suspect so because r30 is a pretty strange version number.

The generated manifest has quite some "noise" in it such that repeated builds will not produce the same manifest:

Manifest-Version: 1.0
Automatic-Module-Name: com.google.errorprone.annotations
Bnd-LastModified: 1681659866842
Build-Jdk-Spec: 11
Bundle-ManifestVersion: 2
Bundle-Name: Bundle derived from maven artifact com.google.errorprone:
 error_prone_annotations:2.18.0
Bundle-SymbolicName: com.google.errorprone.error_prone_annotations
Bundle-Version: 2.18.0
Created-By: 17.0.4.1 (Eclipse Adoptium)
DynamicImport-Package: *
Export-Package: com.google.errorprone.annotations;version="2.18.0";use
 s:="javax.lang.model.element",com.google.errorprone.annotations.concu
 rrent;version="2.18.0"
Import-Package: javax.lang.model.element;resolution:=optional
Originally-Created-By: Maven JAR Plugin 3.2.2
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-6.4.0.202211291949

That's not so nice...

@HannesWell
Copy link
Author

But the guava-base dependency doesn't work. Maybe because it's kind of a weird version number? The error is

Could not resolve artifact com.google.guava:guava-base:jar:r30

That definitely exists though:

https://repo1.maven.org/maven2/com/google/guava/guava-base/r03/

That's right that this exists, but it seems to be an artifact from 2010: https://mvnrepository.com/artifact/com.google.guava/guava-base/r03
And I don't think we want that. 😅 The usual guava works fine.

I also wonder about the details of the BND instructions. E.g., does it make sense to consider all package imports optional? I have my doubts about that. In general, will each artifact need specialized instructions? I kind of suspect so because r30 is a pretty strange version number.

No we probably don't want to make all imports optional. This is just chosen as default to make it as flexible as possible and working as many cases as possible (e.g. often compile-time only deps are also listed) assuming that the required dependencies are actually specified in the pom. But since in general the BND-instructions are just a fallback it is totally fine to modify them to a more reasonable value for real world use.

It of course depends on the exact metadata, but for what I have encountered so far e.g. with using wildcards smartly one set of instructions was sufficient.

The generated manifest has quite some "noise" in it such that repeated builds will not produce the same manifest:

You can use the -noextraheaders instruction to remove them. If that is not sufficient you can explicitly remove headers using the -removeheaders instruction (and list the headers to remove afterwards.

The BND-lib references and incides can often be helpful:

To sum this up, I would use a location like the following. I tried to use the latest version possible.
E.g. for guava 30.x I used 30.1.1 which can also replace the 30.x version from orbit even for those bundles that require guava<31.
:

		<location includeDependencyDepth="none" includeDependencyScopes="" includeSource="true" label="Google" missingManifest="generate" type="Maven">
			<dependencies>
				<dependency>
					<groupId>com.google.errorprone</groupId>
					<artifactId>error_prone_annotations</artifactId>
					<version>2.18.0</version>
					<type>jar</type>
				</dependency>
				<dependency>
					<groupId>com.google.guava</groupId>
					<artifactId>failureaccess</artifactId>
					<version>1.0.1</version>
					<type>jar</type>
				</dependency>
				<dependency>
					<groupId>com.google.guava</groupId>
					<artifactId>guava</artifactId>
					<version>30.1.1-jre</version>
					<type>jar</type>
				</dependency>
				<dependency>
					<groupId>com.google.inject</groupId>
					<artifactId>guice</artifactId>
					<version>5.1.0</version>
					<type>jar</type>
				</dependency>
				<dependency>
					<groupId>javax.inject</groupId>
					<artifactId>javax.inject</artifactId>
					<version>1</version>
					<type>jar</type>
				</dependency>
			</dependencies>
			<instructions><![CDATA[
Bundle-Name:           Bundle derived from maven artifact ${mvnGroupId}:${mvnArtifactId}:${mvnVersion}
version:               ${version_cleanup;${mvnVersion}}
Bundle-SymbolicName:   eclipse.orbit.wrapped.${mvnGroupId}.${mvnArtifactId}
Bundle-Version:        ${version}
Import-Package:        *
Export-Package:        *;version="${version}";-noimport:=true
-noextraheaders: true
]]></instructions>
			<exclude>com.google.code.findbugs:jsr305:3.0.1</exclude>
			<exclude>com.google.code.findbugs:jsr305:3.0.2</exclude>
			<exclude>com.google.j2objc:j2objc-annotations:1.3</exclude>
			<exclude>org.checkerframework:checker-qual:3.5.0</exclude>
		</location>

@HannesWell
Copy link
Author

Btw. I noticed that changed instructions are not always taken into account by m2e. I'll look into that tomorrow.

@merks
Copy link
Owner

merks commented Apr 18, 2023

That's helpful information! I forgot it just required an older version of guava for the "base" package, which is already a very annoying problem when trying to eliminate duplicates, and especially so for guava which tends to be visible in APIs...

Going further, this does seem to be a bit of a rat hole with this failure trying what you showed:

[ERROR] Failed to resolve target definition file:/D:/Users/merks/oomph-incubator-1.0/git/org.eclipse.oomph.incubator/maven/tp/Maven.target: Artifact MavenArtifactFacade [wrappedArtifact=javax.inject:javax.inject:jar:1] of location MavenDependencyRoots = [GroupId = com.google.errorprone, ArtifactId = error_prone_annotations, Version = 2.18.0, ArtifactType = jar, IncludeDependencyScope = , GroupId = com.google.guava, ArtifactId = guava, Version = 30.1-jre, ArtifactType = jar, IncludeDependencyScope = , GroupId = javax.inject, ArtifactId = javax.inject, Version = 1, ArtifactType = jar, IncludeDependencyScope = ], IncludeDependencyScope = [compile], MissingManifestStrategy = GENERATE, IncludeSource = true is not a valid jar file

With this failure without that dependency:

[ERROR] Missing requirement: com.google.inject 5.1.0 requires 'java.package; javax.annotation [3.0.0,4.0.0)' but it could not be found

Note the package version range above which makes me wonder does this ancient really provide that package version?

https://repo1.maven.org/maven2/javax/inject/javax.inject/1/

Given it's not an OSGi bundle, we can't really say can we.

I will investigate further.

@HannesWell
Copy link
Author

With this failure without that dependency:

[ERROR] Missing requirement: com.google.inject 5.1.0 requires 'java.package; javax.annotation [3.0.0,4.0.0)' but it could not be found

Regarding this failure, the version range is probably coming due the presence of javax.annotation.Nullable in the code, which is provided by com.google.code.findbugs:jsr305:3.0.1.

The good news is that in the 5.1.1-SNAPSHOT, since google/guice#1173 (which was just merged tonight) version range from the javax.annotation has no version range anymore.
I assume the intention was to remove it completely, but at least it can now be served by the javax.annotation bundle (which in fact does not contain the Nullable annotation), but that seems not necessary at runtime anyways.

Furthermore with this change Import-Package header values were changed from version 5.1.0

Import-Package:
 com.google.common.base;version="[30.1,31)",
 com.google.common.cache;version="[30.1,31)",
 com.google.common.collect;version="[30.1,31)",
 com.google.common.primitives;version="[30.1,31)",
 com.google.errorprone.annotations,
 javax.annotation;version="[3.0,4)",
 javax.inject,
 org.aopalliance.intercept

to

Import-Package:
 com.google.common.base;version="31.0",
 com.google.common.cache;version="31.0",
 com.google.common.collect;version="31.0",
 com.google.common.primitives;version="31.0",
 com.google.errorprone.annotations,
 javax.annotation,
 javax.inject,
 org.aopalliance.intercept,
 sun.misc

The missing upper bound is not great in SemVer terms but at least allows to use Guice with a new major version of Guava, which comes relatively often but often only breaks not relevant parts.

@merks
Copy link
Owner

merks commented Apr 24, 2023

This issue suggests that this "findbugs" thing also leads to problems:

eclipse-platform/eclipse.platform.ui#727 (comment)

@HannesWell

Even just updating what I have I hit this new problem:

[ERROR] Missing requirement: ch.qos.logback.classic 1.4.7 requires 'osgi.serviceloader; (osgi.serviceloader=ch.qos.logback.classic.spi.Configurator)' but it could not be found
[ERROR] Cannot satisfy dependency: org.eclipse.oomph.maven.all.feature.group 4.28.0.qualifier depends on: org.eclipse.equinox.p2.iu; ch.qos.logback.classic [1.4.7,1.4.7]

Looking in the jar, I get the sense that this jar itself should be providing this capability:

image

Is there something wrong with the new 1.4.7 version?

@HannesWell
Copy link
Author

HannesWell commented Apr 24, 2023

The best thing would probably be to completely remove the import of javax.annotation from guice as suggested in the linked guice PR. I'll create a PR there.

Alternatively proper version ranges could also help (jsr305 has Version 3 and the other one Version 1.x).
Or maybe we are lucky with the javax -> Jakarta Migration and jsr305 stays at javax.

Is there something wrong with the new 1.4.7 version?

Ah, damn. I should have made them optional in qos-ch/logback#639

I'll provide a fix for logback this evening.

@HannesWell
Copy link
Author

HannesWell commented Apr 24, 2023

The best thing would probably be to completely remove the import of javax.annotation from guice as suggested in the linked guice PR. I'll create a PR there.

Just created

Alternatively proper version ranges could also help (jsr305 has Version 3 and the other one Version 1.x). Or maybe we are lucky with the javax -> Jakarta Migration and jsr305 stays at javax.

Is there something wrong with the new 1.4.7 version?

Ah, damn. I should have made them optional in qos-ch/logback#639

I'll provide a fix for logback this evening.

Created

@HannesWell
Copy link
Author

@merks both PRs where merged.
Do you want to try Guice 5.1.1-SNAPSHOT? AFAICT guice snapshots are deployed to the standard OSSRH snapshot repo and therefore don't need an extra repo configured.

For Logback I'm not aware of any snapshot repo.

@merks
Copy link
Owner

merks commented Apr 26, 2023

I added it to the target and it builds, but it silently not actually included in the result. In fact, if I added it without -SNAPSHOT I see this in the log:

Downloading from central-id: https://repo1.maven.org/maven2/com/google/inject/guice/5.1.1/guice-5.1.1.jar

But no failure messages, and the build completes as if this dependency were not present at all.

The PDE shows it as a problem though:

image

Also for this:

image

So I guess there is nothing I can test yet and I guess there is a bit of a problem in Tycho not reporting errors for missing dependencies...

@guw
Copy link

guw commented May 3, 2023

@merks Would it make sense to include the fix for Findbugs here?
eclipse-platform/eclipse.platform.ui#727 (comment)

There is a lot more code out there which depends on this weird package. :(

@guw
Copy link

guw commented May 3, 2023

Ok, forget about the idea. It doesn't seem to work. The PDE Maven support is only generating OSGi metadata when it's missing. It's not updating/patching/manipulating existing (wrong) metadata.

@merks
Copy link
Owner

merks commented May 3, 2023

Yes, a repair needs a new publish. 😞

@HannesWell
Copy link
Author

Ok, forget about the idea. It doesn't seem to work. The PDE Maven support is only generating OSGi metadata when it's missing. It's not updating/patching/manipulating existing (wrong) metadata.

That's right. The possibility to generate a OSGi compliant manifest is intended as fallback and not to alter existing metadata. In general the goal of the Maven targets is to consumer original Maven artifacts, to not have diverging jars. Modifying the manifest of course modifies the jar. Without OSGi metadata there is no other ways than altering the jar afterwards, but in general the better way is always to contribute OSGi metadata upstream. IIRC we already had a discussion about that in the m2e issue tracker, but on a quick search I didn't found it.

And in case of jsr-305 the metadata are right, it is just unfortunate that jsr-305 and javax.annotation spec share the same package name,

Regarding JSR-305, it looks like its use is reduced e.g. the upcoming Guice 6.0 will not have any reference to javax.annotation in its Manifest; #4 (comment)

@merks
Copy link
Owner

merks commented May 3, 2023

I suppose technically one can wrap an unaltered jar in an OSGi bundle. But there’s not really an advantage to that!

@HannesWell
Copy link
Author

@merks sorry for the delay I now assembled a self-contained working target that includes guice 6.0.0-rc2, guice 7.0.0-rc1 and guava 31.1-jre and all dependencies required in OSGi.
The two guice version are due to the transition from javax to jakarta (see the linked release notes).

    <location includeDependencyDepth="none" includeDependencyScopes="compile,runtime" includeSource="true" label="Google" missingManifest="generate" type="Maven">
      <dependencies>
        <dependency>
          <groupId>aopalliance</groupId>
          <artifactId>aopalliance</artifactId>
          <version>1.0</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.errorprone</groupId>
          <artifactId>error_prone_annotations</artifactId>
          <version>2.19.1</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>failureaccess</artifactId>
          <version>1.0.1</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>31.1-jre</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.inject</groupId>
          <artifactId>guice</artifactId>
          <version>6.0.0-rc2</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.inject</groupId>
          <artifactId>guice</artifactId>
          <version>7.0.0-rc1</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>jakarta.inject</groupId>
          <artifactId>jakarta.inject-api</artifactId>
          <version>1.0.5</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>jakarta.inject</groupId>
          <artifactId>jakarta.inject-api</artifactId>
          <version>2.0.1</version>
          <type>jar</type>
        </dependency>
      </dependencies>
      <instructions><![CDATA[
Bundle-Name:           Bundle derived from maven artifact ${mvnGroupId}:${mvnArtifactId}:${mvnVersion}
version:               ${version_cleanup;${mvnVersion}}
Bundle-SymbolicName:   eclipse.orbit.wrapped.${mvnGroupId}.${mvnArtifactId}
Bundle-Version:        ${version}
Import-Package:        *
Export-Package:        *;version="${version}";-noimport:=true
-noextraheaders: true
-removeheaders: Private-Package
]]></instructions>
      <exclude>javax.inject:javax.inject:1</exclude>
      <exclude>com.google.code.findbugs:jsr305:3.0.1</exclude>
      <exclude>com.google.code.findbugs:jsr305:3.0.2</exclude>
      <exclude>com.google.j2objc:j2objc-annotations:1.3</exclude>
      <exclude>org.checkerframework:checker-qual:3.5.0</exclude>
    </location>

If you want to leverage transitive dependencies it can be trimmed to:

    <location includeDependencyDepth="infinite" includeDependencyScopes="compile,runtime" includeSource="true" label="Google" missingManifest="generate" type="Maven">
      <dependencies>
        <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>31.1-jre</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.inject</groupId>
          <artifactId>guice</artifactId>
          <version>6.0.0-rc2</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>com.google.inject</groupId>
          <artifactId>guice</artifactId>
          <version>7.0.0-rc1</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>jakarta.inject</groupId>
          <artifactId>jakarta.inject-api</artifactId>
          <version>1.0.5</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>jakarta.inject</groupId>
          <artifactId>jakarta.inject-api</artifactId>
          <version>2.0.1</version>
          <type>jar</type>
        </dependency>
      </dependencies>
      <instructions><![CDATA[
Bundle-Name:           Bundle derived from maven artifact ${mvnGroupId}:${mvnArtifactId}:${mvnVersion}
version:               ${version_cleanup;${mvnVersion}}
Bundle-SymbolicName:   eclipse.orbit.wrapped.${mvnGroupId}.${mvnArtifactId}
Bundle-Version:        ${version}
Import-Package:        *
Export-Package:        *;version="${version}";-noimport:=true
-noextraheaders: true
-removeheaders: Private-Package
]]></instructions>
      <exclude>javax.inject:javax.inject:1</exclude>
      <exclude>com.google.code.findbugs:jsr305:3.0.1</exclude>
      <exclude>com.google.code.findbugs:jsr305:3.0.2</exclude>
      <exclude>com.google.j2objc:j2objc-annotations:1.3</exclude>
      <exclude>org.checkerframework:checker-qual:3.5.0</exclude>
    </location>

The main problem was that javax.inject:javax.inject:1 currently cannot be wrapped by Tycho:
eclipse-tycho/tycho#2394

All other exclusions are actually/probably not necessary because they are not required by OSGi metadata. So even though they might end up as generated/wrapped bundles in the TP, they will not make it in any p2-repo unless they are explicitly included in a feature.

At the moment this generates/wrapps an OSGi artifact for error_prone_annotations and aopalliance. For the latter there is already a bundle in Eclipse-Orbit and for the former I have created a PR to add proper OSGi metadata.

Do you want me to contribute that somewhere, to be ready when Guice 6 and 7 are released?

@laeubi
Copy link

laeubi commented May 11, 2023

Missing requirement: com.google.inject 5.1.0 requires 'java.package; com.google.errorprone.annotations

It is very likely from the documentation that the errorprone annotations are only class retention annotations and therefore are not needed at all at runtime.

@HannesWell
Copy link
Author

Missing requirement: com.google.inject 5.1.0 requires 'java.package; com.google.errorprone.annotations

It is very likely from the documentation that the errorprone annotations are only class retention annotations and therefore are not needed at all at runtime.

Unfortunately they really do have retention policy runtime. :/
One example is com.google.errorprone.annotations.Keep.

And I have to admit that I don't know what happens if one enoumerates over the annotations of a class and the annotation class cannot be loaded? Is that annotation just skipped, does the whole operation throw a Exception?
If the whole thing does not explode when an annotation class cannot be loaded, I think it would be possible to ask in guice to make the package-import optional, but if it does explode that's not a way to go.
Alternatively we can simply hope that google/error-prone#3903 is available soon. :)

@guw
Copy link

guw commented May 11, 2023

And I have to admit that I don't know what happens if one enoumerates over the annotations of a class and the annotation class cannot be loaded? Is that annotation just skipped, does the whole operation throw a Exception?

Missing annotation are skipped, i.e. as if they were not applied/set.
https://stackoverflow.com/questions/3567413/why-doesnt-a-missing-annotation-cause-a-classnotfoundexception-at-runtime

@merks
Copy link
Owner

merks commented May 11, 2023

BTW, one thing that makes me a bit "paranoid" about wrapping is that if one makes a mistake in the recipe, or needs to update the recipe, one has to be concerned about creating a new IU/artifact-key with a higher version number. So these for example

https://git.eclipse.org/c/oomph/org.eclipse.oomph.incubator.git/tree/maven-bnd/tp/MavenBND.target#n58

which are published here:

https://download.eclipse.org/oomph/simrel-maven-bnd/nightly/N202305021250/index.html

are really hard to fix if they are broken. My recipe didn't include -removeheaders: Private-Package so is that bad?

One could of course do something in the recipe about the version.

Bundle-Version:        ${version}

But this recipe applies for all bundles in the group/feature, not per bundle, so if one had to fix one bundle one would have to split it out...

With the Orbit approach, the qualifier comes from the commit of the corresponding project and if one changes the recipe, this commit time stamp changes. With this m2e target approach, there is nothing to correspond to that and it makes me concerned about how to manage this in case one doesn't get it exactly right the first time...

@HannesWell
Copy link
Author

And I have to admit that I don't know what happens if one enoumerates over the annotations of a class and the annotation class cannot be loaded? Is that annotation just skipped, does the whole operation throw a Exception?

Missing annotation are skipped, i.e. as if they were not applied/set. https://stackoverflow.com/questions/3567413/why-doesnt-a-missing-annotation-cause-a-classnotfoundexception-at-runtime

Thanks for the link.
Just created google/guice#1739, lets see what they say.

are really hard to fix if they are broken. My recipe didn't include -removeheaders: Private-Package so is that bad?

That's indeed a difficult situation. But regarding this specific case the Private-Package are not that bad. Headers unknown to the OSGi runtime are simply ignored and Private-Package is not used AFAIK, therefore this is just some noise in the Manifest but not too bad.

One could of course do something in the recipe about the version.

Bundle-Version:        ${version}

But this recipe applies for all bundles in the group/feature, not per bundle, so if one had to fix one bundle one would have to split it out...

That's the only salutation I can think of to increment the version (append a manually specified suffix).
In theory we could add something like a extra-properties element per dependency where you could specify a version-suffix property that is referenced in the instructions. But since the metadata-generation is only a fall-back and not considered a first class solution, I'm not sure what the other m2e committers think about that. Furthermore I'm not sure if that really fits well into the goal to mainly use standard maven elements in Maven-target locations.
But in general I think that scenario is not that common. I believe once the default instructions are settled they don't change often and until then the version suffix of all artifacts have to be bumped anyways.
And if another artifact needs custom instruction it is likely in its own location already anyways.

Btw. from the MavenBND.target I would also remove the DynamicImport-Package header.
And for the BSN I suggest to use a generated name that reflects more clearly that this is a wrapped bundle.
This discussion gives some background: eclipse-m2e/m2e-core#330

@HannesWell
Copy link
Author

And I have to admit that I don't know what happens if one enoumerates over the annotations of a class and the annotation class cannot be loaded? Is that annotation just skipped, does the whole operation throw a Exception?

Missing annotation are skipped, i.e. as if they were not applied/set. https://stackoverflow.com/questions/3567413/why-doesnt-a-missing-annotation-cause-a-classnotfoundexception-at-runtime

Thanks for the link. Just created google/guice#1739, lets see what they say.

The PR has been merged just in time for the Guice 6/7 release, so for that we don't need error-prone anymore and therefore don't have to wrap it (the PR to add OSGi metadata to error-prone is merged too but not yet released).

Nevertheless I'm trying to convince the Xtext devs, to use the Maven targets directly inhttps://github.com/eclipse-xtext/xtext/pull/2207.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants