/* * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.serialver; import java.io.*; import java.io.ObjectStreamClass; import java.nio.file.Paths; import java.text.MessageFormat; import java.util.ResourceBundle; import java.util.MissingResourceException; import java.net.URLClassLoader; import java.net.URL; import java.net.MalformedURLException; /** * Supporting class for the serialver tool. */ public class SerialVer { /* * A class loader that will load from the CLASSPATH environment * variable set by the user. */ static URLClassLoader loader = null; /* * Create a URL class loader that will load classes from the * specified classpath. */ static void initializeLoader(String cp) throws IOException { String[] paths = cp.split(File.pathSeparator); int count = paths.length; URL[] urls = new URL[count]; for (int i = 0; i < count; i++) { urls[i] = Paths.get(paths[i]).toUri().toURL(); } loader = new URLClassLoader(urls); } /* * From the classname find the serialVersionUID string formatted * for to be copied to a java class. */ static String serialSyntax(String classname) throws ClassNotFoundException { String ret = null; boolean classFound = false; // If using old style of qualifyling inner classes with '$'s. if (classname.indexOf('$') != -1) { ret = resolveClass(classname); } else { /* Try to resolve the fully qualified name and if that fails, start * replacing the '.'s with '$'s starting from the last '.', until * the class is resolved. */ try { ret = resolveClass(classname); classFound = true; } catch (ClassNotFoundException e) { /* Class not found so far */ } if (!classFound) { StringBuilder workBuffer = new StringBuilder(classname); String workName = workBuffer.toString(); int i; while ((i = workName.lastIndexOf('.')) != -1 && !classFound) { workBuffer.setCharAt(i, '$'); try { workName = workBuffer.toString(); ret = resolveClass(workName); classFound = true; } catch (ClassNotFoundException e) { /* Continue searching */ } } } if (!classFound) { throw new ClassNotFoundException(); } } return ret; } static String resolveClass(String classname) throws ClassNotFoundException { Class<?> cl = Class.forName(classname, false, loader); ObjectStreamClass desc = ObjectStreamClass.lookup(cl); if (desc != null) { return " private static final long serialVersionUID = " + desc.getSerialVersionUID() + "L;"; } else { return null; } } /** * Entry point for serialver tool. * @param args the arguments */ public static void main(String[] args) { String envcp = null; int i = 0; if (args.length == 0) { usage(); System.exit(1); } for (i = 0; i < args.length; i++) { if (args[i].equals("-classpath")) { if ((i+1 == args.length) || args[i+1].startsWith("-")) { System.err.println(Res.getText("error.missing.classpath")); usage(); System.exit(1); } envcp = new String(args[i+1]); i++; } else if (args[i].startsWith("-")) { System.err.println(Res.getText("invalid.flag", args[i])); usage(); System.exit(1); } else { break; // drop into processing class names } } /* * Get user's CLASSPATH environment variable, if the -classpath option * is not defined, and make a loader that can read from that path. */ if (envcp == null) { envcp = System.getProperty("env.class.path"); /* * If environment variable not set, add current directory to path. */ if (envcp == null) { envcp = "."; } } try { initializeLoader(envcp); } catch (MalformedURLException mue) { System.err.println(Res.getText("error.parsing.classpath", envcp)); System.exit(2); } catch (IOException ioe) { System.err.println(Res.getText("error.parsing.classpath", envcp)); System.exit(3); } /* * Check if there are any class names specified */ if (i == args.length) { usage(); System.exit(1); } /* * The rest of the parameters are classnames. */ boolean exitFlag = false; for (i = i; i < args.length; i++ ) { try { String syntax = serialSyntax(args[i]); if (syntax != null) System.out.println(args[i] + ":" + syntax); else { System.err.println(Res.getText("NotSerializable", args[i])); exitFlag = true; } } catch (ClassNotFoundException cnf) { System.err.println(Res.getText("ClassNotFound", args[i])); exitFlag = true; } } if (exitFlag) { System.exit(1); } } /** * Usage */ public static void usage() { System.err.println(Res.getText("usage")); } } /** * Utility for integrating with serialver and for localization. * Handle Resources. Access to error and warning counts. * Message formatting. * * @see java.util.ResourceBundle * @see java.text.MessageFormat */ class Res { private static ResourceBundle messageRB; /** * Initialize ResourceBundle */ static void initResource() { try { messageRB = ResourceBundle.getBundle("sun.tools.serialver.resources.serialver"); } catch (MissingResourceException e) { throw new Error("Fatal: Resource for serialver is missing"); } } /** * get and format message string from resource * * @param key selects message from resource */ static String getText(String key) { return getText(key, (String)null); } /** * get and format message string from resource * * @param key selects message from resource * @param a1 first argument */ static String getText(String key, String a1) { return getText(key, a1, null); } /** * get and format message string from resource * * @param key selects message from resource * @param a1 first argument * @param a2 second argument */ static String getText(String key, String a1, String a2) { return getText(key, a1, a2, null); } /** * get and format message string from resource * * @param key selects message from resource * @param a1 first argument * @param a2 second argument * @param a3 third argument */ static String getText(String key, String a1, String a2, String a3) { if (messageRB == null) { initResource(); } try { String message = messageRB.getString(key); return MessageFormat.format(message, a1, a2, a3); } catch (MissingResourceException e) { throw new Error("Fatal: Resource for serialver is broken. There is no " + key + " key in resource."); } } }