diff --git a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java index df64724f10..52e6234255 100644 --- a/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java +++ b/src/eclipseAgent/lombok/eclipse/agent/EclipsePatcher.java @@ -109,6 +109,7 @@ public String mapResourceName(int classFileFormatVersion, String resourceName) { patchRenameField(sm); patchInline(sm); patchNullCheck(sm); + patchCrossModuleClassLoading(sm); patchForTests(sm); @@ -1032,6 +1033,13 @@ private static void patchASTNodeSearchUtil(ScriptManager sm) { .build()); } + private static void patchCrossModuleClassLoading(ScriptManager sm) { + sm.addScriptIfWitness(OSGI_TYPES, ScriptBuilder.wrapReturnValue() + .target(new MethodTarget("org.eclipse.jdt.internal.compiler.parser.Parser", "")) + .wrapMethod(new Hook("lombok.launch.PatchFixesHider$ModuleClassLoading", "parserClinit", "void")) + .build()); + } + private static void patchForTests(ScriptManager sm) { sm.addScriptIfWitness(new String[] {"lombok/eclipse/EclipseRunner"}, ScriptBuilder.wrapReturnValue() .target(new MethodTarget("org.osgi.framework.FrameworkUtil", "getBundle", "org.osgi.framework.Bundle", "java.lang.Class")) diff --git a/src/eclipseAgent/lombok/launch/PatchFixesHider.java b/src/eclipseAgent/lombok/launch/PatchFixesHider.java index dcbcff235b..a9db91f54b 100755 --- a/src/eclipseAgent/lombok/launch/PatchFixesHider.java +++ b/src/eclipseAgent/lombok/launch/PatchFixesHider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2021 The Project Lombok Authors. + * Copyright (C) 2010-2023 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -60,6 +60,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.parser.Parser; import org.eclipse.jdt.internal.core.SourceField; import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent; import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent; @@ -163,6 +164,38 @@ private static boolean sameTypes(Class[] types, String[] typeNames) { } return true; } + + private static void prependToClassLoader(ClassLoader currentClassLoader, ClassLoader prepend) { + try { + Method prependParentMethod = Permit.getMethod(currentClassLoader.getClass(), "prependParent", ClassLoader.class); + Permit.invoke(prependParentMethod, currentClassLoader, prepend); + } catch (Throwable t) { + // Ignore + } + } + + private static ClassLoader findJdtCoreClassLoader(ClassLoader classLoader) { + try { + Method getBundleMethod = Permit.getMethod(classLoader.getClass(), "getBundle"); + Object bundle = Permit.invoke(getBundleMethod, classLoader); + + Method getBundleContextMethod = Permit.getMethod(bundle.getClass(), "getBundleContext"); + Object bundleContext = Permit.invoke(getBundleContextMethod, bundle); + + Method getBundlesMethod = Permit.getMethod(bundleContext.getClass(), "getBundles"); + Object[] bundles = (Object[]) Permit.invoke(getBundlesMethod, bundleContext); + + for (Object searchBundle : bundles) { + if (searchBundle.toString().startsWith("org.eclipse.jdt.core_")) { + Method getModuleClassLoaderMethod = Permit.getMethod(searchBundle.getClass(), "getModuleClassLoader", boolean.class); + return (ClassLoader) Permit.invoke(getModuleClassLoaderMethod, searchBundle, false); + } + } + } catch (Throwable t) { + // Ignore + } + return null; + } } /** Contains patch fixes that are dependent on lombok internals. */ @@ -201,6 +234,14 @@ public static BufferedOutputStream runPostCompiler(BufferedOutputStream out, Str } } + public static final class ModuleClassLoading { + public static void parserClinit() { + ClassLoader jdtCoreClassLoader = Util.findJdtCoreClassLoader(Parser.class.getClassLoader()); + ClassLoader currentClassLoader = ModuleClassLoading.class.getClassLoader(); + Util.prependToClassLoader(currentClassLoader, jdtCoreClassLoader); + } + } + public static final class Transform { private static Method TRANSFORM; private static Method TRANSFORM_SWAPPED; @@ -208,51 +249,14 @@ public static final class Transform { private static synchronized void init(ClassLoader prepend) { if (TRANSFORM != null) return; - prependClassLoader(prepend); - if (!prepend.toString().contains("org.eclipse.jdt.core:")) { - ClassLoader jdtCoreClassLoader = findJdtCoreClassLoader(prepend); - prependClassLoader(jdtCoreClassLoader); - } + Main.prependClassLoader(prepend); + ClassLoader currentClassLoader = Transform.class.getClassLoader(); + Util.prependToClassLoader(currentClassLoader, prepend); Class shadowed = Util.shadowLoadClass("lombok.eclipse.TransformEclipseAST"); TRANSFORM = Util.findMethodAnyArgs(shadowed, "transform"); TRANSFORM_SWAPPED = Util.findMethodAnyArgs(shadowed, "transform_swapped"); } - private static void prependClassLoader(ClassLoader classLoader) { - Main.prependClassLoader(classLoader); - try { - ClassLoader currentClassLoader = Transform.class.getClassLoader(); - - Method prependParentMethod = Permit.getMethod(currentClassLoader.getClass(), "prependParent", ClassLoader.class); - Permit.invoke(prependParentMethod, currentClassLoader, classLoader); - } catch (Throwable t) { - // Ignore - } - } - - private static ClassLoader findJdtCoreClassLoader(ClassLoader classLoader) { - try { - Method getBundleMethod = Permit.getMethod(classLoader.getClass(), "getBundle"); - Object bundle = Permit.invoke(getBundleMethod, classLoader); - - Method getBundleContextMethod = Permit.getMethod(bundle.getClass(), "getBundleContext"); - Object bundleContext = Permit.invoke(getBundleContextMethod, bundle); - - Method getBundlesMethod = Permit.getMethod(bundleContext.getClass(), "getBundles"); - Object[] bundles = (Object[]) Permit.invoke(getBundlesMethod, bundleContext); - - for (Object searchBundle : bundles) { - if (searchBundle.toString().startsWith("org.eclipse.jdt.core_")) { - Method getModuleClassLoaderMethod = Permit.getMethod(searchBundle.getClass(), "getModuleClassLoader", boolean.class); - return (ClassLoader) Permit.invoke(getModuleClassLoaderMethod, searchBundle, false); - } - } - } catch (Throwable t) { - // Ignore - } - return null; - } - public static void transform(Object parser, Object ast) throws IOException { init(parser.getClass().getClassLoader()); Util.invokeMethod(TRANSFORM, parser, ast); diff --git a/src/launch/lombok/launch/ShadowClassLoader.java b/src/launch/lombok/launch/ShadowClassLoader.java index b418a7f843..5b8e3211da 100644 --- a/src/launch/lombok/launch/ShadowClassLoader.java +++ b/src/launch/lombok/launch/ShadowClassLoader.java @@ -112,6 +112,7 @@ class ShadowClassLoader extends ClassLoader { public void prependParent(ClassLoader loader) { if (loader == null) return; if (loader == getParent()) return; + if (loader == this) return; prependedParentLoaders.add(loader); }