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 } |