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

[BUG] Internal package changes in ECJ will break Lombok. #3564

Closed
rgrunber opened this issue Dec 5, 2023 · 36 comments
Closed

[BUG] Internal package changes in ECJ will break Lombok. #3564

rgrunber opened this issue Dec 5, 2023 · 36 comments
Labels
accepted The issue/enhancement is valid, sensible, and explained in sufficient detail bug eclipse
Milestone

Comments

@rgrunber
Copy link

rgrunber commented Dec 5, 2023

Originally filed at eclipse-jdtls/eclipse.jdt.ls#2985 .

Lombok is using JDT ECJ (org.eclipse.jdt.core.compiler.batch) internals (eg.

if (expressions != null) for (Expression ex : expressions) {
StringBuffer sb = new StringBuffer();
ex.print(0, sb);
raws.add(sb.toString());
)

In eclipse-jdt/eclipse.jdt.core#1403 these internals were updated (basically the single argument to print changed from StringBuffer to StringBuilder. There's a few other references to StringBuffer in the code that should be checked also.

public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuffer output, TypeDeclaration type) {
Map<String, String> docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit);
if (docs != null) {
String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration);
String rawJavadoc = docs.get(signature);
if (rawJavadoc != null) {
for (String line : rawJavadoc.split("\r?\n")) {
ASTNode.printIndent(tab, output).append(line).append("\n");
}
}
}
return methodDeclaration.print(tab, output);
}

PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class);

.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))

@Rawi01 Rawi01 added bug eclipse accepted The issue/enhancement is valid, sensible, and explained in sufficient detail labels Dec 5, 2023
@HannesWell
Copy link

The code snippet

StringBuffer sb = new StringBuffer();
ex.print(0, sb);
raws.add(sb.toString());

can just be replaced with

raws.add(ex.toString()); 

since ASTNode.toString() does the same and does not have (and even cannot) its signature changed.
So this would be a backwards compatible change that should work with future and past versions of eclipse.

@robstryker
Copy link
Contributor

@HannesWell - so that would be the only change required? What about all references in EclipsePatcher that make replaceMethodCall calls to replace specific method calls with new impls in PatchFixesHider ?

Actually I don't think I even understand PatchFixesHider as it appears to just be calling the underlying method anyway. Maybe I'm missing something.

@gayanper
Copy link

gayanper commented Dec 5, 2023

Do you have instructions to build this project and also import as a eclipse project into latest Eclipse IDE release ?

@robstryker
Copy link
Contributor

@rspilker are there any instructions, as @gayanper has requested?

@snjeza
Copy link

snjeza commented Dec 5, 2023

@gayanper You can try Lombok 1.18.31
It includess the patch described at #3564 (comment)

@gayanper
Copy link

gayanper commented Dec 5, 2023

@rspilker are there any instructions, as @gayanper has requested?

never mind, I found the the ant target to generate eclipse project files. It was decades after I use ant to setup a project ;)

@snjeza
Copy link

snjeza commented Dec 5, 2023

@rspilker are there any instructions, as @gayanper has requested?

$ git clone git@github.com:projectlombok/lombok.git
$ ant dist

and also import as a eclipse project into latest Eclipse IDE release

File>Import>Existing Projects into Workspace

@gayanper
Copy link

gayanper commented Dec 5, 2023

@snjeza can you point to your branch ?

@HannesWell
Copy link

@HannesWell - so that would be the only change required? What about all references in EclipsePatcher that make replaceMethodCall calls to replace specific method calls with new impls in PatchFixesHider ?

I don't know anything about lombok and how it is using Eclipse JDT so I cannot say more, sorry for that.
But when I look at org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration I cannot see any printMethod method for which PatchFixesHider seems to look. Maybe it is gone for a long time already? Which is maybe why it is called via reflection?

Actually I don't think I even understand PatchFixesHider as it appears to just be calling the underlying method anyway. Maybe I'm missing something.

Could be, I have no clue. :)

The call to TypeDeclaration.printBody() could maybe also be replaced with declaration.toString() and making sure that the javadoc field is null and restored to its previous value afterwards.

@robstryker
Copy link
Contributor

PrintMethod actually lives here in Lombok in the PatchFixesHider.java file.

Here in Lombok, the EclipsePatcher.java file has the following code:

		sm.addScript(ScriptBuilder.replaceMethodCall()
				.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
				.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
				.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
				.requestExtra(StackRequest.THIS)
				.build());

What this appears to be doing is saying, any time anyone tries to call TypeDeclaration.printBody(etc) that control should instead flow through PatchFixesHider$Javadoc file and into it's printMethod function instead.

@snjeza
Copy link

snjeza commented Dec 5, 2023

can you point to your branch ?

@gayanper you can try the following

$ git clone git@github.com:projectlombok/lombok.git
$ cd lombok
  • apply the patch
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index dd646e57..e46ed79d 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1331,9 +1331,9 @@ public class EclipseHandlerUtil {
                                expressions = new Expression[] { rhs };
                        }
                        if (expressions != null) for (Expression ex : expressions) {
-                               StringBuffer sb = new StringBuffer();
-                               ex.print(0, sb);
-                               raws.add(sb.toString());
+                               //StringBuffer sb = new StringBuffer();
+                               //ex.print(0, sb);
+                               raws.add(ex.toString());
                                expressionValues.add(ex);
                                guesses.add(calculateValue(ex));
  • buld lombok
$ ant dist

@gayanper
Copy link

gayanper commented Dec 5, 2023

ant dist

gives me errors, did you run any other targets before and is there specific ant version requirement ?

@snjeza
Copy link

snjeza commented Dec 5, 2023

gives me errors, did you run any other targets before and is there specific ant version requirement ?

@gayanper Could you show me errors?

My environment:

$ ant -version
Apache Ant(TM) version 1.10.12 compiled on January 18 2023
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
	modified:   src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java

no changes added to commit (use "git add" and/or "git commit -a")

The updated patch

diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index dd646e57..e46ed79d 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1331,9 +1331,9 @@ public class EclipseHandlerUtil {
 				expressions = new Expression[] { rhs };
 			}
 			if (expressions != null) for (Expression ex : expressions) {
-				StringBuffer sb = new StringBuffer();
-				ex.print(0, sb);
-				raws.add(sb.toString());
+				//StringBuffer sb = new StringBuffer();
+				//ex.print(0, sb);
+				raws.add(ex.toString());
 				expressionValues.add(ex);
 				guesses.add(calculateValue(ex));
 			}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 52e62342..019b3199 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -989,9 +989,16 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
 		sm.addScript(ScriptBuilder.replaceMethodCall()
 				.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
 				.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
-				.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
+				.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod2", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
 				.requestExtra(StackRequest.THIS)
 				.build());
+		
+		sm.addScript(ScriptBuilder.replaceMethodCall()
+			.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuilder", "int", "java.lang.StringBuilder"))
+			.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuilder", "int", "java.lang.StringBuilder"))
+			.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod2", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuilder", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
+			.requestExtra(StackRequest.THIS)
+			.build());
 
 		sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
 				.fieldName("$javadoc")
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index a9db91f5..6d55b216 100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -428,11 +428,13 @@ final class PatchFixesHider {
 	public static final class Javadoc {
 		private static final Method GET_HTML;
 		private static final Method PRINT_METHOD;
+		private static final Method PRINT_METHOD2;
 		
 		static {
 			Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc");
 			GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class);
 			PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class);
+			PRINT_METHOD2 = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuilder.class, TypeDeclaration.class);
 		}
 		
 		public static String getHTMLContentFromSource(String original, IJavaElement member) {
@@ -442,6 +444,10 @@ final class PatchFixesHider {
 		public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
 			return (StringBuffer) Util.invokeMethod(PRINT_METHOD, methodDeclaration, tab, output, type);
 		}
+		
+		public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuilder output, TypeDeclaration type) {
+			return (StringBuffer) Util.invokeMethod(PRINT_METHOD2, methodDeclaration, tab, output, type);
+		}
 	}
 	
 	/**

fixes EclipsePatcher too.

@robstryker
Copy link
Contributor

Ok guys just to add some context here, from my code sluething.

The main driver is those first 3 lines we saw before:

if (expressions != null) for (Expression ex : expressions) {
StringBuffer sb = new StringBuffer();
ex.print(0, sb);
raws.add(sb.toString());
expressionValues.add(ex);
guesses.add(calculateValue(ex));

If we change this as @snjeza has done, it is extremely likely that the code will compile and run. However, it appears that the overrides that Lombok is attempting to add will not function.

Lombok is attempting to introspect all calls to org.eclipse.jdt.internal.compiler.ast.TypeDeclaration and it's printBody method. When introspecting this, it attempts to discover any calls to a AbstractMethodDeclaration object's print(int, stringbuffer) calls. And then replace it with a call to lombok's printMethod instead.

sm.addScript(ScriptBuilder.replaceMethodCall()
.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
.requestExtra(StackRequest.THIS)
.build());

Lombok's printMethod lives in PatchFixesHider$Javadoc and simply calls another Lombok version of it:

static {
Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc");
GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class);
PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class);
}
public static String getHTMLContentFromSource(String original, IJavaElement member) {
return (String) Util.invokeMethod(GET_HTML, original, member);
}
public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
return (StringBuffer) Util.invokeMethod(PRINT_METHOD, methodDeclaration, tab, output, type);
}

From there, it redirects to Lombok's PatchJavadoc class and it's printMethod implementation, to ultimately override the version in JDT.

public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, Integer tab, StringBuffer output, TypeDeclaration type) {
Map<String, String> docs = CompilationUnit_javadoc.get(methodDeclaration.compilationResult.compilationUnit);
if (docs != null) {
String signature = EclipseHandlerUtil.getSignature(type, methodDeclaration);
String rawJavadoc = docs.get(signature);
if (rawJavadoc != null) {
for (String line : rawJavadoc.split("\r?\n")) {
ASTNode.printIndent(tab, output).append(line).append("\n");
}
}
}
return methodDeclaration.print(tab, output);
}

Basically, PatchJavadoc has a version of printMethod that is intended to override AbstractMethodDeclaration.print(etc) implementation.

Simply put, using only the 3 line fix above will let it compile and run, but will likely not allow Lombok's override behavior to take effect, unless we add similar replacements for each step along this chain.

@robstryker
Copy link
Contributor

I believe my PR (#3565) might be a lot closer to a solution that maintains the current behavior without breaking, but I have no way to test it.

@gayanper once you have a workflow to build PRs and test them, let me know. There might be some places where we might need to add some exception handling in my PR.

@robstryker
Copy link
Contributor

@snjeza your updated patch has a few errors.

First You're missing a change in PatchJavadoc.java.

Second, your printMethod functions both return StringBuffer. The second should return StringBuilder.

Third, calls to Util.findMethod will throw a RuntimeException if the given function is not found.

I believe my PR over at #3565 is more complete at this time.

@gayanper
Copy link

gayanper commented Dec 5, 2023

@snjeza your updated patch has a few errors.

First You're missing a change in PatchJavadoc.java.

Second, your printMethod functions both return StringBuffer. The second should return StringBuilder.

Third, calls to Util.findMethod will throw a RuntimeException if the given function is not found.

I believe my PR over at #3565 is more complete at this time.

Seems like it has some compilation issues

@gayanper
Copy link

gayanper commented Dec 5, 2023

This is the sample code that cause the jdt failure

package com.example.demo;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;

@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Lombok {
  private final String name;
}

@snjeza
Copy link

snjeza commented Dec 5, 2023

I believe my PR over at #3565 is more complete at this time.
Seems like it has some compilation issues

$ ant dist
...
1. ERROR in /home/snpe/projects/lombok/src/core/lombok/core/configuration/ConfigurationFile.java (at line 196)
				matcher.appendReplacement(result, value);
				        ^^^^^^^^^^^^^^^^^
The method appendReplacement(StringBuffer, String) in the type Matcher is not applicable for the arguments (StringBuilder, String)
----------
2. ERROR in /home/snpe/projects/lombok/src/core/lombok/core/configuration/ConfigurationFile.java (at line 198)
			matcher.appendTail(result);
			        ^^^^^^^^^^
The method appendTail(StringBuffer) in the type Matcher is not applicable for the arguments (StringBuilder)
----------
3. ERROR in /home/snpe/projects/lombok/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java (at line 75)
					ASTNode.printIndent(tab, output).append(line).append("\n");
					        ^^^^^^^^^^^
The method printIndent(int, StringBuffer) in the type ASTNode is not applicable for the arguments (Integer, StringBuilder)
----------
4. ERROR in /home/snpe/projects/lombok/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java (at line 79)
		return methodDeclaration.print(tab, output);
		                         ^^^^^
The method print(int, StringBuffer) in the type AbstractMethodDeclaration is not applicable for the arguments (Integer, StringBuilder)
----------
5. ERROR in /home/snpe/projects/lombok/src/eclipseAgent/lombok/launch/PatchFixesHider.java (at line 430)
		private static final Method PRINT_METHOD_OLD;
		                            ^^^^^^^^^^^^^^^^
The blank final field PRINT_METHOD_OLD may not have been initialized
----------
6. ERROR in /home/snpe/projects/lombok/src/eclipseAgent/lombok/launch/PatchFixesHider.java (at line 431)
		private static final Method PRINT_METHOD_NEW;
		                            ^^^^^^^^^^^^^^^^
The blank final field PRINT_METHOD_NEW may not have been initialized
----------
7. ERROR in /home/snpe/projects/lombok/src/eclipseAgent/lombok/launch/PatchFixesHider.java (at line 989)
			return buffer;
			       ^^^^^^
Type mismatch: cannot convert from StringBuffer to StringBuilder
----------

BUILD FAILED
/home/snpe/projects/lombok/buildScripts/compile.ant.xml:177: Compilation not successful

@gayanper
Copy link

gayanper commented Dec 5, 2023

I couldn't get none of the above changes compiled, so I did it on my own

diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index dd646e57..206abf0c 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1332,7 +1332,7 @@ public class EclipseHandlerUtil {
 			}
 			if (expressions != null) for (Expression ex : expressions) {
 				StringBuffer sb = new StringBuffer();
-				ex.print(0, sb);
+				sb.append(ex.toString());
 				raws.add(sb.toString());
 				expressionValues.add(ex);
 				guesses.add(calculateValue(ex));
diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
index 52e62342..4f0e5215 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java
@@ -986,12 +986,6 @@ public class EclipsePatcher implements AgentLauncher.AgentLaunchable {
 				.requestExtra(StackRequest.PARAM1)
 				.build());
 		
-		sm.addScript(ScriptBuilder.replaceMethodCall()
-				.target(new MethodTarget("org.eclipse.jdt.internal.compiler.ast.TypeDeclaration", "printBody", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
-				.methodToReplace(new Hook("org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "print", "java.lang.StringBuffer", "int", "java.lang.StringBuffer"))
-				.replacementMethod(new Hook("lombok.launch.PatchFixesHider$Javadoc", "printMethod", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration", "int", "java.lang.StringBuffer", "org.eclipse.jdt.internal.compiler.ast.TypeDeclaration"))
-				.requestExtra(StackRequest.THIS)
-				.build());
 
 		sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.addField()
 				.fieldName("$javadoc")
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
index 673c30fd..52d41784 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchJavadoc.java
@@ -76,7 +76,7 @@ public class PatchJavadoc {
 				}
 			}
 		}
-		return methodDeclaration.print(tab, output);
+		return output.append(methodDeclaration.toString());
 	}
 	
 	private static class Signature {
diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
index a9db91f5..02585e6a 100755
--- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java
+++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java
@@ -427,21 +427,15 @@ final class PatchFixesHider {
 	/** Contains patch code to support Javadoc for generated methods */
 	public static final class Javadoc {
 		private static final Method GET_HTML;
-		private static final Method PRINT_METHOD;
 		
 		static {
 			Class<?> shadowed = Util.shadowLoadClass("lombok.eclipse.agent.PatchJavadoc");
 			GET_HTML = Util.findMethod(shadowed, "getHTMLContentFromSource", String.class, Object.class);
-			PRINT_METHOD = Util.findMethod(shadowed, "printMethod", AbstractMethodDeclaration.class, Integer.class, StringBuffer.class, TypeDeclaration.class);
 		}
 		
 		public static String getHTMLContentFromSource(String original, IJavaElement member) {
 			return (String) Util.invokeMethod(GET_HTML, original, member);
 		}
-		
-		public static StringBuffer printMethod(AbstractMethodDeclaration methodDeclaration, int tab, StringBuffer output, TypeDeclaration type) {
-			return (StringBuffer) Util.invokeMethod(PRINT_METHOD, methodDeclaration, tab, output, type);
-		}
 	}
 	
 	/**

Please try to compare the patches and may be @snjeza can try my example code with latest jdt build on vscode.

@robstryker
Copy link
Contributor

@gayanper the problem with this patch is that it won't be making any use at all of the overrides that lombok wants to apply in PatchJavadoc.java

In fact, I think a reflection solution will be required here.

@snjeza
Copy link

snjeza commented Dec 5, 2023

Please try to compare the patches and may be @snjeza can try my example code with latest jdt build on vscode.

It works for me

@gayanper
Copy link

gayanper commented Dec 5, 2023

Please try to compare the patches and may be @snjeza can try my example code with latest jdt build on vscode.

It works for me

@snjeza or @robstryker please feel free to take my patch and update the PR.

@robstryker
Copy link
Contributor

My PR over at #3565 now compiles.

I have to be honest, @gayanper, your patch is fine IF AND ONLY IF lombok had absolutely no reason to try to override the print method at all. If that's the case, or if the original reason for overriding the print method no longer applies, then your patch is simpler and most likely will work as expected.

However, if lombok had a legitimate reason to try to override the jdt implementation of the print method, and if that reason still applies, then my patch is most likely more suitable as we still override those functions with the lombok-custom behavior.

Unfortunately I'm not sure any of us here know the history of why lombok was trying to override this behavior. @rspilker do you think you can add some color to this for us? Or decide between the patches?

@snjeza
Copy link

snjeza commented Dec 6, 2023

My PR over at #3565 now compiles.

I have tested it using 4.31-I-builds//I20231206-041
It works fine.

@Rawi01
Copy link
Collaborator

Rawi01 commented Dec 6, 2023

I love that so many people here are actively engaged in solving the problem, it's always helpful when more people gather experiences with the codebase. I will try to add the missing test stuff. Does anyone know if this issue also affect eclipse 2023-12?

We override the print methods only for our test cases, one for generated javadoc and one to align the output between different eclipse versions. We can not simply change them without breaking older tests but I think there could be a shorter and easier solution for our printMethod.

@snjeza
Copy link

snjeza commented Dec 6, 2023

Does anyone know if this issue also affect eclipse 2023-12

No, this issue doesn't affect Eclipse 2023-12 (Eclipse 4.30).

@robstryker
Copy link
Contributor

hey @Rawi01 - just to let you know I'm pretty much done with what I can contribute further to this patch, at least without knowing how to use or test this thing ;) I've actually never used lombok and have no idea what it is :X I just saw a bug that needed fixing and tried my best, but I've reached what I think is the end of the road since I don't know how to test or trace through any scenarios, or even what those scenarios might be.

I hope you can take what I've done and run with it further.

@bobfields
Copy link

bobfields commented Mar 13, 2024

Was this fixed in the latest Eclipse update ? I updated today and lombok is broken, with the same error above. Tried reverting, got "No repository found containing: (and a bunch of links)". Now I'm broken since all my projects use lombok.

!ENTRY org.eclipse.jdt.core 4 0 2024-03-13 12:25:14.115
!MESSAGE Lombok annotation handler class lombok.eclipse.handlers.HandleAccessors failed
!STACK 0
java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt.internal.compiler.ast.Expression.print(int, java.lang.StringBuffer)'
	at lombok.eclipse.handlers.EclipseHandlerUtil.createAnnotation(EclipseHandlerUtil.java:1335)
	at lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:105)
	at lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
	at 

Versions:
Eclipse IDE for Java Developers 4.31.0.20240307-1200
Eclipse Java Development Tools 3.19.400.v20240229-0520
Eclipse Java EE Developer Tools 3.33.0.v202401080452
Eclipse Java Web Developer Tools 3.33.0.v202402161256
Eclipse Java Web Developer Tools - JavaScript Support 3.32.0.v202309190220
Eclipse JSON Editor and Tools 1.1.11.v202308160419
Eclipse Tomcat Management Feature 9.1.6
Eclipse Web Developer Tools - JavaScript Support 3.33.0.v202403030558
Eclipse XML Editors and Tools 3.33.0.v202402030243
Eclipse XSL Developer Tools 1.3.1500.v202307260701

Any advice on how to revert just one Eclipse plugin, i.e.
Eclipse Java Development Tools 3.19.300.v20231201-0110
I assume this is where the bad lombok code is located.
I'm using lombok 1.18.30 in both the Eclipse.ini javaagent and also in the project dependencies.

@rgrunber
Copy link
Author

rgrunber commented Mar 13, 2024

Was this fixed in the latest Eclipse update ? I updated today and lombok is broken, with the same error above. Tried reverting, got "No repository found containing: (and a bunch of links)". Now I'm broken since all my projects use lombok.

The fix was for Lombok. Have you tried with https://projectlombok.org/lombok-edge.jar ? It should work against the newer versions of Eclipse.

@bobfields
Copy link

OK changed eclipse.ini from:
-javaagent:D:\m2repo\org\projectlombok\lombok\1.18.30\lombok-1.18.30.jar
to
-javaagent:D:\m2repo\org\projectlombok\lombok\lombok-edge.jar
And Eclipse now builds the lombok projects successfully. Did not have to change project dependencies.
v1.18.30 was built 2023-09-20. edge was built 2024-01-12. 2 months ago.
Would be really nice if they released that version through maven. Since Eclipse is broken with the current release version.

Thanks so much for your help !

@pglamm
Copy link

pglamm commented Mar 14, 2024

Would be really nice if they released that version through maven. Since Eclipse is broken with the current release version.

Yes, indeed. I just upgraded Spring Tools Suite to newest (Eclipse v4.22.0.202403071427), which broke lombok-1.18.30. Using the edge version in eclipse.ini (SpringToolSuite4.ini) fixed it for me. According to the milestone, the next release will be 1.18.32 or 1.20.0, but no due date.

Is there any news about a due date, or could a patch be released to the Maven repo?

@rspilker
Copy link
Collaborator

This is part of the latest edge release, all feedback is welcome.

@flavius
Copy link

flavius commented Mar 20, 2024

eclipse_installation_info.txt
Problem persists with edge:

!ENTRY org.eclipse.jdt.core 4 0 2024-03-20 16:36:53.684
!MESSAGE Lombok annotation handler class lombok.eclipse.handlers.HandleEqualsAndHashCode failed
!STACK 0
java.lang.NoSuchMethodError: 'java.lang.StringBuffer org.eclipse.jdt.internal.compiler.ast.Expression.print(int, java.lang.StringBuffer)'
	at lombok.eclipse.handlers.EclipseHandlerUtil.createAnnotation(EclipseHandlerUtil.java:1335)
	at lombok.eclipse.HandlerLibrary$AnnotationHandlerContainer.handle(HandlerLibrary.java:105)
	at lombok.eclipse.HandlerLibrary.handleAnnotation(HandlerLibrary.java:237)
	at lombok.eclipse.TransformEclipseAST$AnnotationVisitor.visitAnnotationOnType(TransformEclipseAST.java:265)
	at lombok.eclipse.EclipseNode.traverse(EclipseNode.java:107)
	at lombok.eclipse.EclipseAST.traverseChildren(EclipseAST.java:231)
	at lombok.eclipse.EclipseNode.traverse(EclipseNode.java:74)
	at lombok.eclipse.EclipseAST.traverseChildren(EclipseAST.java:231)
	at lombok.eclipse.EclipseNode.traverse(EclipseNode.java:69)
	at lombok.eclipse.EclipseAST.traverse(EclipseAST.java:224)
	at lombok.eclipse.TransformEclipseAST.go(TransformEclipseAST.java:222)
	at lombok.eclipse.TransformEclipseAST.transform(TransformEclipseAST.java:183)
	at lombok.eclipse.TransformEclipseAST.transform_swapped(TransformEclipseAST.java:107)
	at jdk.internal.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at lombok.launch.PatchFixesHider$Util.invokeMethod(PatchFixesHider.java:133)
	at lombok.launch.PatchFixesHider$Transform.transform_swapped(PatchFixesHider.java:256)
	at org.eclipse.jdt.internal.compiler.parser.Parser.endParse(Parser.java:11465)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:12666)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:12896)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:12853)
	at org.eclipse.jdt.internal.compiler.parser.Parser.dietParse(Parser.java:11236)
	at org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter.convert(SourceTypeConverter.java:152)
	at org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter.buildCompilationUnit(SourceTypeConverter.java:99)
	at org.eclipse.jdt.internal.core.CompilationUnitProblemFinder.accept(CompilationUnitProblemFinder.java:123)
	at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:372)
	at org.eclipse.jdt.internal.compiler.lookup.PackageBinding.getTypeOrPackage(PackageBinding.java:276)
	at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findImport(CompilationUnitScope.java:626)
	at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.findSingleImport(CompilationUnitScope.java:698)
	at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInImports(CompilationUnitScope.java:527)
	at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInTypes(CompilationUnitScope.java:600)
	at org.eclipse.jdt.internal.compiler.Compiler.resolve(Compiler.java:1061)
	at org.eclipse.jdt.internal.compiler.Compiler.resolve(Compiler.java:1110)
	at org.eclipse.jdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:280)
	at org.eclipse.jdt.internal.core.CompilationUnitProblemFinder.process(CompilationUnitProblemFinder.java:346)
	at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:189)
	at org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:93)
	at org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:742)
	at org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:808)
	at org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1311)
	at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:132)
	at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:94)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47)
	at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:91)
	at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:158)
	at org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:94)
	at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:107)
	at org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:78)
	at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:207)

@user20161119
Copy link

I got the same error after STS upgrade to

Version: 4.22.0.RELEASE
Build Id: 202403071427
Revision: 44291b464093d161f115d8e16059e5272ed3c81d

with lomok version 1.18.32

this is the error from error log
https://gist.github.com/user20161119/eca99e9719ce39ac2e1f81f8c6af9f3e

@Rawi01
Copy link
Collaborator

Rawi01 commented Mar 22, 2024

Please double check that you use the latest lombok version in eclipse (the version in Maven/Gradle doesn't matter)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted The issue/enhancement is valid, sensible, and explained in sufficient detail bug eclipse
Projects
None yet
Development

No branches or pull requests