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

Don't fail the build if a dep has multiple licenses and at least one of them is not denylisted #25

Closed
alaindesilets opened this issue Jan 17, 2023 · 13 comments · Fixed by #34
Labels
bug Something isn't working question Further information is requested

Comments

@alaindesilets
Copy link

I don't want depdendancies that are only available under GPL. However I am available with GPL deps that also offer more permissive licenses.

Here is how I encode that in my pom:

		<plugin>
			<groupId>com.github.carlomorelli</groupId>
			<artifactId>licensescan-maven-plugin</artifactId>
			<version>2.1</version>
			<configuration>
				<printLicenses>true</printLicenses>
				<blacklistedLicenses>
					<!-- GPL and Afferor are not allowed, unless they are IN ADDITION
					     to another license -->
					<license>regex:.*(?&lt;!\+\s?)GNU General Public License.*</license>
					<license>regex:.*(?&lt;!(L|\+\s?))GPL.*</license>
					<license>regex:.*(?&lt;!\+\s?)Affero.*</license>
				</blacklistedLicenses>
				<failBuildOnBlacklisted>true</failBuildOnBlacklisted>
			</configuration>
			<executions>
				<execution>
					<phase>compile</phase> 
					<goals>
						<goal>audit</goal>
					</goals>
				</execution>
			</executions>
		</plugin>

I thought this worked because for the longest time I didn't get any failures. But today I added jakarta.json-api to my pom and it does cause the build to fail, eventhough it's available under both GPL and Apache licenses.

I am guessing that the problem comes from the fact that the plugin checks each of those licenses against the provided regexes.

Is there a way to support my use case?

Thx

@alaindesilets
Copy link
Author

BTW, here is what the plugin prints out for the license info for jakarta.json-api:

[INFO]  - artifact jakarta.json:jakarta.json-api:2.0.1:compile
[INFO]    with license: Eclipse Public License 2.0
[INFO]    with license: GNU General Public License, version 2 with the GNU Classpath Exception

@carlomorelli
Copy link
Owner

I'm not a great RegEx expert, can you provide examples on what this regex .*(?&lt;!\+\s?)GNU General Public License would capture?

@carlomorelli
Copy link
Owner

carlomorelli commented Jan 17, 2023

In any case, the problem is that we don't unescape the &lt; char, which is needed before sending to the Pattern matcher. Will take a look on this.

More than else, I'm surprised you don't get an exception during mvn compile and you get thrown at the command prompt. But it's probably some exception handling that Maven does.

@alaindesilets
Copy link
Author

For example:

Licensed under: GNU General Public License or Eclipse Public License 2.0

In other words, if the description of the dependency's license mentions GNU as well as another license.

But I get the feeling that the plugin matches regexps agains each license individually.

@alaindesilets
Copy link
Author

Actually, this string

Licensed under: GNU General Public License or Eclipse Public License 2.0

is an example of a string that should NOT match the regex. But the following should:

GNU General Public License 

@carlomorelli
Copy link
Owner

You have to help me here, please provide some more examples. One single example where you also contradict from one post to another does not help (you can also edit the posts btw).

I've done some tests in RegExr and it looks like you want to use "negative lookbehind" matching?

  1. before the regex gets processed, i think there is an overlap of two problems.
  • One problem is due to a bug -- we don't do any XML unescaping before passing the regex string into the pattern class, and that is necessary to convert &lt; into <. This will be fixed.
  • Second problem is on your side. You need to escape properly Java-style your regexes. So in short if you need to submit this regex ".(?<!+\s?)GNU General Public License." this is the actual string you have to use: .*(?&lt;!\\+\\s?)GNU General Public License.* (notice the escaping of slashes)
  1. this plugin is built with Java 1.6 retrocompatibility in mind. It looks that this "negative lookbehind" is not really working as you expect until Java8. See if what is written in this Baeldung page can help you reformulate your regexes ?

@alaindesilets
Copy link
Author

You need to escape properly Java-style your regexes.

Oops. They were escaped originally, but they got unescaped in the process of commenting and uncommenting them out (using intelliJ). In any case, I have restored them to their escaped state:

<!-- GPL and Afferor are not allowed, unless they are IN ADDITION
  to another license -->
<license>regex:.*(?&lt;!\+\s?)GNU General Public License.*</license>
<license>regex:.*(?&lt;!(L|\+\s?))GPL.*</license>
<license>regex:.*(?&lt;!\+\s?)Affero.*</license>

but I still get the following failures:

[INFO]  - artifact jakarta.json:jakarta.json-api:2.0.1:compile
[INFO]    with license: Eclipse Public License 2.0
[INFO]    with license: GNU General Public License, version 2 with the GNU Classpath Exception
[WARNING] WARNING: found blacklisted license

[WARNING] WARNING: found blacklisted license
[INFO]  - artifact org.eclipse.parsson:parsson:1.0.0:compile
[INFO]    with license: Eclipse Public License 2.0
[INFO]    with license: GNU General Public License, version 2 with the GNU Classpath Exception
[WARNING] WARNING: found blacklisted license

Is there a way to see the exact string that the plugin is trying to match against the blacklist regexps and which of the blacklist regexps failed on it? That would greatly help in debugging the regexps.

I wrote the regexps a few years ago so I am a bit fuzzy on the details. But I think they assume that they will be matched against a string that looks like this:

License 1 + License 2 + License 3 etc...

In other words, all available licenses are listed on a single line, joined by + signs. The regexps will flag strings that contain "GNU General Public License", "Affero" or "GPL", but only if they are NOT preceded by a + sign (and, in the case of GPL, the character L, because I am OK with LGPL dependencies).

The properly escaped regexps seem to work as intended for this kind of one-line format, because following dependency does NOT get flagged:

[INFO]  - artifact com.sun.xml.bind:jaxb-core:2.3.0.1:compile
[INFO]    with license: CDDL+GPL License

But the jakkarta and parsson dependencies list the alternative licenses on separate lines and that's probably why they are getting flagged.

If my hypothesis is correct, a simple way to fix that would be for the plugin to join all the license terms together with a + sign before checking that single string against the blacklist regexps.

@carlomorelli
Copy link
Owner

but I still get the following failures:

[INFO]  - artifact jakarta.json:jakarta.json-api:2.0.1:compile
[INFO]    with license: Eclipse Public License 2.0
[INFO]    with license: GNU General Public License, version 2 with the GNU Classpath Exception
[WARNING] WARNING: found blacklisted license

Is there a way to see the exact string that the plugin is trying to match against the blacklist regexps and which of the blacklist regexps failed on it? That would greatly help in debugging the regexps.

I can't provide you custom builds for debugging your regexes.
We can add a feature request for this though.

I wrote the regexps a few years ago so I am a bit fuzzy on the details. But I think they assume that they will be matched against a string that looks like this:

License 1 + License 2 + License 3 etc...

You are expecting a behaviour of the plugin here based on lots of assumptions: a regex of which we are unsure how it works and what should catch, the existence of Artefacts out there that have multiple licenses aggregated in one string with + sign separator (i don't even recall seeing one) while the canonical way of having a multiple-license artifact is to use a list of strings (as supported by Maven constructs). etc...

If my hypothesis is correct, a simple way to fix that would be for the plugin to join all the license terms together with a + sign before checking that single string against the blacklist regexps.

The plugin correctly detects artefacts with multiple licenses as it uses the official Maven Metadata constructs. The plugin's current behaviour is that it flags build failure as soon as one of these licenses is matching one of the blacklisted, which is the behaviour that I guess you don't want.
If I understand it right, you prefer that that when a dual-licensed artifact has one blacklisted license of the two, the build still moves on as the other license is still allowed. Can you confirm that?

Can you confirm that is what you mean?
If so I will implement this by adding a conditional check when a scanned artefact has >1 licenses.
(I don't think the approach to hack the licenses into a aggregated string with + sign solves the use cases of most people)

@carlomorelli carlomorelli changed the title Dependencies that are available under different licenses Have option to pass the build if a dep has multiple licenses and at least one of them is not denylisted Jan 18, 2023
@alaindesilets
Copy link
Author

I wrote the regexps a few years ago so I am a bit fuzzy on the details. But I think they assume that they will be matched against a string that looks like this:

License 1 + License 2 + License 3 etc...

You are expecting a behaviour of the plugin here based on lots of assumptions: a regex of which we are unsure how it works and what should catch, the existence of Artefacts out there that have multiple licenses aggregated in one string with + sign separator (i don't even recall seeing one) while the canonical way of having a multiple-license artifact is to use a list of strings (as supported by Maven constructs). etc...

Here is an example that pops up when I do my build:

[INFO]  - artifact com.sun.xml.bind:jaxb-core:2.3.0.1:compile
[INFO]    with license: CDDL+GPL License

I have seen several others over the years. Note that this particular dependency does NOT get flagged, specifically because the "GPL" keyword is preceded by a + sign.

I presume that this particular convention means that jaxb-core is available under either CDDL or GPL. Another interpretation would be that the artifact contains some GPL code and some code that is CDDL.

The plugin correctly detects artefacts with multiple licenses as it uses the official Maven Metadata constructs. The plugin's current behaviour is that it flags build failure as soon as one of these licenses is matching one of the blacklisted, which is the behaviour that I guess you don't want.
If I understand it right, you prefer that that when a dual-licensed artifact has one blacklisted license of the two, the build still moves on as the other license is still allowed. Can you confirm that?

Can you confirm that is what you mean? If so I will implement this by adding a conditional check when a scanned artefact has >1 licenses. (I don't think the approach to hack the licenses into a aggregated string with + sign solves the use cases of most people)

Yes. More precisely, a dependency should be flagged if and only if all of the available licenses for that dependency match at least one of the black-list regexps.

Thx for taking this into considerations.

Alain

@carlomorelli
Copy link
Owner

Tnx.

I was thinking of giving an option command to enable this, but the more I think of it, the more this actually looks like it should be the default behaviour.

There is no point in failing the build if an artifact is dual-licensed and at least one of the two licenses is not blacklisted.

I'll try to have this fix in place, but i need to do some refactorying first, this may take some time.

@carlomorelli carlomorelli changed the title Have option to pass the build if a dep has multiple licenses and at least one of them is not denylisted Don't fail the build if a dep has multiple licenses and at least one of them is not denylisted Jan 19, 2023
@carlomorelli carlomorelli added bug Something isn't working question Further information is requested labels Jan 19, 2023
@alaindesilets
Copy link
Author

alaindesilets commented Jan 19, 2023 via email

@carlomorelli
Copy link
Owner

This is now implemented.

You can test it using release 3.0-RC3 just issues.

@alaindesilets
Copy link
Author

alaindesilets commented Jan 30, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants