Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/javax/tools/ToolProvider.java
38900 views
/*1* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.tools;2627import java.io.File;28import java.lang.ref.Reference;29import java.lang.ref.WeakReference;30import java.net.URL;31import java.net.URLClassLoader;32import java.net.MalformedURLException;33import java.util.HashMap;34import java.util.Locale;35import java.util.Map;36import java.util.logging.Logger;37import java.util.logging.Level;38import static java.util.logging.Level.*;3940/**41* Provides methods for locating tool providers, for example,42* providers of compilers. This class complements the43* functionality of {@link java.util.ServiceLoader}.44*45* @author Peter von der Ahé46* @since 1.647*/48public class ToolProvider {4950private static final String propertyName = "sun.tools.ToolProvider";51private static final String loggerName = "javax.tools";5253/*54* Define the system property "sun.tools.ToolProvider" to enable55* debugging:56*57* java ... -Dsun.tools.ToolProvider ...58*/59static <T> T trace(Level level, Object reason) {60// NOTE: do not make this method private as it affects stack traces61try {62if (System.getProperty(propertyName) != null) {63StackTraceElement[] st = Thread.currentThread().getStackTrace();64String method = "???";65String cls = ToolProvider.class.getName();66if (st.length > 2) {67StackTraceElement frame = st[2];68method = String.format((Locale)null, "%s(%s:%s)",69frame.getMethodName(),70frame.getFileName(),71frame.getLineNumber());72cls = frame.getClassName();73}74Logger logger = Logger.getLogger(loggerName);75if (reason instanceof Throwable) {76logger.logp(level, cls, method,77reason.getClass().getName(), (Throwable)reason);78} else {79logger.logp(level, cls, method, String.valueOf(reason));80}81}82} catch (SecurityException ex) {83System.err.format((Locale)null, "%s: %s; %s%n",84ToolProvider.class.getName(),85reason,86ex.getLocalizedMessage());87}88return null;89}9091private static final String defaultJavaCompilerName92= "com.sun.tools.javac.api.JavacTool";9394/**95* Gets the Java™ programming language compiler provided96* with this platform.97* @return the compiler provided with this platform or98* {@code null} if no compiler is provided99*/100public static JavaCompiler getSystemJavaCompiler() {101return instance().getSystemTool(JavaCompiler.class, defaultJavaCompilerName);102}103104private static final String defaultDocumentationToolName105= "com.sun.tools.javadoc.api.JavadocTool";106107/**108* Gets the Java™ programming language documentation tool provided109* with this platform.110* @return the documentation tool provided with this platform or111* {@code null} if no documentation tool is provided112*/113public static DocumentationTool getSystemDocumentationTool() {114return instance().getSystemTool(DocumentationTool.class, defaultDocumentationToolName);115}116117/**118* Returns the class loader for tools provided with this platform.119* This does not include user-installed tools. Use the120* {@linkplain java.util.ServiceLoader service provider mechanism}121* for locating user installed tools.122*123* @return the class loader for tools provided with this platform124* or {@code null} if no tools are provided125*/126public static ClassLoader getSystemToolClassLoader() {127try {128Class<? extends JavaCompiler> c =129instance().getSystemToolClass(JavaCompiler.class, defaultJavaCompilerName);130return c.getClassLoader();131} catch (Throwable e) {132return trace(WARNING, e);133}134}135136137private static ToolProvider instance;138139private static synchronized ToolProvider instance() {140if (instance == null)141instance = new ToolProvider();142return instance;143}144145// Cache for tool classes.146// Use weak references to avoid keeping classes around unnecessarily147private Map<String, Reference<Class<?>>> toolClasses = new HashMap<String, Reference<Class<?>>>();148149// Cache for tool classloader.150// Use a weak reference to avoid keeping it around unnecessarily151private Reference<ClassLoader> refToolClassLoader = null;152153154private ToolProvider() { }155156private <T> T getSystemTool(Class<T> clazz, String name) {157Class<? extends T> c = getSystemToolClass(clazz, name);158try {159return c.asSubclass(clazz).newInstance();160} catch (Throwable e) {161trace(WARNING, e);162return null;163}164}165166private <T> Class<? extends T> getSystemToolClass(Class<T> clazz, String name) {167Reference<Class<?>> refClass = toolClasses.get(name);168Class<?> c = (refClass == null ? null : refClass.get());169if (c == null) {170try {171c = findSystemToolClass(name);172} catch (Throwable e) {173return trace(WARNING, e);174}175toolClasses.put(name, new WeakReference<Class<?>>(c));176}177return c.asSubclass(clazz);178}179180private static final String[] defaultToolsLocation = { "lib", "tools.jar" };181182private Class<?> findSystemToolClass(String toolClassName)183throws MalformedURLException, ClassNotFoundException184{185// try loading class directly, in case tool is on the bootclasspath186try {187return Class.forName(toolClassName, false, null);188} catch (ClassNotFoundException e) {189trace(FINE, e);190191// if tool not on bootclasspath, look in default tools location (tools.jar)192ClassLoader cl = (refToolClassLoader == null ? null : refToolClassLoader.get());193if (cl == null) {194File file = new File(System.getProperty("java.home"));195if (file.getName().equalsIgnoreCase("jre"))196file = file.getParentFile();197for (String name : defaultToolsLocation)198file = new File(file, name);199200// if tools not found, no point in trying a URLClassLoader201// so rethrow the original exception.202if (!file.exists())203throw e;204205URL[] urls = { file.toURI().toURL() };206trace(FINE, urls[0].toString());207208cl = URLClassLoader.newInstance(urls);209refToolClassLoader = new WeakReference<ClassLoader>(cl);210}211212return Class.forName(toolClassName, false, cl);213}214}215}216217218