All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.util.FindClass Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hadoop.util;

import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.security.CodeSource;

/**
 * This entry point exists for diagnosing classloader problems:
 * is a class or resource present -and if so, where?
 *
 * 

* Actions *
*

    *
  • load
    : load a class but do not attempt to create it
  • *
  • create
    : load and create a class, print its string value
  • *
  • printresource
    : load a resource then print it to stdout
  • *
  • resource
    : load a resource then print the URL of that * resource
  • *
* * It returns an error code if a class/resource cannot be loaded/found * -and optionally a class may be requested as being loaded. * The latter action will call the class's constructor -it must support an * empty constructor); any side effects from the * constructor or static initializers will take place. * * All error messages are printed to {@link System#out}; errors * to {@link System#err}. * */ @SuppressWarnings("UseOfSystemOutOrSystemErr") public final class FindClass extends Configured implements Tool { /** * create command: {@value} */ public static final String A_CREATE = "create"; /** * Load command: {@value} */ public static final String A_LOAD = "load"; /** * Command to locate a resource: {@value} */ public static final String A_RESOURCE = "locate"; /** * Command to locate and print a resource: {@value} */ public static final String A_PRINTRESOURCE = "print"; /** * Exit code when the operation succeeded: {@value} */ public static final int SUCCESS = 0; /** * generic error {@value} */ protected static final int E_GENERIC = 1; /** * usage error -bad arguments or similar {@value} */ protected static final int E_USAGE = 2; /** * class or resource not found {@value} */ protected static final int E_NOT_FOUND = 3; /** * class load failed {@value} */ protected static final int E_LOAD_FAILED = 4; /** * class creation failed {@value} */ protected static final int E_CREATE_FAILED = 5; /** * Output stream. Defaults to {@link System#out} */ private static PrintStream stdout = System.out; /** * Error stream. Defaults to {@link System#err} */ private static PrintStream stderr = System.err; /** * Empty constructor; passes a new Configuration * object instance to its superclass's constructor */ public FindClass() { super(new Configuration()); } /** * Create a class with a specified configuration * @param conf configuration */ public FindClass(Configuration conf) { super(conf); } /** * Change the output streams to be something other than the * System.out and System.err streams * @param out new stdout stream * @param err new stderr stream */ @VisibleForTesting public static void setOutputStreams(PrintStream out, PrintStream err) { stdout = out; stderr = err; } /** * Get a class fromt the configuration * @param name the class name * @return the class * @throws ClassNotFoundException if the class was not found * @throws Error on other classloading problems */ private Class getClass(String name) throws ClassNotFoundException { return getConf().getClassByName(name); } /** * Get the resource * @param name resource name * @return URL or null for not found */ private URL getResource(String name) { return getConf().getResource(name); } /** * Load a resource * @param name resource name * @return the status code */ private int loadResource(String name) { URL url = getResource(name); if (url == null) { err("Resource not found: %s", name); return E_NOT_FOUND; } out("%s: %s", name, url); return SUCCESS; } /** * Dump a resource to out * @param name resource name * @return the status code */ @SuppressWarnings("NestedAssignment") private int dumpResource(String name) { URL url = getResource(name); if (url == null) { err("Resource not found:" + name); return E_NOT_FOUND; } try { //open the resource InputStream instream = url.openStream(); //read it in and print int data; while (-1 != (data = instream.read())) { stdout.print((char) data); } //end of file stdout.print('\n'); return SUCCESS; } catch (IOException e) { printStack(e, "Failed to read resource %s at URL %s", name, url); return E_LOAD_FAILED; } } /** * print something to stderr * @param s string to print */ private static void err(String s, Object... args) { stderr.format(s, args); stderr.print('\n'); } /** * print something to stdout * @param s string to print */ private static void out(String s, Object... args) { stdout.format(s, args); stdout.print('\n'); } /** * print a stack trace with text * @param e the exception to print * @param text text to print */ private static void printStack(Throwable e, String text, Object... args) { err(text, args); e.printStackTrace(stderr); } /** * Loads the class of the given name * @param name classname * @return outcome code */ private int loadClass(String name) { try { Class clazz = getClass(name); loadedClass(name, clazz); return SUCCESS; } catch (ClassNotFoundException e) { printStack(e, "Class not found " + name); return E_NOT_FOUND; } catch (Exception e) { printStack(e, "Exception while loading class " + name); return E_LOAD_FAILED; } catch (Error e) { printStack(e, "Error while loading class " + name); return E_LOAD_FAILED; } } /** * Log that a class has been loaded, and where from. * @param name classname * @param clazz class */ private void loadedClass(String name, Class clazz) { out("Loaded %s as %s", name, clazz); CodeSource source = clazz.getProtectionDomain().getCodeSource(); URL url = source.getLocation(); out("%s: %s", name, url); } /** * Create an instance of a class * @param name classname * @return the outcome */ private int createClassInstance(String name) { try { Class clazz = getClass(name); loadedClass(name, clazz); Object instance = clazz.newInstance(); try { //stringify out("Created instance " + instance.toString()); } catch (Exception e) { //catch those classes whose toString() method is brittle, but don't fail the probe printStack(e, "Created class instance but the toString() operator failed"); } return SUCCESS; } catch (ClassNotFoundException e) { printStack(e, "Class not found " + name); return E_NOT_FOUND; } catch (Exception e) { printStack(e, "Exception while creating class " + name); return E_CREATE_FAILED; } catch (Error e) { printStack(e, "Exception while creating class " + name); return E_CREATE_FAILED; } } /** * Run the class/resource find or load operation * @param args command specific arguments. * @return the outcome * @throws Exception if something went very wrong */ @Override public int run(String[] args) throws Exception { if (args.length != 2) { return usage(args); } String action = args[0]; String name = args[1]; int result; if (A_LOAD.equals(action)) { result = loadClass(name); } else if (A_CREATE.equals(action)) { //first load to separate load errors from create result = loadClass(name); if (result == SUCCESS) { //class loads, so instantiate it result = createClassInstance(name); } } else if (A_RESOURCE.equals(action)) { result = loadResource(name); } else if (A_PRINTRESOURCE.equals(action)) { result = dumpResource(name); } else { result = usage(args); } return result; } /** * Print a usage message * @param args the command line arguments * @return an exit code */ private int usage(String[] args) { err( "Usage : [load | create] "); err( " [locate | print] ]"); err("The return codes are:"); explainResult(SUCCESS, "The operation was successful"); explainResult(E_GENERIC, "Something went wrong"); explainResult(E_USAGE, "This usage message was printed"); explainResult(E_NOT_FOUND, "The class or resource was not found"); explainResult(E_LOAD_FAILED, "The class was found but could not be loaded"); explainResult(E_CREATE_FAILED, "The class was loaded, but an instance of it could not be created"); return E_USAGE; } /** * Explain an error code as part of the usage * @param errorcode error code returned * @param text error text */ private void explainResult(int errorcode, String text) { err(" %2d -- %s ", errorcode , text); } /** * Main entry point. * Runs the class via the {@link ToolRunner}, then * exits with an appropriate exit code. * @param args argument list */ public static void main(String[] args) { try { int result = ToolRunner.run(new FindClass(), args); System.exit(result); } catch (Exception e) { printStack(e, "Running FindClass"); System.exit(E_GENERIC); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy