src/share/classes/javax/tools/ToolProvider.java

Tue, 28 Dec 2010 15:54:52 -0800

author
ohair
date
Tue, 28 Dec 2010 15:54:52 -0800
changeset 798
4868a36f6fd8
parent 659
cfd047f3cf60
child 816
7c537f4298fb
permissions
-rw-r--r--

6962318: Update copyright year
Reviewed-by: xdono

     1 /*
     2  * Copyright (c) 2005, 2010, 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.tools;
    28 import java.io.File;
    29 import java.lang.ref.Reference;
    30 import java.lang.ref.WeakReference;
    31 import java.net.URL;
    32 import java.net.URLClassLoader;
    33 import java.net.MalformedURLException;
    34 import java.util.HashMap;
    35 import java.util.Locale;
    36 import java.util.Map;
    37 import java.util.logging.Logger;
    38 import java.util.logging.Level;
    39 import static java.util.logging.Level.*;
    41 /**
    42  * Provides methods for locating tool providers, for example,
    43  * providers of compilers.  This class complements the
    44  * functionality of {@link java.util.ServiceLoader}.
    45  *
    46  * @author Peter von der Ahé
    47  * @since 1.6
    48  */
    49 public class ToolProvider {
    51     private static final String propertyName = "sun.tools.ToolProvider";
    52     private static final String loggerName   = "javax.tools";
    54     /*
    55      * Define the system property "sun.tools.ToolProvider" to enable
    56      * debugging:
    57      *
    58      *     java ... -Dsun.tools.ToolProvider ...
    59      */
    60     static <T> T trace(Level level, Object reason) {
    61         // NOTE: do not make this method private as it affects stack traces
    62         try {
    63             if (System.getProperty(propertyName) != null) {
    64                 StackTraceElement[] st = Thread.currentThread().getStackTrace();
    65                 String method = "???";
    66                 String cls = ToolProvider.class.getName();
    67                 if (st.length > 2) {
    68                     StackTraceElement frame = st[2];
    69                     method = String.format((Locale)null, "%s(%s:%s)",
    70                                            frame.getMethodName(),
    71                                            frame.getFileName(),
    72                                            frame.getLineNumber());
    73                     cls = frame.getClassName();
    74                 }
    75                 Logger logger = Logger.getLogger(loggerName);
    76                 if (reason instanceof Throwable) {
    77                     logger.logp(level, cls, method,
    78                                 reason.getClass().getName(), (Throwable)reason);
    79                 } else {
    80                     logger.logp(level, cls, method, String.valueOf(reason));
    81                 }
    82             }
    83         } catch (SecurityException ex) {
    84             System.err.format((Locale)null, "%s: %s; %s%n",
    85                               ToolProvider.class.getName(),
    86                               reason,
    87                               ex.getLocalizedMessage());
    88         }
    89         return null;
    90     }
    92     private static final String defaultJavaCompilerName
    93         = "com.sun.tools.javac.api.JavacTool";
    95     /**
    96      * Gets the Java&trade; programming language compiler provided
    97      * with this platform.
    98      * @return the compiler provided with this platform or
    99      * {@code null} if no compiler is provided
   100      */
   101     public static JavaCompiler getSystemJavaCompiler() {
   102         return instance().getSystemTool(JavaCompiler.class, defaultJavaCompilerName);
   103     }
   105     /**
   106      * Returns the class loader for tools provided with this platform.
   107      * This does not include user-installed tools.  Use the
   108      * {@linkplain java.util.ServiceLoader service provider mechanism}
   109      * for locating user installed tools.
   110      *
   111      * @return the class loader for tools provided with this platform
   112      * or {@code null} if no tools are provided
   113      */
   114     public static ClassLoader getSystemToolClassLoader() {
   115         try {
   116             Class<? extends JavaCompiler> c =
   117                     instance().getSystemToolClass(JavaCompiler.class, defaultJavaCompilerName);
   118             return c.getClassLoader();
   119         } catch (Throwable e) {
   120             return trace(WARNING, e);
   121         }
   122     }
   125     private static ToolProvider instance;
   127     private static synchronized ToolProvider instance() {
   128         if (instance == null)
   129             instance = new ToolProvider();
   130         return instance;
   131     }
   133     // Cache for tool classes.
   134     // Use weak references to avoid keeping classes around unnecessarily
   135     private Map<String, Reference<Class<?>>> toolClasses = new HashMap<String, Reference<Class<?>>>();
   137     // Cache for tool classloader.
   138     // Use a weak reference to avoid keeping it around unnecessarily
   139     private Reference<ClassLoader> refToolClassLoader = null;
   142     private ToolProvider() { }
   144     private <T> T getSystemTool(Class<T> clazz, String name) {
   145         Class<? extends T> c = getSystemToolClass(clazz, name);
   146         try {
   147             return c.asSubclass(clazz).newInstance();
   148         } catch (Throwable e) {
   149             trace(WARNING, e);
   150             return null;
   151         }
   152     }
   154     private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) {
   155         Reference<Class<?>> refClass = toolClasses.get(name);
   156         Class<?> c = (refClass == null ? null : refClass.get());
   157         if (c == null) {
   158             try {
   159                 c = findSystemToolClass(name);
   160             } catch (Throwable e) {
   161                 return trace(WARNING, e);
   162             }
   163             toolClasses.put(name, new WeakReference<Class<?>>(c));
   164         }
   165         return c.asSubclass(clazz);
   166     }
   168     private static final String[] defaultToolsLocation = { "lib", "tools.jar" };
   170     private Class<?> findSystemToolClass(String toolClassName)
   171         throws MalformedURLException, ClassNotFoundException
   172     {
   173         // try loading class directly, in case tool is on the bootclasspath
   174         try {
   175             return enableAsserts(Class.forName(toolClassName, false, null));
   176         } catch (ClassNotFoundException e) {
   177             trace(FINE, e);
   179             // if tool not on bootclasspath, look in default tools location (tools.jar)
   180             ClassLoader cl = (refToolClassLoader == null ? null : refToolClassLoader.get());
   181             if (cl == null) {
   182                 File file = new File(System.getProperty("java.home"));
   183                 if (file.getName().equalsIgnoreCase("jre"))
   184                     file = file.getParentFile();
   185                 for (String name : defaultToolsLocation)
   186                     file = new File(file, name);
   188                 // if tools not found, no point in trying a URLClassLoader
   189                 // so rethrow the original exception.
   190                 if (!file.exists())
   191                     throw e;
   193                 URL[] urls = { file.toURI().toURL() };
   194                 trace(FINE, urls[0].toString());
   196                 cl = URLClassLoader.newInstance(urls);
   197                 cl.setPackageAssertionStatus("com.sun.tools.javac", true);
   198                 refToolClassLoader = new WeakReference<ClassLoader>(cl);
   199             }
   201             return Class.forName(toolClassName, false, cl);
   202         }
   204     }
   206     private static Class<?> enableAsserts(Class<?> cls) {
   207         try {
   208             ClassLoader loader = cls.getClassLoader();
   209             if (loader != null)
   210                 loader.setPackageAssertionStatus("com.sun.tools.javac", true);
   211             else
   212                 trace(FINE, "loader == null");
   213         } catch (SecurityException ex) {
   214             trace(FINE, ex);
   215         }
   216         return cls;
   217     }
   220 }

mercurial