Path: blob/master/src/jdk.compiler/share/classes/sun/tools/serialver/SerialVer.java
41154 views
/*1* Copyright (c) 1996, 2019, 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 sun.tools.serialver;2627import java.io.*;28import java.io.ObjectStreamClass;29import java.nio.file.Paths;30import java.text.MessageFormat;31import java.util.ResourceBundle;32import java.util.MissingResourceException;33import java.net.URLClassLoader;34import java.net.URL;35import java.net.MalformedURLException;3637/**38* Supporting class for the serialver tool.39*/40public class SerialVer {4142/*43* A class loader that will load from the CLASSPATH environment44* variable set by the user.45*/46static URLClassLoader loader = null;4748/*49* Create a URL class loader that will load classes from the50* specified classpath.51*/52static void initializeLoader(String cp) throws IOException {53String[] paths = cp.split(File.pathSeparator);54int count = paths.length;55URL[] urls = new URL[count];56for (int i = 0; i < count; i++) {57urls[i] = Paths.get(paths[i]).toUri().toURL();58}59loader = new URLClassLoader(urls);60}6162/*63* From the classname find the serialVersionUID string formatted64* for to be copied to a java class.65*/66static String serialSyntax(String classname) throws ClassNotFoundException {67String ret = null;68boolean classFound = false;6970// If using old style of qualifying inner classes with '$'s.71if (classname.indexOf('$') != -1) {72ret = resolveClass(classname);73} else {74/* Try to resolve the fully qualified name and if that fails, start75* replacing the '.'s with '$'s starting from the last '.', until76* the class is resolved.77*/78try {79ret = resolveClass(classname);80classFound = true;81} catch (ClassNotFoundException e) {82/* Class not found so far */83}84if (!classFound) {85StringBuilder workBuffer = new StringBuilder(classname);86String workName = workBuffer.toString();87int i;88while ((i = workName.lastIndexOf('.')) != -1 && !classFound) {89workBuffer.setCharAt(i, '$');90try {91workName = workBuffer.toString();92ret = resolveClass(workName);93classFound = true;94} catch (ClassNotFoundException e) {95/* Continue searching */96}97}98}99if (!classFound) {100throw new ClassNotFoundException();101}102}103return ret;104}105106static String resolveClass(String classname) throws ClassNotFoundException {107Class<?> cl = Class.forName(classname, false, loader);108ObjectStreamClass desc = ObjectStreamClass.lookup(cl);109if (desc != null) {110return " private static final long serialVersionUID = " +111desc.getSerialVersionUID() + "L;";112} else {113return null;114}115}116117/**118* Entry point for serialver tool.119* @param args the arguments120*/121public static void main(String[] args) {122String envcp = null;123int i = 0;124125if (args.length == 0) {126usage();127System.exit(1);128}129130for (i = 0; i < args.length; i++) {131if (args[i].equals("-classpath")) {132if ((i+1 == args.length) || args[i+1].startsWith("-")) {133System.err.println(Res.getText("error.missing.classpath"));134usage();135System.exit(1);136}137envcp = new String(args[i+1]);138i++;139} else if (args[i].startsWith("-")) {140System.err.println(Res.getText("invalid.flag", args[i]));141usage();142System.exit(1);143} else {144break; // drop into processing class names145}146}147148149/*150* Get user's CLASSPATH environment variable, if the -classpath option151* is not defined, and make a loader that can read from that path.152*/153if (envcp == null) {154envcp = System.getProperty("env.class.path");155/*156* If environment variable not set, add current directory to path.157*/158if (envcp == null) {159envcp = ".";160}161}162163try {164initializeLoader(envcp);165} catch (MalformedURLException mue) {166System.err.println(Res.getText("error.parsing.classpath", envcp));167System.exit(2);168} catch (IOException ioe) {169System.err.println(Res.getText("error.parsing.classpath", envcp));170System.exit(3);171}172173/*174* Check if there are any class names specified175*/176if (i == args.length) {177usage();178System.exit(1);179}180181/*182* The rest of the parameters are classnames.183*/184boolean exitFlag = false;185for (i = i; i < args.length; i++ ) {186try {187String syntax = serialSyntax(args[i]);188if (syntax != null)189System.out.println(args[i] + ":" + syntax);190else {191System.err.println(Res.getText("NotSerializable",192args[i]));193exitFlag = true;194}195} catch (ClassNotFoundException cnf) {196System.err.println(Res.getText("ClassNotFound", args[i]));197exitFlag = true;198}199}200if (exitFlag) {201System.exit(1);202}203}204205206/**207* Usage208*/209public static void usage() {210System.err.println(Res.getText("usage"));211}212213}214215/**216* Utility for integrating with serialver and for localization.217* Handle Resources. Access to error and warning counts.218* Message formatting.219*220* @see java.util.ResourceBundle221* @see java.text.MessageFormat222*/223class Res {224225private static ResourceBundle messageRB;226227/**228* Initialize ResourceBundle229*/230static void initResource() {231try {232messageRB =233ResourceBundle.getBundle("sun.tools.serialver.resources.serialver");234} catch (MissingResourceException e) {235throw new Error("Fatal: Resource for serialver is missing");236}237}238239/**240* get and format message string from resource241*242* @param key selects message from resource243*/244static String getText(String key) {245return getText(key, (String)null);246}247248/**249* get and format message string from resource250*251* @param key selects message from resource252* @param a1 first argument253*/254static String getText(String key, String a1) {255return getText(key, a1, null);256}257258/**259* get and format message string from resource260*261* @param key selects message from resource262* @param a1 first argument263* @param a2 second argument264*/265static String getText(String key, String a1, String a2) {266return getText(key, a1, a2, null);267}268269/**270* get and format message string from resource271*272* @param key selects message from resource273* @param a1 first argument274* @param a2 second argument275* @param a3 third argument276*/277static String getText(String key, String a1, String a2, String a3) {278if (messageRB == null) {279initResource();280}281try {282String message = messageRB.getString(key);283return MessageFormat.format(message, a1, a2, a3);284} catch (MissingResourceException e) {285throw new Error("Fatal: Resource for serialver is broken. There is no " + key + " key in resource.");286}287}288}289290291