src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java

changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 384
8f2986ff0235
equal deleted inserted replaced
366:8c0b6bccfe47 368:0989ad8c0860
1 /* 1 /*
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2012, 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
37 * 37 *
38 * @exception SOAPException if the given class could not be found 38 * @exception SOAPException if the given class could not be found
39 * or could not be instantiated 39 * or could not be instantiated
40 */ 40 */
41 private static Object newInstance(String className, 41 private static Object newInstance(String className,
42 ClassLoader classLoader) 42 ClassLoader classLoader,
43 String defaultFactoryClass)
43 throws SOAPException 44 throws SOAPException
44 { 45 {
45 try { 46 try {
46 Class spiClass; 47 Class spiClass = safeLoadClass(className, classLoader, defaultFactoryClass);
47 if (classLoader == null) {
48 spiClass = Class.forName(className);
49 } else {
50 spiClass = classLoader.loadClass(className);
51 }
52 return spiClass.newInstance(); 48 return spiClass.newInstance();
53 } catch (ClassNotFoundException x) { 49 } catch (ClassNotFoundException x) {
54 throw new SOAPException( 50 throw new SOAPException(
55 "Provider " + className + " not found", x); 51 "Provider " + className + " not found", x);
56 } catch (Exception x) { 52 } catch (Exception x) {
71 * 67 *
72 * @param factoryId the name of the factory to find, which is 68 * @param factoryId the name of the factory to find, which is
73 * a system property 69 * a system property
74 * @exception SOAPException if there is a SOAP error 70 * @exception SOAPException if there is a SOAP error
75 */ 71 */
76 static Object find(String factId) 72 static Object find(String factoryId)
77 throws SOAPException 73 throws SOAPException
78 { 74 {
79 final ClassLoader classLoader; 75 return find(factoryId, null, false);
80 final String factoryId = factId;
81 try {
82 classLoader = Thread.currentThread().getContextClassLoader();
83 } catch (Exception x) {
84 throw new SOAPException(x.toString(), x);
85 }
86
87 // Use the system property first
88 try {
89 String systemProp =
90 System.getProperty( factoryId );
91 if( systemProp!=null) {
92 return newInstance(systemProp, classLoader);
93 }
94 } catch (SecurityException se) {
95 }
96
97 // try to read from $java.home/lib/jaxm.properties
98 try {
99 String javah=System.getProperty( "java.home" );
100 String configFile = javah + File.separator +
101 "lib" + File.separator + "jaxm.properties";
102 final File f=new File( configFile );
103 if( f.exists()) {
104 Properties props=new Properties();
105 props.load( new FileInputStream(f));
106 String factoryClassName = props.getProperty(factoryId);
107 return newInstance(factoryClassName, classLoader);
108 }
109 } catch(Exception ex ) {
110 }
111
112 String serviceId = "META-INF/services/" + factoryId;
113 // try to find services in CLASSPATH
114 try {
115 InputStream is=null;
116 if (classLoader == null) {
117 is=ClassLoader.getSystemResourceAsStream(serviceId);
118 } else {
119 is=classLoader.getResourceAsStream(serviceId);
120 }
121
122 if( is!=null ) {
123 BufferedReader rd =
124 new BufferedReader(new InputStreamReader(is, "UTF-8"));
125
126 String factoryClassName = rd.readLine();
127 rd.close();
128
129 if (factoryClassName != null &&
130 ! "".equals(factoryClassName)) {
131 return newInstance(factoryClassName, classLoader);
132 }
133 }
134 } catch( Exception ex ) {
135 }
136
137 return null;
138 } 76 }
139 77
140 /** 78 /**
141 * Finds the implementation <code>Class</code> object for the given 79 * Finds the implementation <code>Class</code> object for the given
142 * factory name, or if that fails, finds the <code>Class</code> object 80 * factory name, or if that fails, finds the <code>Class</code> object
158 * @exception SOAPException if there is a SOAP error 96 * @exception SOAPException if there is a SOAP error
159 */ 97 */
160 static Object find(String factoryId, String fallbackClassName) 98 static Object find(String factoryId, String fallbackClassName)
161 throws SOAPException 99 throws SOAPException
162 { 100 {
163 101 return find(factoryId, fallbackClassName, true);
164 Object obj = find(factoryId); 102 }
165 if (obj != null) 103
166 return obj; 104 /**
167 105 * Finds the implementation <code>Class</code> object for the given
106 * factory name, or if that fails, finds the <code>Class</code> object
107 * for the given default class name, but only if <code>tryFallback</code>
108 * is <code>true</code>. The arguments supplied must be used in order
109 * If using the first argument is successful, the second one will not
110 * be used. Note the default class name may be needed even if fallback
111 * is not to be attempted, so certain error condiitons can be handled.
112 * <P>
113 * This method is package private so that this code can be shared.
114 *
115 * @return the <code>Class</code> object of the specified message factory;
116 * may not be <code>null</code>
117 *
118 * @param factoryId the name of the factory to find, which is
119 * a system property
120 * @param defaultClassName the implementation class name, which is
121 * to be used only if nothing else
122 * is found; <code>null</code> to indicate
123 * that there is no default class name
124 * @param tryFallback whether to try the default class as a
125 * fallback
126 * @exception SOAPException if there is a SOAP error
127 */
128 static Object find(String factoryId, String defaultClassName,
129 boolean tryFallback) throws SOAPException {
168 ClassLoader classLoader; 130 ClassLoader classLoader;
169 try { 131 try {
170 classLoader = Thread.currentThread().getContextClassLoader(); 132 classLoader = Thread.currentThread().getContextClassLoader();
171 } catch (Exception x) { 133 } catch (Exception x) {
172 throw new SOAPException(x.toString(), x); 134 throw new SOAPException(x.toString(), x);
173 } 135 }
174 136
175 if (fallbackClassName == null) { 137 // Use the system property first
138 try {
139 String systemProp =
140 System.getProperty( factoryId );
141 if( systemProp!=null) {
142 return newInstance(systemProp, classLoader, defaultClassName);
143 }
144 } catch (SecurityException se) {
145 }
146
147 // try to read from $java.home/lib/jaxm.properties
148 try {
149 String javah=System.getProperty( "java.home" );
150 String configFile = javah + File.separator +
151 "lib" + File.separator + "jaxm.properties";
152 File f=new File( configFile );
153 if( f.exists()) {
154 Properties props=new Properties();
155 props.load( new FileInputStream(f));
156 String factoryClassName = props.getProperty(factoryId);
157 return newInstance(factoryClassName, classLoader, defaultClassName);
158 }
159 } catch(Exception ex ) {
160 }
161
162 String serviceId = "META-INF/services/" + factoryId;
163 // try to find services in CLASSPATH
164 try {
165 InputStream is=null;
166 if (classLoader == null) {
167 is=ClassLoader.getSystemResourceAsStream(serviceId);
168 } else {
169 is=classLoader.getResourceAsStream(serviceId);
170 }
171
172 if( is!=null ) {
173 BufferedReader rd =
174 new BufferedReader(new InputStreamReader(is, "UTF-8"));
175
176 String factoryClassName = rd.readLine();
177 rd.close();
178
179 if (factoryClassName != null &&
180 ! "".equals(factoryClassName)) {
181 return newInstance(factoryClassName, classLoader, defaultClassName);
182 }
183 }
184 } catch( Exception ex ) {
185 }
186
187 // If not found and fallback should not be tried, return a null result.
188 if (!tryFallback)
189 return null;
190
191 // We didn't find the class through the usual means so try the default
192 // (built in) factory if specified.
193 if (defaultClassName == null) {
176 throw new SOAPException( 194 throw new SOAPException(
177 "Provider for " + factoryId + " cannot be found", null); 195 "Provider for " + factoryId + " cannot be found", null);
178 } 196 }
179 197 return newInstance(defaultClassName, classLoader, defaultClassName);
180 return newInstance(fallbackClassName, classLoader); 198 }
199
200 /**
201 * Loads the class, provided that the calling thread has an access to the
202 * class being loaded. If this is the specified default factory class and it
203 * is restricted by package.access we get a SecurityException and can do a
204 * Class.forName() on it so it will be loaded by the bootstrap class loader.
205 */
206 private static Class safeLoadClass(String className,
207 ClassLoader classLoader, String defaultFactoryClass)
208 throws ClassNotFoundException {
209 try {
210 // make sure that the current thread has an access to the package of the given name.
211 SecurityManager s = System.getSecurityManager();
212 if (s != null) {
213 int i = className.lastIndexOf('.');
214 if (i != -1) {
215 s.checkPackageAccess(className.substring(0, i));
216 }
217 }
218
219 if (classLoader == null)
220 return Class.forName(className);
221 else
222 return classLoader.loadClass(className);
223 } catch (SecurityException se) {
224 // The FactoryFinder is in the bootstrap class loader, so
225 // the following should work, but we only attempt it
226 // if it the the default class.
227 if (className.equals(defaultFactoryClass))
228 return Class.forName(className);
229 throw se;
230 }
181 } 231 }
182 } 232 }

mercurial