-
Notifications
You must be signed in to change notification settings - Fork 34
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
Signatures URLs added to any task are actually applied to all tasks #203
Comments
This looks indeed like a bug. I will fix this before releasing the java 19 update. |
I think the easiest fix is to modify the convention mapping to make a clone: forbidden-apis/src/main/resources/de/thetaphi/forbiddenapis/gradle/plugin-init.groovy Line 48 in 89dd053
Should be trivial to do with some instanceof check or a simple call to clone(). |
Hi, Actually there's a test for the Groovy behaviour and it works (see the test gradle project). It adds "jdk-system-out" in groovy syntax only to the main source set and the test one stays unmodified. In your example if you change the code to use forbiddenApisTest {
signaturesURLs += loadResource("commons-lang3-extra.txt")
} I have no idea about Kotlin, but in fact the Groovy DSL clones correctly. So it looks like affecting kotlin only. At moment I am not sure if this is a bug at all. Other tasks in Gradle behave the same. It also affects classpath. Modern plugins implemented after Kotlin now use the Property classes (but those wree used to prevent this kind of problems). Forbiddenapis is unfortuantley therefore not 100% compatible to the Kotlin DSL. I can't change to SetProperty at the moment because of Gradle 3.x minimum dependency, so I would leave this to be fixed later in forbiddenapis v4. |
A final fix would be to use XxxProperty for all settings, but this would require upgrading gradle, so needs to be delayed. I will put this on the backlog. Workaround:
I will think about it a bit more, but the change to properties requires more work - and would finally remove the (outdated) convention mapping technique. |
I finally found a solution to fix in PR #209: I studied other old plugins and the trick is the following: Instead of returing a new instance in the convention, have some collection available as template. When the convention is executed, it takes the template, adds the extensions's data to it ( I added a Gradle-like I may release a bugfix version 3.4.1 this week or maybe a 3.5. I have one othe rissue to fix. |
Consider the case where your test configuration has commons-lang3, but main does not.
So you think you're adding the signatures only to the test task:
tasks.forbiddenApisTest { signaturesURLs.add(loadResource("commons-lang3-extra.txt")) }
But then you get a build failing in
forbiddenApisMain
because it can't find commons-lang3'sStringUtils
.This is flaky behaviour, which is why we hadn't noticed it immediately: If
forbiddenApisMain
runs first, it will work fine, because the configuration forforbiddenApisTest
hasn't been evaluated yet. But ifforbiddenApisTest
runs first, it configuressignaturesURLs
, which turns out to be the same collection used byforbiddenApisMain
. Since forbidden APIs depends on the result of compilation, and main always finishes compiling before test, this would only happen in larger projects where there are so many tasks running concurrently that it's possible for the test one to run first.From quickly reading the code, it would look like each task uses its own collection, but it seems that the convention mapping then stomps all the references with a reference to the collection in the shared extension. So all tasks actually use the same collection object, and thus using
+=
/add
isn't actually safe right now.The workaround is to copy the collection first:
Odds are, the same issue exists with all other collections, including
bundledSignatures
. But withbundledSignatures
it's less noticeable because you're going to be using the same JDK on main and test.Ideally, these collections would actually be
SetProperty
, with the initial contents of the set coming from the shared extension. But of course, that changes the public API. :(The text was updated successfully, but these errors were encountered: