jaxws/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/model/Injector.java
changeset 43852 93a527059d8a
parent 25871 b80b84e87032
equal deleted inserted replaced
43752:3c68ef249093 43852:93a527059d8a
     1 /*
     1 /*
     2  * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package com.sun.xml.internal.ws.model;
    26 package com.sun.xml.internal.ws.model;
    27 
    27 
       
    28 import java.lang.reflect.Field;
    28 import javax.xml.ws.WebServiceException;
    29 import javax.xml.ws.WebServiceException;
    29 import java.lang.reflect.InvocationTargetException;
    30 import java.lang.reflect.InvocationTargetException;
    30 import java.lang.reflect.Method;
    31 import java.lang.reflect.Method;
    31 import java.net.URL;
    32 import java.net.URL;
    32 import java.security.AccessController;
    33 import java.security.AccessController;
    33 import java.security.PrivilegedAction;
    34 import java.security.PrivilegedAction;
       
    35 import java.security.PrivilegedActionException;
       
    36 import java.security.PrivilegedExceptionAction;
       
    37 import java.security.ProtectionDomain;
    34 import java.util.logging.Level;
    38 import java.util.logging.Level;
    35 import java.util.logging.Logger;
    39 import java.util.logging.Logger;
    36 
    40 
    37 /**
    41 /**
    38  * A {@link ClassLoader} used to "inject" wrapper and exception bean classes
    42  * A {@link ClassLoader} used to "inject" wrapper and exception bean classes
    42  */
    46  */
    43 final class Injector {
    47 final class Injector {
    44 
    48 
    45     private static final Logger LOGGER = Logger.getLogger(Injector.class.getName());
    49     private static final Logger LOGGER = Logger.getLogger(Injector.class.getName());
    46 
    50 
    47     private static final Method defineClass;
    51     private static Method defineClass;
    48     private static final Method resolveClass;
    52     private static Method resolveClass;
    49     private static final Method getPackage;
    53     private static Method getPackage;
    50     private static final Method definePackage;
    54     private static Method definePackage;
       
    55     private static Object U;
    51 
    56 
    52     static {
    57     static {
    53         Method[] m = AccessController.doPrivileged(
    58         try {
    54                 new PrivilegedAction<Method[]>() {
    59             Method[] m = AccessController.doPrivileged(
       
    60                     new PrivilegedAction<Method[]>() {
       
    61                 @Override
       
    62                 public Method[] run() {
       
    63                     return new Method[]{
       
    64                         getMethod(ClassLoader.class, "defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE),
       
    65                         getMethod(ClassLoader.class, "resolveClass", Class.class),
       
    66                         getMethod(ClassLoader.class, "getPackage", String.class),
       
    67                         getMethod(ClassLoader.class, "definePackage",
       
    68                             String.class, String.class, String.class, String.class,
       
    69                             String.class, String.class, String.class, URL.class)
       
    70                     };
       
    71                 }
       
    72             }
       
    73             );
       
    74             defineClass = m[0];
       
    75             resolveClass = m[1];
       
    76             getPackage = m[2];
       
    77             definePackage = m[3];
       
    78 
       
    79         } catch (Throwable t) {
       
    80             try {
       
    81                 U = AccessController.doPrivileged(new PrivilegedExceptionAction() {
    55                     @Override
    82                     @Override
    56                     public Method[] run() {
    83                     public Object run() throws Exception {
    57                         return new Method[]{
    84                         Class u = Class.forName("sun.misc.Unsafe");
    58                                 getMethod(ClassLoader.class, "defineClass", String.class, byte[].class, Integer.TYPE, Integer.TYPE),
    85                         Field theUnsafe = u.getDeclaredField("theUnsafe");
    59                                 getMethod(ClassLoader.class, "resolveClass", Class.class),
    86                         theUnsafe.setAccessible(true);
    60                                 getMethod(ClassLoader.class, "getPackage", String.class),
    87                         return theUnsafe.get(null);
    61                                 getMethod(ClassLoader.class, "definePackage",
       
    62                                         String.class, String.class, String.class, String.class,
       
    63                                         String.class, String.class, String.class, URL.class)
       
    64                         };
       
    65                     }
    88                     }
    66                 }
    89                 });
    67         );
    90                 defineClass = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
    68         defineClass = m[0];
    91                     @Override
    69         resolveClass = m[1];
    92                     public Method run() throws Exception {
    70         getPackage = m[2];
    93                         try {
    71         definePackage = m[3];
    94                             return U.getClass().getMethod("defineClass",
       
    95                                     new Class[]{String.class,
       
    96                                         byte[].class,
       
    97                                         Integer.TYPE,
       
    98                                         Integer.TYPE,
       
    99                                         ClassLoader.class,
       
   100                                         ProtectionDomain.class});
       
   101                         } catch (NoSuchMethodException | SecurityException ex) {
       
   102                             throw ex;
       
   103                         }
       
   104                     }
       
   105                 });
       
   106             } catch (SecurityException | PrivilegedActionException ex) {
       
   107                 Logger.getLogger(Injector.class.getName()).log(Level.SEVERE, null, ex);
       
   108                 WebServiceException we = new WebServiceException(ex);
       
   109                 we.addSuppressed(t);
       
   110                 throw we;
       
   111             }
       
   112         }
    72     }
   113     }
    73 
   114 
    74     private static Method getMethod(final Class<?> c, final String methodname, final Class<?>... params) {
   115     private static Method getMethod(final Class<?> c, final String methodname, final Class<?>... params) {
    75         try {
   116         try {
    76             Method m = c.getDeclaredMethod(methodname, params);
   117             Method m = c.getDeclaredMethod(methodname, params);
    89             return cl.loadClass(className);
   130             return cl.loadClass(className);
    90         } catch (ClassNotFoundException e) {
   131         } catch (ClassNotFoundException e) {
    91             // nothing to do
   132             // nothing to do
    92         }
   133         }
    93         try {
   134         try {
       
   135             if (definePackage == null) {
       
   136                 return (Class) defineClass.invoke(U, className.replace('/', '.'), image, 0, image.length, cl, Injector.class.getProtectionDomain());
       
   137             }
    94             int packIndex = className.lastIndexOf('.');
   138             int packIndex = className.lastIndexOf('.');
    95             if (packIndex != -1) {
   139             if (packIndex != -1) {
    96                 String pkgname = className.substring(0, packIndex);
   140                 String pkgname = className.substring(0, packIndex);
    97                 // Check if package already loaded.
   141                 // Check if package already loaded.
    98                 Package pkg = (Package)getPackage.invoke(cl, pkgname);
   142                 Package pkg = (Package) getPackage.invoke(cl, pkgname);
    99                 if (pkg == null) {
   143                 if (pkg == null) {
   100                     definePackage.invoke(cl, pkgname, null, null, null, null, null, null, null);
   144                     definePackage.invoke(cl, pkgname, null, null, null, null, null, null, null);
   101                 }
   145                 }
   102             }
   146             }
   103 
   147 
   104             Class c = (Class)defineClass.invoke(cl,className.replace('/','.'),image,0,image.length);
   148             Class c = (Class) defineClass.invoke(cl, className.replace('/', '.'), image, 0, image.length);
   105             resolveClass.invoke(cl, c);
   149             resolveClass.invoke(cl, c);
   106             return c;
   150             return c;
   107         } catch (IllegalAccessException e) {
   151         } catch (IllegalAccessException | InvocationTargetException e) {
   108             LOGGER.log(Level.FINE,"Unable to inject "+className,e);
   152             if (LOGGER.isLoggable(Level.FINE)) {
   109             throw new WebServiceException(e);
   153                 LOGGER.log(Level.FINE, "Unable to inject " + className, e);
   110         } catch (InvocationTargetException e) {
   154             }
   111             LOGGER.log(Level.FINE,"Unable to inject "+className,e);
       
   112             throw new WebServiceException(e);
   155             throw new WebServiceException(e);
   113         }
   156         }
   114     }
   157     }
   115 
   158 
   116 }
   159 }