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

Allow signatures to be loaded as Maven artifacts #13

Closed
GoogleCodeExporter opened this issue Mar 14, 2015 · 16 comments
Closed

Allow signatures to be loaded as Maven artifacts #13

GoogleCodeExporter opened this issue Mar 14, 2015 · 16 comments
Assignees
Milestone

Comments

@GoogleCodeExporter
Copy link

In issue #10 it was shown that its possible to release "signature" artifacts as 
Maven packages. You could then add a dependency to the Maven plugin section of 
your POM and load the signaures JAR file into the plugin's classpath. Those 
signatures would then be available by the "bundled-signatures" config setting.

The only problem is the package name: All those Maven artifacts need to have 
the signatures in the de.thetaphi.forbiddenapis package, which violates general 
Maven bundling, which should have package names named by the released product 
(see also OSGI).

Instead the signatures should be moved into the META-INF/ folder of the JAR, so 
its universal. An addon signature artifact would then be a JAR file with only a 
META-INF/ resource folder.

Original issue reported on code.google.com by uwe.h.schindler on 11 Oct 2013 at 3:53

@GoogleCodeExporter
Copy link
Author

Original comment by uwe.h.schindler on 11 Oct 2013 at 3:54

  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect

@GoogleCodeExporter
Copy link
Author

I discovered that there is one nasty issue with the approach to add a 
dependency to the plugin declaration in the POM. Maven seems to simply add that 
dependency to the dependencies of the plugin (i.e. those declared in the POM of 
the plugin) and then to resolve them all in the same way. In particular, Maven 
will use the repositories declared in the POM of the plugin, and not the 
repositories declared in the POM of the project where the plugin is configured. 
This would still work for bundled signatures available from Maven central or if 
one builds the the JAR with the signatures first, but in all other cases, the 
build may fail with the following kind of error:

[ERROR] Failed to execute goal de.thetaphi:forbiddenapis:1.4-SNAPSHOT:check 
(default) on project synapse-nhttp-transport: Execution default of goal 
de.thetaphi:forbiddenapis:1.4-SNAPSHOT:check failed: Plugin 
de.thetaphi:forbiddenapis:1.4-SNAPSHOT or one of its dependencies could not be 
resolved: Could not find artifact 
org.apache.ws.commons.axiom:forbiddenapi-signatures:jar:1.2.15-SNAPSHOT in 
sonatype-nexus-snapshots 
(https://oss.sonatype.org/content/repositories/snapshots)

In the example shown above, Maven is trying to resolve 
org.apache.ws.commons.axiom:forbiddenapi-signatures:jar:1.2.15-SNAPSHOT from 
oss.sonatype.org because that repository is declared in the POM of the plugin 
(via its parent POM), but the artifact is in the Apache snapshot repository 
(which is properly declared in the POM of the project).

To get the desired feature (i.e. load bundles signatures from a Maven 
artifact), we will need to add a parameter to the plugin that allows to specify 
a list of Maven artifacts and then write the code that resolves these artifacts 
using the correct list of remote repositories.


Original comment by andreas.veithen@gmail.com on 14 Oct 2013 at 5:14

@GoogleCodeExporter
Copy link
Author

You think we should add code like in the animal-sniffer plugin?

See this:
https://fisheye.codehaus.org/browse/mojo/tags/animal-sniffer-parent-1.9/animal-s
niffer-maven-plugin/src/main/java/org/codehaus/mojo/animal_sniffer/maven/CheckSi
gnatureMojo.java?r=17664

This is a big change and I have to think about it, but we can make it work. So 
I would for now not move the bundled artifacts and instead we should do this as 
a separate "feature": Load signatures from remote artifacts, given by maven 
coordinates.

Original comment by uwe.h.schindler on 14 Oct 2013 at 5:55

@GoogleCodeExporter
Copy link
Author

> Load signatures from remote artifacts, given by maven coordinates.

This means signatures dont need to be JAR files, you can directly load them 
from Maven as a "signature file" artifact.

Original comment by uwe.h.schindler on 14 Oct 2013 at 5:59

@GoogleCodeExporter
Copy link
Author

> You think we should add code like in the animal-sniffer plugin?

Yes. Another example would be the "copy" goal in the maven-dependency-plugin.

> This means signatures dont need to be JAR files, you can directly load them 
from Maven as a "signature file" artifact.

As a matter of fact, it would not be required to package them as JARs.

Original comment by andreas.veithen@gmail.com on 24 Oct 2013 at 9:07

@GoogleCodeExporter
Copy link
Author

Original comment by uwe.h.schindler on 25 Oct 2013 at 9:48

  • Changed title: Allow signatures to be loaded as Maven artifacts

@GoogleCodeExporter
Copy link
Author

I checked around to find the easiest way to do this:

I have 2 ideas:

1) Add another signatures config option, which is a list of Strings, every 
string pointing to an artifact (like the get-Mojo in the maven-dependency 
plugin): http://maven.apache.org/plugins/maven-dependency-plugin/get-mojo.html
Those dependencies would be resolved directly from the configured repos, but 
not transitively.

2) List the artifacts as "standard dependecies" in your pom with a new 
type/scope in the standard dependencies section of your pom. I have no idea if 
this is easy possible:

<dependency>
 <groupId>you.own.group</groupId>
 <artifactId>myforbiddensignatures</artifactId>
 <version>x.x</version>
 <type>TOBEDISCUSSED</type>
 <scope>forbidden-apis</scope>
</dependency>

This would be most elegant, the maven plugin would only ask the resover to 
resolve all scope="forbidden-apis" artifacts (including dependencies, if they 
declare some!). The type would default to something unique for those artifacts. 
This approach would work like with any other dependency, so you can also list 
versions in dependencyManagement or whatever you can do here.

What do you think?

Original comment by uwe.h.schindler on 25 Oct 2013 at 10:36

@GoogleCodeExporter
Copy link
Author

The second approach would also allow to configure the dependencies per 
sub-module like in the standard Maven build scenario, so you would not need to 
disable signatures that don't resolve. The sub-projects would list the 
signatures together with their own JAR dependencies...

Original comment by uwe.h.schindler on 25 Oct 2013 at 10:38

@GoogleCodeExporter
Copy link
Author

Some investigation shows: scope="..." would be not possible. It should be more 
the type of artifact that is used to differentiate between standard deps and 
forbiddens. Like a WAR dependency is never added to compile classpath, although 
listed in scope="compile".

So the thing should look like this:
- add dependency to signatures for scope="compile" or scope="test" or both, 
e.g. runtime
- set type of dependency to "forbidden-apis-signature"

The plugin would then resolve all dependencies for the scope of compilation 
(CheckMojo or TestCheckMojo) and collect all artifacts of the 
"forbidden-apis-signature" type.

Original comment by uwe.h.schindler on 25 Oct 2013 at 12:17

@GoogleCodeExporter
Copy link
Author

I will delay this issue to be implemented after the next release, maybe for 
version 2.0. This requires major changes.

Original comment by uwe.h.schindler on 9 Nov 2013 at 11:31

@uschindler
Copy link
Member

One other soulution would be to allow <signatureResources>. This would load signatures from plugin's classpath. Not fixed to META-INF or other subfolder, just by giving a resource URI:

<signatureResources>
  <resource>my/own/package/signatures.txt</resource>
</signatureResources>

This would execute getClass().getClassloader().getResourceAsStream(...)

In any case, defining real maven dependencies would be the more flexible use case, but harder to do.

@veithen
Copy link

veithen commented May 25, 2015

Simply loading signatures from the plugin's classpath isn't a good solution because this implies that the Maven artifacts are added as plugin dependencies, but this won't work because plugin dependencies are loaded from the wrong repositories (see my first comment above).

@uschindler
Copy link
Member

Ah, you are right. But the possibility to do this could also be availabe or does it make no sense at all?

@uschindler
Copy link
Member

I started to work on this, want this to be ready for release of v. 2.0. Maven is at the moment the only plugin left that does not support signatures files from Maven central.

Gradle supports it out of box:

  • create configuration (e.g., "forbiddenSignatures") and add the artifacts as dependencies. You are free to use any type, just Maven coordinates are important
  • Assign the configuration (which implements FileCollection) to the signaturesFiles property of the task

Ant also supports it (since a few cleanups on weekend):

  • Moved the signatures to a separate XML element named <signatures>...</signatures>. This element can contain several resource types (all of Ant like files, filesets, ivy:cachefilesets, strings, and also a special type added by forbidden called <bundled name=.../>).
  • By this its possible to collect signatures files from any resource (also IVY or simply give an URL, string,...)

I like Ant's solution best, because you have full flexibility. You also can pick single files from JARs or whatever. Really everything is possible.

As always, maven will be most restricted. Adding a new dependency type is impossible.

The PR #79 implements a new configuration parameter signaturesArtifacts that is implemented by several strings for groupId, artifactId, version and type/packaging (+ other coordinate parts like qualifiers). This is very limited but should fit the needs. If you want to have it inside JAR artficats, the coordinates also optionally may supply a resource name (resolved against the JAR file). This is not yet implemented, but want to get basic setup working.

@uschindler
Copy link
Member

This is now how it looks like:

Possibility (a):

<signaturesArtifact>
  <groupId>org.apache.foobar</groupId>
  <artifactId>example</artifactId>
  <version>1.0</version>
  <classifier>signatures</classifier>
  <type>txt</type>
</signaturesArtifact>

(this relies on a separate .txt file artifact in Maven Central)

The alternative (b) is to refer to a TXT file inside a jar/war/zip/ear/... artifact using the "additional coordinate" named "path":

<signaturesArtifact>
  <groupId>org.apache.foobar</groupId>
  <artifactId>example</artifactId>
  <version>1.0</version>
  <type>jar</type>
  <path>path/inside/jar/file/signatures.txt</path>
</signaturesArtifact>

So practically, an alternative way to specify bundled signatures via Maven is:

<signaturesArtifact>
  <groupId>de.thetaphi</groupId>
  <artifactId>forbiddenapis</artifactId>
  <version>2.0-SNAPSHOT</version>
  <type>jar</type>
  <path>de/thetaphi/forbiddenapis/signatures/jdk-deprecated-1.6.txt</path>
</signaturesArtifact>

For both cases, the artifact declarations have to be wrapped inside an outer, additional <signaturesArtifacts>...</signaturesArtifacts> outer element.

PR #79 is almost ready, just a test for Maven 2 and Maven 3 is missing.

uschindler added a commit that referenced this issue Sep 29, 2015
Issue #13: Implement signatures artifacts, downloaded from Maven repos
@uschindler uschindler added this to the 2.0 milestone Sep 29, 2015
@uschindler
Copy link
Member

This feature was committed to master: bbc5418

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

No branches or pull requests

3 participants