You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by jl...@apache.org on 2019/08/04 06:15:03 UTC

[netbeans] branch master updated: Fixing injection of com.sun.tools.javac.code.Scope and adding injection of javax.lang.model.element.ModuleElement, when the available javac is not new enough.

This is an automated email from the ASF dual-hosted git repository.

jlahoda pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 7282c53  Fixing injection of com.sun.tools.javac.code.Scope and adding injection of javax.lang.model.element.ModuleElement, when the available javac is not new enough.
7282c53 is described below

commit 7282c53c8469253bd3e27036e9c729e015a1b450
Author: Jan Lahoda <jl...@netbeans.org>
AuthorDate: Sun Aug 4 08:14:55 2019 +0200

    Fixing injection of com.sun.tools.javac.code.Scope and adding injection of javax.lang.model.element.ModuleElement, when the available javac is not new enough.
---
 .../modules/java/source/NoJavacHelper.java         | 70 ++++++++++++----------
 1 file changed, 40 insertions(+), 30 deletions(-)

diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/NoJavacHelper.java b/java/java.source.base/src/org/netbeans/modules/java/source/NoJavacHelper.java
index a9e5a4e..ecadb7d 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/NoJavacHelper.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/NoJavacHelper.java
@@ -18,20 +18,15 @@
  */
 package org.netbeans.modules.java.source;
 
-import com.sun.source.tree.BreakTree;
-import com.sun.source.tree.ExpressionTree;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.ProtectionDomain;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Opcodes;
 import org.openide.modules.OnStart;
-import sun.misc.Unsafe;
 
 /**
  *
@@ -39,14 +34,21 @@ import sun.misc.Unsafe;
  */
 public class NoJavacHelper {
 
+    private static final AtomicReference<Boolean> hasWorkingJavac = new AtomicReference<>();
     public static boolean hasWorkingJavac() {
+        Boolean res = hasWorkingJavac.get();
+        if (res != null) {
+            return res;
+        }
         try {
             Class.forName("javax.lang.model.element.ModuleElement");
-            return true;
+            res = true;
         } catch (ClassNotFoundException ex) {
             //OK
-            return false;
+            res = false;
         }
+        hasWorkingJavac.compareAndSet(null, res);
+        return hasWorkingJavac.get();
     }
 
     public static boolean hasNbJavac() {
@@ -65,41 +67,49 @@ public class NoJavacHelper {
         @Override
         public void run() {
             if (!hasWorkingJavac()) {
-                ClassWriter w = new ClassWriter(0);
-                w.visit(Opcodes.V1_8, Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC, "com/sun/tools/javac/code/Scope$WriteableScope", null, "com/sun/tools/javac/code/Scope", null);
-                byte[] classData = w.toByteArray();
-
                 String JavaVersion = System.getProperty("java.specification.version"); //NOI18N
                 boolean isJdkVer8OrBelow = true;
                 if (!JavaVersion.startsWith("1.")) {   //NOI18N
                     isJdkVer8OrBelow = false;
                 }
                 if (isJdkVer8OrBelow) {
-                    try {
-                        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); //NOI18N
-                        theUnsafe.setAccessible(true);
-                        Unsafe unsafe = (Unsafe) theUnsafe.get(null);
-
-                        Class scopeClass = Class.forName("com.sun.tools.javac.code.Scope");  //NOI18N
+                    {
+                        ClassWriter w = new ClassWriter(0);
+                        w.visit(Opcodes.V1_8, Opcodes.ACC_ABSTRACT | Opcodes.ACC_PUBLIC, "com/sun/tools/javac/code/Scope$WriteableScope", null, "com/sun/tools/javac/code/Scope", null);
+                        byte[] classData = w.toByteArray();
 
-                        Method defineClass = Unsafe.class.getDeclaredMethod("defineClass", String.class, Byte[].class, Integer.class, Integer.class, ClassLoader.class, ProtectionDomain.class);  //NOI18N
-                        defineClass.invoke(unsafe, "com.sun.tools.javac.code.Scope$WriteableScope", classData, 0, classData.length, scopeClass.getClassLoader(), scopeClass.getProtectionDomain());  //NOI18N 
-                    } catch (Throwable t) {
-                        //ignore...
-                        Logger.getLogger(NoJavacHelper.class.getName()).log(Level.FINE, null, t);
+                        defineClass("com.sun.tools.javac.code.Scope$WriteableScope",
+                                    "com.sun.tools.javac.code.Scope",
+                                    classData);
                     }
-                } else {
-                    try {
-                        Method defineClass = MethodHandles.Lookup.class.getDeclaredMethod("defineClass", Byte[].class); //NOI18N
-                        defineClass.invoke(MethodHandles.lookup(), classData);
-                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
-                        Logger.getLogger(NoJavacHelper.class.getName()).log(Level.FINE, null, ex);
+                    {
+                        ClassWriter w = new ClassWriter(0);
+                        w.visit(Opcodes.V1_8, Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE | Opcodes.ACC_PUBLIC, "javax/lang/model/element/ModuleElement", null, "java/lang/Object", new String[] {"javax/lang/model/element/Element"});
+                        byte[] classData = w.toByteArray();
 
+                        defineClass("javax.lang.model.element.ModuleElement",
+                                    "com.sun.tools.javac.code.Scope",
+                                    classData);
                     }
                 }
-
             }
         }
 
+        private void defineClass(String fqn, String injectToClass, byte[] classData) {
+            try {
+                Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
+                Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe"); //NOI18N
+                theUnsafe.setAccessible(true);
+                Object unsafe = theUnsafe.get(null);
+
+                Class targetClass = Class.forName(injectToClass);  //NOI18N
+
+                Method defineClass = unsafeClass.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class);  //NOI18N
+                defineClass.invoke(unsafe, fqn, classData, 0, classData.length, targetClass.getClassLoader(), targetClass.getProtectionDomain());  //NOI18N 
+            } catch (Throwable t) {
+                //ignore...
+                Logger.getLogger(NoJavacHelper.class.getName()).log(Level.WARNING, null, t);
+            }
+        }
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists