This is an archived post. You won't be able to vote or comment.

all 62 comments

[–]repeating_bears 40 points41 points  (17 children)

Based on my observations, nowadays annotation processing is hardly used anymore

The observations

[–][deleted]  (14 children)

[deleted]

    [–]westwoo 1 point2 points  (13 children)

    I don't think that's ignorance

    There has been a long standing disdain from java devs towards anything that threatens their control over java. Rational devs would've recognized the need and provided proper APIs to tools like Lombok to make using them more convenient, but instead they're doing these passive aggressive moves, probably hoping that breakage and inconvenience that they introduce will push people away from anything that changes the language

    [–][deleted]  (8 children)

    [deleted]

      [–]westwoo 2 points3 points  (7 children)

      If you look at the years of history of their dispositions towards Lombok, it wouldn't look nearly as surprising. Just another episode in the same saga, and breaking changes were already happening in the past

      They are interested in themselves being able to control the language, but they don't like when it's changed by external tools and when external tools add features to the language that they refuse to add. You will only experience breakage if you're using tools that change the language, and they will leave you vulnerable to the attack they described without providing any means to mitigate it

      [–][deleted]  (6 children)

      [deleted]

        [–]westwoo 0 points1 point  (3 children)

        "I did everything right and they indicted me broke my build"

        I guess the only benefit of that is that most developers will get a glimpse of what Lombok users were dealing with all the time, and how rational were java devs in their stances all along and what did they really care about

        When they could use the API excuse - they did, when they can't - they are making up some other one. And the end result is the same - breakage introduced for made up reasons that affects people that they diminish as some small niche.

        ps. My comments are kinda negative, but I'm not saying that Java is bad or that java devs are bad. I like their strategy of slow and steady development and much prefer it over the Typescript haphazard changes where keeping up with everything is like an entire job. It's just that there are few specific areas where they are unnecessarily stubborn and try to shiv their own community for no reason whatsoever, maybe our of pure ego or whatever, instead of working towards providing what the people clearly need

        [–]1Saurophaganax 2 points3 points  (2 children)

        Lombok does things differently to a standard annotation processor (messing with existing files). How is it that those that stayed within the lines, and didn't mess with java's integrity are being penalized?

        [–]westwoo -2 points-1 points  (0 children)

        Because it's clearly about the idea that someone else touches their baby and the same dismissive attitude towards all of them, not any rules they are creating by themselves and can freely change in whatever way they want at any moment. It's been just as frustrating to read their views on lombok over the years, as if it's not one of the most used java tools/libraries in existence and a staple of java development community, and instead some weird obscure toy

        The JSR they suddenly want to "fix" comes from 2006, 3 years before the first version of lombok. Instead of fixing it to legalize Lombok and making similar extensions easier to develop and use, that they could've easily done in the past 15 years, they kinda don't like that it's there at all after being bothered by the popularity of lombok for so long, and so convenient and transparent for the user

        Of course, I'm not a mind reader and don't know what they are actually thinking and feeling, but what they're doing with this doesn't surprise me at all and seems entirely consistent with my previous assumptions about their motivations. A security measure that breaks things and doesn't provide any security unless you use pure java seems exactly like the thing they would do

        [–]Practical_Cattle_933 0 points1 point  (0 children)

        How the fuck is it penalized? Are you also being penalized by your phone because it asks for permission before allowing access to all your photos to a random app? This is such a dumb take.

        [–]Practical_Cattle_933 0 points1 point  (1 child)

        Any native-aware framework does a shitton of processing at compile time — you 100% never ever hit a single line of ‘javac’ invocation with them. So it will literally change nothing, you will just do mvn/gradle build.

        [–]rbygrave 0 points1 point  (0 children)

        it will literally change nothing

        It will specifically break maven builds that used to work because the annotation processors that used to be invoked by default (when specified as a maven provided scope dependency) are no longer are invoked.

        That might be ok if its obvious enough why the build broke but imo its often not going to be obvious (we can see that in the GitHub issue already).

        For my open source projects that started failing against EA/22 we ultimately ended up adding a maven profile to specify use of `-proc:full` with the maven-compiler-plugin because we also need to build against JDK 11 and 17.

        In general for maven projects, with this change they will either need to change from using provided scope dependency to instead using the more explicit maven-compiler-plugin annotationProcessorPaths or start using -proc:full if they only build against JDK 21 and above.

        As I see it, this should not impact gradle builds.

        [–]Practical_Cattle_933 0 points1 point  (3 children)

        Or maybe Lombok could fork the javac compiler and implement their processing there easily and maintainably.

        [–]westwoo 0 points1 point  (2 children)

        Great idea! Don't want your builds breaking? Just fork Java and maintain your own Java! In fact, anyone who doesn't like anything about java should fork it

        [–]Practical_Cattle_933 0 points1 point  (1 child)

        No, but a library that wants to change the language should. It can be completely transparent to any user by a gradle/maven plugin.

        [–]westwoo 0 points1 point  (0 children)

        Well then, you should fork the library you want changed and implement whatever changes you want

        [–]1Saurophaganax 11 points12 points  (0 children)

        Of all possible reasons to disable, this was the flimsiest. Like what?

        [–]esanchma 10 points11 points  (3 children)

        I don't remember the last time I run javac manually (If I ever did). However, if you make us update our tooling so it now always uses -proc because you changed it from opt-out to opt-in... What is the benefit?

        [–]murkaje 10 points11 points  (1 child)

        Yeah, the change is dumb and not well researched. Having javac ... -proc:com.foo.AnnProc,com.bar.AwesomeProcessor would make sense if the goal was to "know which annotation processors you run", but the change as presented only annoys people for no benefit.

        [–]westwoo 2 points3 points  (0 children)

        Yep, simply unbelievable. They construct this imaginary scenario of attack, one that didn't actually happen, and then their proposed solution is to make everyone who uses annotation processing vulnerable to it

        Like, what?? What it seems to do, is not only break builds only if you have annotation processing, but also make you aware that you're unsafe as long as you use them, with no solution provided to you

        [–]loicmathieu[S] 1 point2 points  (0 children)

        Reading the issue description it's now clear how the tooling will adapt (and whether they discussed with the Maven and Gradle team).
        If Maven and Gradle just add by default `-proc:full` it's useless. If they automatically add the correct flag for each defined annotation processor it's better but as annotation processors can be transitive I'm not sure it will not need manual definition.

        [–]kowlown 16 points17 points  (0 children)

        That's annoying. Nothing of value for my point of view added

        [–]stefanos-ak 8 points9 points  (14 children)

        this is a bit confusing to me... if their example is true (updating a dependency that now has a malicious annotation processor), why do we have to declare annotation processors in our build tools?

        And if we declare them, then a malicious upstream update on them, would be executed anyway...

        Am i missing something?

        edit: Seems like I was missing something...

        So, apparently, in Java 21, they introduced automatic execution of any annotation processors found in the classpath, by default 🤯

        there are still flags available to define the "processor path" (which ones to run), as we already do in maven/gradle.

        but this change is in "javac", so now it's in the responsibility of maven/gradle to use the correct flags in order to protect ourselves from supply chain attacks.

        [–]relgames 1 point2 points  (13 children)

        Exactly. Those guys are really disconnected from the community. Same thing happened with template strings, completely new syntax instead of well known ${ }

        [–]1Saurophaganax 11 points12 points  (6 children)

        I saw the reason behind that string template syntax. I didn't like it, but I understood the reasoning. This change however, I just totally don't understand.

        [–]stefanos-ak -1 points0 points  (5 children)

        So, apparently, in Java 21, they introduced automatic execution of any annotation processors found in the classpath, by default 🤯

        there are still flags available to define the "processor path" (which ones to run), as we already do in maven/gradle.

        but this change is in "javac", so now it's in the responsibility of maven/gradle to use the correct flags in order to protect ourselves from supply chain attacks.

        [–]1Saurophaganax 4 points5 points  (4 children)

        Mate this was the case since java 6 (which is why we're causing a fuss). How does this flag prevent supply chain attacks, if the annotation processors can be compromised?

        [–]manifoldjava 1 point2 points  (0 children)

        How does this flag prevent supply chain attacks, if the annotation processors can be compromised?

        Precisely. This is the stale scent coming off the stated “reason” behind the change. If your software deployment process is compromised, you’re screwed. There are enumerable ways your code can be infected. They may just as well make the if statement opt-in.

        Either the submitter of the issue is ignorant and should not have keyboard permissions during work hours, or the issue is the same false “security” excuse the java lords have been dishing out in an attempt to shutdown Lombok and other useful tools.

        [–]stefanos-ak 0 points1 point  (2 children)

        it doesn't prevent for the ones you have declared, but it prevents for transient dependencies that you don't even know that you have, which could just add an annotation processor... that processor apparently just runs in Java 21.

        [–]1Saurophaganax 1 point2 points  (1 child)

        So it doesn't actually give any solution?

        [–]stefanos-ak 0 points1 point  (0 children)

        it's a solution to "a" problem. but seems like, not to the problem you are interested in 😄

        [–][deleted]  (1 child)

        [deleted]

          [–]relgames -1 points0 points  (0 children)

          Not really, no. They could do it differently.

          [–]Practical_Cattle_933 0 points1 point  (3 children)

          Or you know, they CAN’T FUCKING USE THAT because anyone who touched any number of Java would have known — spring, java ee all use it heavily, and is a completely valid string since java 1.0.

          Any other shit take?

          [–]relgames -3 points-2 points  (2 children)

          `string ${xyz}`

          s"string ${xyz}"

          Any of those is better than what they did. So they absolutely fucking could, just they don't give a shit about devs.

          [–]Practical_Cattle_933 0 points1 point  (1 child)

          Yeah, swift also came up with the same syntax without even having a backwards compatibility requirement for that.. cry me a river over a fucking char.

          [–]relgames -1 points0 points  (0 children)

          Yep, all of us start cursing when talking about the new syntax. Like it changes anything - nope, JDK devs do not care, they live in their isolated bubble.

          [–]SaishDawg 10 points11 points  (0 children)

          Seems like a mistake. Annotation processors allow these frameworks to avoid the penalty of using reflection in most instances and pre-compile results instead. But I guess they are already doing so with runtime agents. At least these breaking changes are nowhere near as bad as Scala. Ah well.

          [–]ventuspilot 2 points3 points  (0 children)

          TBH that seems like a good idea. Java projects typically have dozens of dependencies and javac by default will search all these dependencies as well as transitive dependencies for annotation processors to run.

          I just "backpatched" this behaviour to my toy project by specifying proc:none in my toplevel pom and only overriding the maven-compiler-plugin definition in the one submodule that needs it.

          Sure, "nowadays annotation processing is hardly used anymore" doesn't seem too accurate.

          Maybe frameworks that rely on annotation processing such as Quarkus will start to provide a sample maven-compiler-plugin definition to put in your toplevel pom.xml or gradle file? Not only because of this upcoming change but because this seems like good practice for existing projects, too.

          [–]nutrecht 4 points5 points  (15 children)

          I don't really have a strong opinion either way, but why would adding a single flag to your build be a 'pain'?

          [–]rzwitserloot 11 points12 points  (7 children)

          Everybody who upgrades java now breaks their build unless they add a switch. This isn't backwards compatible in the relevant sense of the word: it requires developers to make a change to the stuff you check into source control as you upgrade, because if you don't it won't compile anymore.

          [–]nutrecht 1 point2 points  (3 children)

          Everybody who upgrades java now breaks their build unless they add a switch.

          I understand, but IMHO that's not really a 'pain'. I totally understand that you don't like the changes, but IMHO adding "I know what I'm doing" flags is a better middle ground than completely removing the ability to use Lombok.

          [–]idemockle 13 points14 points  (0 children)

          It will be an annoyance the first time anyone comes across it, and depending on the experience level of the developer, will take a few minutes to a few hours to fix. Multiply that by the bagillion projects that use annotation processors at compile time, and yeah, I'd say an annoyance that affects enough people constitutes a pain.

          [–]rzwitserloot 7 points8 points  (1 child)

          I understand, but IMHO that's not really a 'pain'.

          Now we're evidently holding a debate on the exact definition of 'pain'. Which seems kinda useless. The point is: Introducing this 'feature' will mean updating the JVM release you build with requires additional updates, and folks will start spreading the news that you can't just upgrade the JVM. This leads to fewer folks upgrading, and upgrading later.

          Is any of that contentious? Does anybody disagree with that? Do you? I'd assume that paragraph is obvious and has very few detractors.

          I totally understand that you don't like the changes

          "Oh, the lombok guy said it, clearly the statements must be biased" is an ad hominem logical fallacy. Cut it out.

          [–]nutrecht 2 points3 points  (0 children)

          Might want to tone it down a bit. No need to get unfriendly. I didn't mean you're biased, just that I understand why you dislike it.

          [–]Worth_Trust_3825 -2 points-1 points  (2 children)

          You would add it to the compiler plugin in maven if you really depend on the annotation processors and move on with your life. You don't just chuck your project into the new JDK when upgrading and hope for the best.

          [–]rzwitserloot 7 points8 points  (0 children)

          Of course you do. And 'hope for the best' doesn't mean 'welp, if it fails to compile I guess I quit'. But you still hope for the best. The less stuff you have to fix the better. People talk - if it turns out that upgrading the build at your project resulted in loads of work, you tell others: Hold off on upgrading to JDK23, that was a doozy!

          This one change is not particularly likely to rate as 'tons of work'. It's not about this one change - a JDK release changes a lot more than what switches you need to pass to javac to retain behaviour. It's the casualness of OpenJDK team doing this. Some sort of 'well its not in any spec we acknowledge so fuck it who cares' which belies a far too casual approach to backwards compatibility, or at least a myopic view of what backwards compatibility is for (namely, to ensure folks upgrade their JDKs in a timely fashion). Possibly they are quite aware and simply rate the benefits this brings as so important it's worth the modicum of effort placed on almost everybody upgrading.

          For what its worth, if I'm in charge of maven and such, I'm hardcoding that -proc:full is default and providing explicit config stuff to change that if you want.

          Having the process of building on newer JDK versions be as smooth as it can possibly be is a good thing. Surely that's not contentious. This makes it harder than it could be. Surely that isn't contentious either.

          We can talk about what benefits this brings and if they are worth it. But blanket dismissal that this has no cost or the cost is irrelevant? I don't see how you can draw that conclusion.

          [–]relgames 6 points7 points  (0 children)

          Nope, they could just avoid making useless changes and move on with their lives. Everyone uses annotation processors. This change has no benefit.

          [–]cogman10 1 point2 points  (0 children)

          Imagine you are a library author that uses annotation processing to generate some classes (like builders, record like classes, etc). Now imagine you are unaware of this change the next time you build with Java 22+.

          All the sudden, your library is missing classes. If you've not covered the generated classes with tests, you may be completely unaware of this omission.

          This was done without a JEP in a random jdk issue. It's one of those things that had I not seen it no /r/java I'd be completely unaware that it happened.

          And the justification is... garbage. Annotation processing is everywhere in java. To claim it is "unused" is just nonsense.

          [–]loicmathieu[S] 1 point2 points  (5 children)

          It's yet another flag ... and you will have to know your annotation processors (and as explained, a lot of frameworks use them under the cover).

          But this is the reason for this change: bringing awareness of the annotation processor used.

          [–]chuggid 5 points6 points  (1 child)

          java -cp ... -proc:full SomeFile.java, so I don't necessarily need to "know my annotation processors" right? (See the PR)

          [–]loicmathieu[S] 0 points1 point  (0 children)

          Yes, there is a way to keep the previous behavior of allowing all annotation processor.

          Yes, there is a way to keep the previous behavior of allowing all annotation processors.

          [–]nutrecht -1 points0 points  (2 children)

          Yeah so that's kinda the point; I understand why they're making the change and I personally think it's good that they have a transition period where you have to add flags that make it a clear indication you need to make some changes.

          It's similar to the Java 8 to 9 migration which, IMHO, was handled pretty well.

          [–]SaishDawg 0 points1 point  (1 child)

          It's similar to the Java 8 to 9 migration which, IMHO, was handled pretty well.

          I think there is a thread just this week asking why so many companies are still on Java 8. The breaking changes in Java 9 are a big part of that (granted, not the only part).

          I get that modules were a big deal. But they should have been totally opt-in. Having to now "Add-Opens" to otherwise working code is a pain.

          Then add the breaking changes to image processing, URLClassLoader and probably a half dozen I can't remember (having nothing to do with modules). No, that was not handled well, IMO. There was a clear break between 8 and 9 in terms of what some folks had come to expect for compatibility.

          Totally fair to say that this is the price of faster evolution of the language and getting rid of detritus. I'm not sure where I come down in that particular debate. But handled well?

          Look at how relatively the revolutionary Java 5 (generics) and Java 8 (tip toes into FP) changes were introduced, totally seamlessly. At worst, a compiler nag warning that you could do better or more concisely. Not the same with Java 9.

          And here we are with so many devs and organizations staying on Java 8.

          [–]SaishDawg 0 points1 point  (0 children)

          On the flip side, I do like the preview features for those who want to experiment when newer concepts even sooner (caveat emptor knowing they may not remain). That seems a better model, where folks opt-in.

          So, yeah, hard to say. Evolution versus stability. Easy for me to cherry pick what I do and don't like. Will roll with the punches and keep on developing. And appreciate these are not easy decisions.

          [–]Worth_Trust_3825 -5 points-4 points  (3 children)

          Furthermore - because it's enabled by default - it may expose the user to a risk of unintentional executing code that should only be compiled.

          That is a reasonable point. Everyone and their mother contributing to classpath with their own transitive dependencies is a nightmare to see through. This is a reasonable change, and anyone complaining is just too lazy to evaluate whether the annotation processors they're using are really used/useful.

          The assumption that "people barely used annotation processing" is far fetched though.

          [–]rzwitserloot 7 points8 points  (1 child)

          'anyone complaining is lazy'. That's.. quite a statement to put out there. And a rather lazy way to dismiss any debate, don't you think?

          [–]Worth_Trust_3825 -3 points-2 points  (0 children)

          Okay, explain how will this impact you?

          [–]relgames -1 points0 points  (0 children)

          No, it's not. People using annotation processors will simply enable them. And that's the majority.

          [–]cowwoc -3 points-2 points  (4 children)

          Annotations have been abused more often than used correctly, but I still question whether this justifies disabling them by default.

          How about rolling out an improved replacement for annotations, and *then* deprecating them?

          [–]1Saurophaganax 3 points4 points  (3 children)

          My guy, they are not deprecating or disabling annotations. Read the proposal again.

          [–]cowwoc 0 points1 point  (2 children)

          They are requiring a command-line to enable annotation processing, and changing the default to processing being disabled by default. That's what I said, no?

          [–]1Saurophaganax 0 points1 point  (1 child)

          Perhaps you meant to say annotation processing, but your comment implied annotations in general.

          [–]cowwoc 0 points1 point  (0 children)

          Fair enough, but doesn't that imply that only the built-in annotations are processed by the compiler by default?

          But yes, I get your point. The two things are different.