Tue, 06 Mar 2012 16:09:35 -0800
7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom
1 /*
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package javax.xml.ws.spi;
28 import java.io.InputStream;
29 import java.io.File;
30 import java.io.FileInputStream;
32 import java.util.Properties;
33 import java.io.BufferedReader;
34 import java.io.InputStreamReader;
35 import javax.xml.ws.WebServiceException;
37 class FactoryFinder {
39 /**
40 * Creates an instance of the specified class using the specified
41 * <code>ClassLoader</code> object.
42 *
43 * @exception WebServiceException if the given class could not be found
44 * or could not be instantiated
45 */
46 private static Object newInstance(String className,
47 ClassLoader classLoader)
48 {
49 try {
50 Class spiClass = safeLoadClass(className, classLoader);
51 return spiClass.newInstance();
52 } catch (ClassNotFoundException x) {
53 throw new WebServiceException(
54 "Provider " + className + " not found", x);
55 } catch (Exception x) {
56 throw new WebServiceException(
57 "Provider " + className + " could not be instantiated: " + x,
58 x);
59 }
60 }
62 /**
63 * Finds the implementation <code>Class</code> object for the given
64 * factory name, or if that fails, finds the <code>Class</code> object
65 * for the given fallback class name. The arguments supplied MUST be
66 * used in order. If using the first argument is successful, the second
67 * one will not be used.
68 * <P>
69 * This method is package private so that this code can be shared.
70 *
71 * @return the <code>Class</code> object of the specified message factory;
72 * may not be <code>null</code>
73 *
74 * @param factoryId the name of the factory to find, which is
75 * a system property
76 * @param fallbackClassName the implementation class name, which is
77 * to be used only if nothing else
78 * is found; <code>null</code> to indicate that
79 * there is no fallback class name
80 * @exception WebServiceException if there is an error
81 */
82 static Object find(String factoryId, String fallbackClassName)
83 {
84 if (isOsgi()) {
85 return lookupUsingOSGiServiceLoader(factoryId);
86 }
87 ClassLoader classLoader;
88 try {
89 classLoader = Thread.currentThread().getContextClassLoader();
90 } catch (Exception x) {
91 throw new WebServiceException(x.toString(), x);
92 }
94 String serviceId = "META-INF/services/" + factoryId;
95 // try to find services in CLASSPATH
96 try {
97 InputStream is=null;
98 if (classLoader == null) {
99 is=ClassLoader.getSystemResourceAsStream(serviceId);
100 } else {
101 is=classLoader.getResourceAsStream(serviceId);
102 }
104 if( is!=null ) {
105 BufferedReader rd =
106 new BufferedReader(new InputStreamReader(is, "UTF-8"));
108 String factoryClassName = rd.readLine();
109 rd.close();
111 if (factoryClassName != null &&
112 ! "".equals(factoryClassName)) {
113 return newInstance(factoryClassName, classLoader);
114 }
115 }
116 } catch( Exception ex ) {
117 }
120 // try to read from $java.home/lib/jaxws.properties
121 try {
122 String javah=System.getProperty( "java.home" );
123 String configFile = javah + File.separator +
124 "lib" + File.separator + "jaxws.properties";
125 File f=new File( configFile );
126 if( f.exists()) {
127 Properties props=new Properties();
128 props.load( new FileInputStream(f));
129 String factoryClassName = props.getProperty(factoryId);
130 return newInstance(factoryClassName, classLoader);
131 }
132 } catch(Exception ex ) {
133 }
136 // Use the system property
137 try {
138 String systemProp =
139 System.getProperty( factoryId );
140 if( systemProp!=null) {
141 return newInstance(systemProp, classLoader);
142 }
143 } catch (SecurityException se) {
144 }
146 if (fallbackClassName == null) {
147 throw new WebServiceException(
148 "Provider for " + factoryId + " cannot be found", null);
149 }
151 return newInstance(fallbackClassName, classLoader);
152 }
155 /**
156 * Loads the class, provided that the calling thread has an access to the class being loaded.
157 */
158 private static Class safeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
159 try {
160 // make sure that the current thread has an access to the package of the given name.
161 SecurityManager s = System.getSecurityManager();
162 if (s != null) {
163 int i = className.lastIndexOf('.');
164 if (i != -1) {
165 s.checkPackageAccess(className.substring(0, i));
166 }
167 }
169 if (classLoader == null)
170 return Class.forName(className);
171 else
172 return classLoader.loadClass(className);
173 } catch (SecurityException se) {
174 // anyone can access the platform default factory class without permission
175 if (Provider.DEFAULT_JAXWSPROVIDER.equals(className))
176 return Class.forName(className);
177 throw se;
178 }
179 }
181 private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "com.sun.org.glassfish.hk2.osgiresourcelocator.ServiceLoader";
183 private static boolean isOsgi() {
184 try {
185 Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
186 return true;
187 } catch (ClassNotFoundException cnfe) {
188 }
189 return false;
190 }
192 private static Object lookupUsingOSGiServiceLoader(String factoryId) {
193 try {
194 // Use reflection to avoid having any dependendcy on ServiceLoader class
195 Class serviceClass = Class.forName(factoryId);
196 Class[] args = new Class[]{serviceClass};
197 Class target = Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
198 java.lang.reflect.Method m = target.getMethod("lookupProviderInstances", Class.class);
199 java.util.Iterator iter = ((Iterable) m.invoke(null, args)).iterator();
200 return iter.hasNext() ? iter.next() : null;
201 } catch (Exception e) {
202 // log and continue
203 return null;
204 }
205 }
207 }