jaxws/src/jdk.xml.ws/share/classes/com/sun/tools/internal/ws/Invoker.java
changeset 26658 e04929038abf
parent 25871 b80b84e87032
equal deleted inserted replaced
26542:9d0e6639a4d7 26658:e04929038abf
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2014, 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
    27 
    27 
    28 import com.sun.istack.internal.tools.MaskingClassLoader;
    28 import com.sun.istack.internal.tools.MaskingClassLoader;
    29 import com.sun.istack.internal.tools.ParallelWorldClassLoader;
    29 import com.sun.istack.internal.tools.ParallelWorldClassLoader;
    30 import com.sun.tools.internal.ws.resources.WscompileMessages;
    30 import com.sun.tools.internal.ws.resources.WscompileMessages;
    31 import com.sun.tools.internal.ws.wscompile.Options;
    31 import com.sun.tools.internal.ws.wscompile.Options;
    32 import com.sun.tools.internal.xjc.api.util.ToolsJarNotFoundException;
       
    33 import com.sun.xml.internal.bind.util.Which;
    32 import com.sun.xml.internal.bind.util.Which;
    34 
    33 
    35 import javax.xml.ws.Service;
    34 import javax.xml.ws.Service;
    36 import javax.xml.ws.WebServiceFeature;
    35 import javax.xml.ws.WebServiceFeature;
    37 import javax.xml.namespace.QName;
    36 import javax.xml.namespace.QName;
    38 import java.io.File;
       
    39 import java.io.OutputStream;
    37 import java.io.OutputStream;
    40 import java.io.IOException;
    38 import java.io.IOException;
    41 import java.lang.reflect.Constructor;
    39 import java.lang.reflect.Constructor;
    42 import java.lang.reflect.InvocationTargetException;
    40 import java.lang.reflect.InvocationTargetException;
    43 import java.lang.reflect.Method;
    41 import java.lang.reflect.Method;
    44 import java.net.MalformedURLException;
       
    45 import java.net.URL;
    42 import java.net.URL;
    46 import java.net.URLClassLoader;
    43 import java.net.URLClassLoader;
    47 import java.util.ArrayList;
    44 import java.util.ArrayList;
    48 import java.util.Arrays;
    45 import java.util.Arrays;
    49 import java.util.List;
    46 import java.util.List;
    57 public final class Invoker {
    54 public final class Invoker {
    58 
    55 
    59     /**
    56     /**
    60      * The list of package prefixes we want the
    57      * The list of package prefixes we want the
    61      * {@link MaskingClassLoader} to prevent the parent
    58      * {@link MaskingClassLoader} to prevent the parent
    62      * classLoader from loading
    59      * class loader from loading
    63      */
    60      */
    64     static final String[] maskedPackages = new String[]{
    61     static final String[] maskedPackages = new String[]{
    65             "com.sun.istack.internal.tools.",
    62             "com.sun.istack.internal.tools.",
    66             "com.sun.tools.internal.jxc.",
    63             "com.sun.tools.internal.jxc.",
    67             "com.sun.tools.internal.xjc.",
    64             "com.sun.tools.internal.xjc.",
   128                         System.err.println(WscompileMessages.WRAPPER_TASK_LOADING_INCORRECT_API(loadedVersion.getVersion(), Which.which(Service.class), targetVersion.getVersion()));
   125                         System.err.println(WscompileMessages.WRAPPER_TASK_LOADING_INCORRECT_API(loadedVersion.getVersion(), Which.which(Service.class), targetVersion.getVersion()));
   129                     }
   126                     }
   130                     return -1;
   127                     return -1;
   131                 }
   128                 }
   132 
   129 
   133                 //find and load tools.jar
       
   134                 List<URL> urls = new ArrayList<URL>();
       
   135                 findToolsJar(cl, urls);
       
   136 
       
   137                 if(urls.size() > 0){
       
   138                     List<String> mask = new ArrayList<String>(Arrays.asList(maskedPackages));
       
   139 
       
   140                     // first create a protected area so that we load JAXB/WS 2.1 API
       
   141                     // and everything that depends on them inside
       
   142                     cl = new MaskingClassLoader(cl,mask);
       
   143 
       
   144                     // then this classloader loads the API and tools.jar
       
   145                     cl = new URLClassLoader(urls.toArray(new URL[urls.size()]), cl);
       
   146 
       
   147                     // finally load the rest of the RI. The actual class files are loaded from ancestors
       
   148                     cl = new ParallelWorldClassLoader(cl,"");
       
   149                         }
       
   150 
       
   151             }
   130             }
   152 
   131 
   153             Thread.currentThread().setContextClassLoader(cl);
   132             Thread.currentThread().setContextClassLoader(cl);
   154 
   133 
   155             Class compileTool = cl.loadClass(mainClass);
   134             Class compileTool = cl.loadClass(mainClass);
   156             Constructor ctor = compileTool.getConstructor(OutputStream.class);
   135             Constructor ctor = compileTool.getConstructor(OutputStream.class);
   157             Object tool = ctor.newInstance(System.out);
   136             Object tool = ctor.newInstance(System.out);
   158             Method runMethod = compileTool.getMethod("run",String[].class);
   137             Method runMethod = compileTool.getMethod("run",String[].class);
   159             boolean r = (Boolean)runMethod.invoke(tool,new Object[]{args});
   138             boolean r = (Boolean)runMethod.invoke(tool,new Object[]{args});
   160             return r ? 0 : 1;
   139             return r ? 0 : 1;
   161         } catch (ToolsJarNotFoundException e) {
       
   162             System.err.println(e.getMessage());
       
   163         } catch (InvocationTargetException e) {
   140         } catch (InvocationTargetException e) {
   164             throw e.getCause();
   141             throw e.getCause();
   165         } catch(ClassNotFoundException e){
   142         } catch(ClassNotFoundException e){
   166             throw e;
   143             throw e;
   167         }finally {
   144         }finally {
   168             Thread.currentThread().setContextClassLoader(oldcc);
   145             Thread.currentThread().setContextClassLoader(oldcc);
   169         }
   146         }
   170 
       
   171         return -1;
       
   172     }
   147     }
   173 
   148 
   174     /**
   149     /**
   175      * Returns true if the RI appears to be loading the JAX-WS 2.1 API.
   150      * Returns true if the RI appears to be loading the JAX-WS 2.1 API.
   176      */
   151      */
   201        return false;
   176        return false;
   202    }
   177    }
   203 
   178 
   204 
   179 
   205     /**
   180     /**
   206      * Creates a classloader that can load JAXB/WS 2.2 API and tools.jar,
   181      * Creates a class loader that can load JAXB/WS 2.2 API,
   207      * and then return a classloader that can RI classes, which can see all those APIs and tools.jar.
   182      * and then return a class loader that can RI classes, which can see all those APIs.
   208      */
   183      */
   209     public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException {
   184     public static ClassLoader createClassLoader(ClassLoader cl) throws ClassNotFoundException, IOException {
   210 
   185 
   211         URL[] urls = findIstack22APIs(cl);
   186         URL[] urls = findIstack22APIs(cl);
   212         if(urls.length==0)
   187         if(urls.length==0)
   213             return cl;  // we seem to be able to load everything already. no need for the hack
   188             return cl;  // we seem to be able to load everything already. no need for the hack
   214 
   189 
   221 
   196 
   222         // first create a protected area so that we load JAXB/WS 2.1 API
   197         // first create a protected area so that we load JAXB/WS 2.1 API
   223         // and everything that depends on them inside
   198         // and everything that depends on them inside
   224         cl = new MaskingClassLoader(cl,mask);
   199         cl = new MaskingClassLoader(cl,mask);
   225 
   200 
   226         // then this classloader loads the API and tools.jar
   201         // then this class loader loads the API
   227         cl = new URLClassLoader(urls, cl);
   202         cl = new URLClassLoader(urls, cl);
   228 
   203 
   229         // finally load the rest of the RI. The actual class files are loaded from ancestors
   204         // finally load the rest of the RI. The actual class files are loaded from ancestors
   230         cl = new ParallelWorldClassLoader(cl,"");
   205         cl = new ParallelWorldClassLoader(cl,"");
   231 
   206 
   232         return cl;
   207         return cl;
   233     }
   208     }
   234 
   209 
   235     /**
   210     /**
   236      * Creates a classloader for loading JAXB/WS 2.2 jar and tools.jar
   211      * Creates a class loader for loading JAXB/WS 2.2 jar
   237      */
   212      */
   238     private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException, ToolsJarNotFoundException {
   213     private static URL[] findIstack22APIs(ClassLoader cl) throws ClassNotFoundException, IOException {
   239         List<URL> urls = new ArrayList<URL>();
   214         List<URL> urls = new ArrayList<URL>();
   240 
   215 
   241         if(Service.class.getClassLoader()==null) {
   216         if(Service.class.getClassLoader()==null) {
   242             // JAX-WS API is loaded from bootstrap classloader
   217             // JAX-WS API is loaded from bootstrap class loader
   243             URL res = cl.getResource("javax/xml/ws/EndpointContext.class");
   218             URL res = cl.getResource("javax/xml/ws/EndpointContext.class");
   244             if(res==null)
   219             if(res==null)
   245                 throw new ClassNotFoundException("There's no JAX-WS 2.2 API in the classpath");
   220                 throw new ClassNotFoundException("There's no JAX-WS 2.2 API in the classpath");
   246             urls.add(ParallelWorldClassLoader.toJarUrl(res));
   221             urls.add(ParallelWorldClassLoader.toJarUrl(res));
   247             res = cl.getResource("javax/xml/bind/JAXBPermission.class");
   222             res = cl.getResource("javax/xml/bind/JAXBPermission.class");
   248             if(res==null)
   223             if(res==null)
   249                 throw new ClassNotFoundException("There's no JAXB 2.2 API in the classpath");
   224                 throw new ClassNotFoundException("There's no JAXB 2.2 API in the classpath");
   250             urls.add(ParallelWorldClassLoader.toJarUrl(res));
   225             urls.add(ParallelWorldClassLoader.toJarUrl(res));
   251         }
   226         }
   252 
   227 
   253         findToolsJar(cl, urls);
       
   254 
       
   255         return urls.toArray(new URL[urls.size()]);
   228         return urls.toArray(new URL[urls.size()]);
   256     }
   229     }
   257 
   230 
   258     private static void findToolsJar(ClassLoader cl, List<URL> urls) throws ToolsJarNotFoundException, MalformedURLException {
       
   259         try {
       
   260             Class.forName("com.sun.tools.javac.Main",false,cl);
       
   261             // we can already load them in the parent class loader.
       
   262             // so no need to look for tools.jar.
       
   263             // this happens when we are run inside IDE/Ant, or
       
   264             // in Mac OS.
       
   265         } catch (ClassNotFoundException e) {
       
   266             // otherwise try to find tools.jar
       
   267             File jreHome = new File(System.getProperty("java.home"));
       
   268             File toolsJar = new File( jreHome.getParent(), "lib/tools.jar" );
       
   269 
       
   270             if (!toolsJar.exists()) {
       
   271                 throw new ToolsJarNotFoundException(toolsJar);
       
   272             }
       
   273             urls.add(toolsJar.toURL());
       
   274         }
       
   275     }
       
   276 
       
   277 }
   231 }