< prev index next >

jaxws/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/reflect/opt/Injector.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -38,10 +38,15 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import com.sun.xml.internal.bind.Util;
 import com.sun.xml.internal.bind.v2.runtime.reflect.Accessor;
+import java.lang.reflect.Field;
+import java.security.CodeSource;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
 
 /**
  * A {@link ClassLoader} used to "inject" optimized accessor classes
  * into the VM.
  *

@@ -129,25 +134,27 @@
         return injector;
     }
     /**
      * Injected classes keyed by their names.
      */
-    private final Map<String, Class> classes = new HashMap<String, Class>();
+    private final Map<String, Class> classes = new HashMap<>();
     private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
     private final Lock r = rwl.readLock();
     private final Lock w = rwl.writeLock();
     private final ClassLoader parent;
     /**
      * True if this injector is capable of injecting accessors.
      * False otherwise, which happens if this classloader can't see {@link Accessor}.
      */
     private final boolean loadable;
-    private static final Method defineClass;
-    private static final Method resolveClass;
-    private static final Method findLoadedClass;
+    private static Method defineClass;
+    private static Method resolveClass;
+    private static Method findLoadedClass;
+    private static Object U;
 
     static {
+        try {
         Method[] m = AccessController.doPrivileged(
                 new PrivilegedAction<Method[]>() {
                     @Override
                     public Method[] run() {
                         return new Method[]{

@@ -159,10 +166,41 @@
                 }
         );
         defineClass = m[0];
         resolveClass = m[1];
         findLoadedClass = m[2];
+        } catch (Throwable t) {
+            try {
+                U = AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                    @Override
+                    public Object run() throws Exception {
+                        Class u = Class.forName("sun.misc.Unsafe");
+                        Field theUnsafe = u.getDeclaredField("theUnsafe");
+                        theUnsafe.setAccessible(true);
+                        return theUnsafe.get(null);
+                    }
+                });
+                defineClass = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
+                    @Override
+                    public Method run() throws Exception {
+                        try {
+                            return U.getClass().getMethod("defineClass",
+                                    new Class[]{String.class,
+                                        byte[].class,
+                                        Integer.TYPE,
+                                        Integer.TYPE,
+                                        ClassLoader.class,
+                                        ProtectionDomain.class});
+                        } catch (NoSuchMethodException | SecurityException ex) {
+                            throw ex;
+                        }
+                    }
+                });
+            } catch (SecurityException | PrivilegedActionException ex) {
+                Logger.getLogger(Injector.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
     }
 
     private static Method getMethod(final Class<?> c, final String methodname, final Class<?>... params) {
         try {
             Method m = c.getDeclaredMethod(methodname, params);

@@ -208,17 +246,15 @@
             // deadlocks
             r.unlock();
             rlocked = false;
 
             //find loaded class from classloader
-            if (c == null) {
+            if (c == null && findLoadedClass != null) {
 
                 try {
                     c = (Class) findLoadedClass.invoke(parent, className.replace('/', '.'));
-                } catch (IllegalArgumentException e) {
-                    logger.log(Level.FINE, "Unable to find " + className, e);
-                } catch (IllegalAccessException e) {
+                } catch (IllegalArgumentException | IllegalAccessException e) {
                     logger.log(Level.FINE, "Unable to find " + className, e);
                 } catch (InvocationTargetException e) {
                     Throwable t = e.getTargetException();
                     logger.log(Level.FINE, "Unable to find " + className, t);
                 }

@@ -251,12 +287,16 @@
 
                 if (c == null) {
 
                     // we need to inject a class into the
                     try {
+                        if (resolveClass != null) {
                         c = (Class) defineClass.invoke(parent, className.replace('/', '.'), image, 0, image.length);
                         resolveClass.invoke(parent, c);
+                        } else {
+                            c = (Class) defineClass.invoke(U, className.replace('/', '.'), image, 0, image.length, parent, Injector.class.getProtectionDomain());
+                        }
                     } catch (IllegalAccessException e) {
                         logger.log(Level.FINE, "Unable to inject " + className, e);
                         return null;
                     } catch (InvocationTargetException e) {
                         Throwable t = e.getTargetException();
< prev index next >