The following error is very sad to deal with: ```j...
# community-support
v
The following error is very sad to deal with:
Copy code
java.lang.NoClassDefFoundError: org/gradle/util/VersionNumber
Well, Gradle had
VersionNumber
class for quite some time, and it is sad Gradle 9 broke backward compatibility with plugins which still use
VersionNumber
from
org.gradle.util
I wonder what are the benefits for Gradle to drop the class. My guess is it does not require much efforts to support. It would be so much better if Gradle used something like
@Deprecated(level=Hidden)
instead of dropping the class.
1
m
I guess
level=Hidden
doesn't work for Java callers.
v
It does work
m
Interesting! TIL
Curious how that work? Like can you declare a Java class method "hidden"?
a
Not that VersionNumber is specifically a bad offender here, but I would like Gradle drop and deprecate way more and way more aggressively
1
v
What’s wrong with
VersionNumber
?
a
because it shouldn't be a part of Gralde API, some completely random utility which should never be exposed to plugin authors
m
Like can you declare a Java class method "hidden"?
For the record, it uses
synthetic
til
Back to the main question, the commit was 4 years ago though, suprised it only comes up in Gradle 9 Never mind, this commit kept the old classes as deprecated
v
@Andrey Mishchenko, it has been exposed since Gradle 1.2 (~2012). No questions why some of the projects accidentally import the class.
a
Exactly
so mistakes happen
v
That is a mistake to drop a class that has been exposed for more than 13 years
a
lack of real public API for plugin authors was a problem for long time, it's time to drop all this legacy
1
1
no, this why we need major versions
1
1
v
GitHub search shows quite some usages of the offending class: https://github.com/search?q=org.gradle.util.versionnumber&type=code
a
So my point: 1. Yes, it's unfortunate that some plugins broke (and yes we are also affected) 2. It must be reported more agressively before
Not so many, some menations are actually fixes after it was deprecated or suppressions of the deprecation
v
Why dropping the classes that do not harm? Sure sometimes it might be complicated to “support” an old API.
a
I think everything outside of public API should be dropped as soon as possible
and the fact that it was available shouldn't be an excuse to keep it
v
@Andrey Mishchenko, the fact that it was available, and the fact it was wildly used makes an excuse to avoid intentional breakage for the end-users. With the current case, Gradle breaks backward compatibility, and the team gives no reasons for the breakage.
a
Not only this class
all internal org.gradle.util
and it was deprecated 4 years ago, quite a long time, even comparing to 12 years in total of it's existence
v
So far this exact class prevents me upgrading pgjdbc/pgjdbc to Gradle 9: https://github.com/pgjdbc/pgjdbc/pull/3749
a
Send PR, hopefully plugin author will fix it
v
Sure thing. I’ve filed https://github.com/gradle/gradle/issues/34546 , and I’ll send a PR to resurrect
VersionNumber
a
Why? %)
v
karaf is not the only plugin that suffers
a
Just why not fix those few plugins
v
There a too many plugins and there are only 24 hours in a single day
a
YEs, we affected by Fladle plugin, send PR, publish own version
v
The approach of intentional breakages hurts the ecosystem
a
The fact that some plugins are not maintained shouldn't prevent Gradle evolution and API cleanup
v
The fact that Gradle drops the methods and classes makes its public image awful as in “Gradle XX broke my build”
1
a
Also this issue makes no sense, even if they return it (which will not happen), it already not available on Gradle 9.0
1
m
Sorry guys, don't mean to pollute your discussion with all my questions but the real question is how come those plugins haven't updated their usage in those X years/months while everything was deprecated?
a
So you reported that it was deprecated more than 2 years ago and got no answer for maintainer, so plugin is dead essentially
exactly
I mean, we are on the same boat, but it just shows us that one of plugins on which we rely is not supported, and Gradle related failure is not our biggest problem with it
v
Keeping the backward compatibility for VersionNumber would be an easy task for Gradle, yet they decided to break things. That is what bothers me
Sure the plugin should be updated one day or another. However, the plugin uses Groovy which I can hardly maintain and update. The maintainer for the plugin is not very active at the same time. It is not always like in “file a PR and release a version”.
a
You can just check on github usages of other org.gradle.util.* removed classes, also find many usages
it's not only about VersionCode
None of those APIs are supposed to be used. How many years are necessary to remove it? I believe the more Gradle waits, the more plugins are actually affected, not less
👆 2
v
That is why I suggest going with
Deprecated(level=Hidden)
. Have you seen the suggestion above? It would prevent new usages while it would keep backward compatibility at the same time
2
a
How would it help in your case? plugin is not updated for more than 5 years
v
Well, that would mean you need to reimplement that class in Kotlin as Java does not know that functionality.
a
plugins which have updates probably have no issues
v
@Vampire, one can add
synthetic
at the bytecode level with Java just fine
v
So you would need to re-implement all those classes in Kotlin, making sure the API stays the same, just to be able to mark them as hidden-deprecated
v
There’s no need to reimplement
v
Yes, one can, but that means they need to post-process the compiled code with some bytecode manipulation tool
The Gradle Folks are short on resources anyway and cannot keep up with everything they want to keep up with.
v
post-processing is a small price to pay considering it would make Gradle’s backward compatibility way better
v
I don't think any effort to support unmaintained plugins that will fail to work sooner or later anyway is really warranted. 🤷‍♂️
a
I think support some abandonware plugin, last time released more than 5 years agon, which doesn't even support ActionT shouldn't be a priority for Gradle team, they have way more obvious areas to improve
v
Look at Java: they do support “bytecode 1.1”. They did drop
jsr
bytecode instruction in Java 1.6, yet Java still executes existing Java 1.5 classes that still use
jsr
instruction
a
Don't you think that for you just fork plugin, merge your Kotlin refactoring would be better spent of resources than try to restore 4 years deprecated internal api
v
To be fair, it was not internal api
a
Look at Gradle, it requires Java 17 to run
v
It was api that should have been internal but was in the public api
👍 1
That's why it was deprecated for 4 years and finally removed
a
yeah, it was not, it was an issue of early Gradle versions, I totally understand it
I just for fixing it, not supporting previous mistakes
v
I just for fixing it, not supporting previous mistakes
Java handled
jsr
removal much better than Gradle did with its
org.gradle.util
v
> I just for fixing it, not supporting previous mistakes Sure me too. But actually discussing about it here will probably not help much. I don't think we will be able to change Vladimir's opinion and even if he would change our minds, that wouldn't help with convincing the Gradle folks. 🙂
🙏 1
v
Resurrecting
VersionNumber
and
ConfigureUtil
does help: https://github.com/pgjdbc/pgjdbc/pull/3752 I copied the classes under
build-logic
, and it works. Unfortunately it breaks with Groovy doing some Groovy things:
Copy code
groovy.lang.MissingMethodException: No signature of method: groovy.xml.MarkupBuilder.setOmitNullAttributes() is applicable for argument types: (Boolean) values: [true]
        Possible solutions: setOmitNullAttributes(boolean), isOmitNullAttributes(), setOmitEmptyAttributes(boolean)
            at com.github.lburgazzoli.gradle.plugin.karaf.features.KarafFeaturesBuilder.<init>(KarafFeaturesBuilder.groovy:35)
            at com.github.lburgazzoli.gradle.plugin.karaf.features.KarafFeaturesBuilder.<init>(KarafFeaturesBuilder.groovy:27)
However, the takeaway is that keeping
VersionNumber
and
ConfigureUtil
afloat is not that hard.
🧠 1
a
Maybe because of new Groovy?
v
may be. Looks like Groovy can’t somehow convert
Boolean
to
boolean
which sounds strange.
a
Look, without all the arguing, don't you think it would be better for your use case to fork the plugin and maintain? Genuine question, especially if you are an active user and the plugin is not maintained anymore by the original maintainer
v
Forking is literally investing time in reworking the release workflows. I remember I’ve spent some time refactoring the plugin, yet it was not complete (otherwise I would switch the status from draft to ready for review). Just to compare: it is a complete no-brainer for me to band-aid
VersionNumber
right under my
build-logic
, and it does heal
VersionNumber
issue. At the same time, forking the plugin, reworking the code, and pushing it would likely take much more time. For instance, Gradle forbids
com.github...
namespace for the plugins yet Maven Central happily accepts it. Those small breakages accumulate over time, and they do exhaust maintainers.
At the same time, forks dilute the community which is bad in my opinion. So I would rather try working with the upstream before making forks.
v
For instance, Gradle forbids
com.github...
namespace for the plugins yet Maven Central happily accepts it.
Those small breakages accumulate over time, and they do exhaust maintainers.
MC only accepts it for old namespaces. MC started with only accepting io.github for new namespaces.
At the same time, forks dilute the community which is bad in my opinion.
As long as the main project is maintained, yes. But if it is dead and you do not have a chance to overtake it, forking is the way to keep it alive which serves the community better than just ignoring that the main project is abandoned. 🤷‍♂️
As long as there is on maintained fork it is fine. Only if multiple forks are created instead of joining forces it is bad.
v
You are right. Recently I faced it with one of my projects (
com.github.autostyle
which happends to be a fork of
spotless
🤣 ). I wan’t able to publish newer versions to Gradle Portal due to Gradle’s limitation. Luckily I can still publish to Central and postpone the group migration.
v
But yeah, of course forking and maintaining that fork needs time and dedication, that's out of question
Yeah, well, I guess for that (you already own the namespace on MC and want to use it for the plugin too) I guess you need to contact the portal-guys and ask for enabling it. 🤷‍♂️ Worth a try maybe.
v
ask for enabling it
The plugin was already published under
com.github.autostyle
before to Gradle Plugin Portal, and I expect they added a client-side validation.
v
I would not expect this to be client-side. Plugins previously published under that ID hopefully can post updates. I'd guess it is just an initial-validation check hopefully.
a
Does it really a problem to migrate group? I mean, it rarely requires more effort than update version I do not say that take care of plugin has no effort, only if I rely on open source project for my own work, I would like to make sure that it's maintained, and if not, fork it under my control
v
>Does it really a problem to migrate group? I mean, it rarely requires more effort than update version Renovate updates versions for me, so it is zero effort. Moving the group would require manual edits across all the usages or it would require a relocation artifact which is not easy to add since it is used once in a blue moon only.
v
I would not expect this to be client-side.
Plugins previously published under that ID hopefully can post updates.
I'd guess it is just an initial-validation check hopefully.
Yep, confirmed. https://plugins.gradle.org/plugin/com.github.sakata1222.jacoco-markdown was released 2 days ago and uses latest plugin version for publishing: https://github.com/sakata1222/jacoco-markdown-gradle-plugin/blob/main/plugin/build.gradle#L10 since 2 years ago.
v
l
Hey @Vladimir Sitnikov, For any publication issue of existing plugins, reach out to
plugin-portal-support at <http://gradle.com|gradle.com>
👍 1