--- old/src/share/vm/logging/logTag.hpp 2016-02-22 15:23:39.324523787 -0500 +++ new/src/share/vm/logging/logTag.hpp 2016-02-22 15:23:39.195094781 -0500 @@ -42,6 +42,7 @@ LOG_TAG(classload) /* Trace all classes loaded */ \ LOG_TAG(classloaderdata) /* class loader loader_data lifetime */ \ LOG_TAG(classunload) /* Trace unloading of classes */ \ + LOG_TAG(classpath) \ LOG_TAG(compaction) \ LOG_TAG(cpu) \ LOG_TAG(cset) \ --- old/src/share/vm/classfile/classLoader.hpp 2016-02-22 15:23:39.368200000 -0500 +++ new/src/share/vm/classfile/classLoader.hpp 2016-02-22 15:23:39.194616457 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -331,7 +331,7 @@ static void exit_with_path_failure(const char* error, const char* message); #endif - static void trace_class_path(outputStream* out, const char* msg, const char* name = NULL); + static void trace_class_path(const char* msg, const char* name = NULL); // VM monitoring and management support static jlong classloader_time_ms(); --- old/src/share/vm/classfile/sharedPathsMiscInfo.cpp 2016-02-22 15:23:39.351444449 -0500 +++ new/src/share/vm/classfile/sharedPathsMiscInfo.cpp 2016-02-22 15:23:39.191194819 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -26,15 +26,15 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/sharedPathsMiscInfo.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/metaspaceShared.hpp" #include "runtime/arguments.hpp" +#include "utilities/ostream.hpp" void SharedPathsMiscInfo::add_path(const char* path, int type) { - if (TraceClassPaths) { - tty->print("[type=%s] ", type_name(type)); - trace_class_path("[Add misc shared path ", path); - } + log_info(classpath)("type=%s ", type_name(type)); + ClassLoader::trace_class_path("add misc shared path ", path); write(path, strlen(path) + 1); write_jint(jint(type)); } @@ -67,7 +67,7 @@ } bool SharedPathsMiscInfo::fail(const char* msg, const char* name) { - ClassLoader::trace_class_path(tty, msg, name); + ClassLoader::trace_class_path(msg, name); MetaspaceShared::set_archive_loading_failed(); return false; } @@ -90,17 +90,14 @@ if (!read_jint(&type)) { return fail("Corrupted archive file header"); } - if (TraceClassPaths) { - tty->print("[type=%s ", type_name(type)); - print_path(tty, type, path); - tty->print_cr("]"); - } + log_info(classpath)("type=%s ", type_name(type)); + print_path(type, path); if (!check(type, path)) { if (!PrintSharedArchiveAndExit) { return false; } } else { - trace_class_path("[ok"); + ClassLoader::trace_class_path("ok"); } } --- old/src/share/vm/classfile/sharedPathsMiscInfo.hpp 2016-02-22 15:23:39.397201301 -0500 +++ new/src/share/vm/classfile/sharedPathsMiscInfo.hpp 2016-02-22 15:23:39.243644204 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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 @@ -64,9 +64,6 @@ void write(const void* ptr, size_t size); bool read(void* ptr, size_t size); - static void trace_class_path(const char* msg, const char* name = NULL) { - ClassLoader::trace_class_path(tty, msg, name); - } protected: static bool fail(const char* msg, const char* name = NULL); virtual bool check(jint type, const char* path); @@ -144,7 +141,9 @@ } } - virtual void print_path(outputStream* out, int type, const char* path) { + virtual void print_path(int type, const char* path) { + ResourceMark rm; + outputStream* out = LogHandle(classpath)::info_stream(); switch (type) { case BOOT: out->print("Expecting -Dsun.boot.class.path=%s", path); --- old/src/share/vm/runtime/arguments.cpp 2016-02-22 15:23:39.386490254 -0500 +++ new/src/share/vm/runtime/arguments.cpp 2016-02-22 15:23:39.223378905 -0500 @@ -405,8 +405,9 @@ static AliasedLoggingFlag const aliased_logging_flags[] = { { "TraceClassLoading", LogLevel::Info, true, LogTag::_classload }, - { "TraceClassUnloading", LogLevel::Info, true, LogTag::_classunload }, + { "TraceClassPaths", LogLevel::Info, true, LogTag::_classpath }, { "TraceClassResolution", LogLevel::Info, true, LogTag::_classresolve }, + { "TraceClassUnloading", LogLevel::Info, true, LogTag::_classunload }, { "TraceExceptions", LogLevel::Info, true, LogTag::_exceptions }, { "TraceMonitorInflation", LogLevel::Debug, true, LogTag::_monitorinflation }, { NULL, LogLevel::Off, false, LogTag::__NO_TAG } @@ -3254,7 +3255,7 @@ // PrintSharedArchiveAndExit will turn on // -Xshare:on - // -XX:+TraceClassPaths + // -Xlog:classpath=info if (PrintSharedArchiveAndExit) { if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) { return JNI_EINVAL; @@ -3262,9 +3263,7 @@ if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) { return JNI_EINVAL; } - if (FLAG_SET_CMDLINE(bool, TraceClassPaths, true) != Flag::SUCCESS) { - return JNI_EINVAL; - } + LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(classpath)); } // Change the default value for flags which have different default values @@ -3317,10 +3316,6 @@ _java_class_path->set_value(copy); FreeHeap(copy); // a copy was made by set_value, so don't need this anymore } - - if (!PrintSharedArchiveAndExit) { - ClassLoader::trace_class_path(tty, "[classpath: ", _java_class_path->value()); - } } static bool has_jar_files(const char* directory) { --- /dev/null 2015-11-21 16:36:38.509275105 -0500 +++ new/test/runtime/logging/ClassPathTest.java 2016-02-22 15:23:39.243855789 -0500 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, 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. + * + * 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. + */ + + +/* + * @test ClassPathTest + * @bug 8142976 + * @library /testlibrary + * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.Platform jdk.test.lib.ProcessTools + * @run driver ClassPathTest + */ + +import jdk.test.lib.OutputAnalyzer; +import jdk.test.lib.Platform; +import jdk.test.lib.ProcessTools; + +public class ClassPathTest { + + public static void main(String... args) throws Exception { + + // Test for classpath tag. + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:classpath=info", + "-Xmx64m", + InnerClass.class.getName()); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + out.getOutput(); + out.shouldContain("[classpath]"); + + // Make sure TraceClassPaths is properly aliased. + pb = ProcessTools.createJavaProcessBuilder("-XX:+TraceClassPaths", + "-Xmx64m", + InnerClass.class.getName()); + out = new OutputAnalyzer(pb.start()); + out.shouldContain("[classpath]"); + } + public static class InnerClass { + public static void main(String[] args) throws Exception { + System.out.println("Inner Class"); + } + } +} --- old/src/share/vm/memory/filemap.cpp 2016-02-22 15:23:39.419641832 -0500 +++ new/src/share/vm/memory/filemap.cpp 2016-02-22 15:23:39.272875416 -0500 @@ -208,9 +208,7 @@ count ++; bytes += (int)entry_size; bytes += name_bytes; - if (TraceClassPaths) { - tty->print_cr("[Add main shared path (%s) %s]", (cpe->is_jar_file() ? "jar" : "dir"), name); - } + log_info(classpath)("add main shared path (%s) %s", (cpe->is_jar_file() ? "jar" : "dir"), name); } else { SharedClassPathEntry* ent = shared_classpath(cur_entry); if (cpe->is_jar_file()) { @@ -275,9 +273,7 @@ struct stat st; const char* name = ent->_name; bool ok = true; - if (TraceClassPaths) { - tty->print_cr("[Checking shared classpath entry: %s]", name); - } + log_info(classpath)("checking shared classpath entry: %s", name); if (os::stat(name, &st) != 0) { fail_continue("Required classpath entry does not exist: %s", name); ok = false; @@ -301,9 +297,7 @@ } } if (ok) { - if (TraceClassPaths) { - tty->print_cr("[ok]"); - } + log_info(classpath)("ok"); } else if (!PrintSharedArchiveAndExit) { _validating_classpath_entry_table = false; return false; @@ -888,10 +882,8 @@ char header_version[JVM_IDENT_MAX]; get_header_version(header_version); if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { - if (TraceClassPaths) { - tty->print_cr("Expected: %s", header_version); - tty->print_cr("Actual: %s", _jvm_ident); - } + log_info(classpath)("expected: %s", header_version); + log_info(classpath)("actual: %s", _jvm_ident); FileMapInfo::fail_continue("The shared archive file was created by a different" " version or build of HotSpot"); return false; @@ -919,7 +911,7 @@ if (status) { if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size)) { if (!PrintSharedArchiveAndExit) { - fail_continue("shared class paths mismatch (hint: enable -XX:+TraceClassPaths to diagnose the failure)"); + fail_continue("shared class paths mismatch (hint: enable -Xlog:classpath=info to diagnose the failure)"); status = false; } } --- old/src/share/vm/runtime/globals.hpp 2016-02-22 15:23:39.455611633 -0500 +++ new/src/share/vm/runtime/globals.hpp 2016-02-22 15:23:39.273308048 -0500 @@ -2409,9 +2409,6 @@ product(bool, IgnoreEmptyClassPaths, false, \ "Ignore empty path elements in -classpath") \ \ - product(bool, TraceClassPaths, false, \ - "Trace processing of class paths") \ - \ product(bool, TraceClassLoadingPreorder, false, \ "Trace all classes loaded in order referenced (not loaded)") \ \ --- old/src/share/vm/classfile/classLoader.cpp 2016-02-22 15:23:39.463279020 -0500 +++ new/src/share/vm/classfile/classLoader.cpp 2016-02-22 15:23:39.291819980 -0500 @@ -37,6 +37,7 @@ #include "gc/shared/generation.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/oopMapCache.hpp" +#include "logging/logTag.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" #include "memory/oopFactory.hpp" @@ -417,34 +418,30 @@ #if INCLUDE_CDS void ClassLoader::exit_with_path_failure(const char* error, const char* message) { assert(DumpSharedSpaces, "only called at dump time"); - tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure"); + tty->print_cr("Hint: enable -Xlog:classpath=info to diagnose the failure"); vm_exit_during_initialization(error, message); } #endif -void ClassLoader::trace_class_path(outputStream* out, const char* msg, const char* name) { - if (!TraceClassPaths) { - return; - } - - if (msg) { - out->print("%s", msg); - } - if (name) { - if (strlen(name) < 256) { - out->print("%s", name); - } else { - // For very long paths, we need to print each character separately, - // as print_cr() has a length limit - while (name[0] != '\0') { - out->print("%c", name[0]); - name++; +void ClassLoader::trace_class_path(const char* msg, const char* name) { + if (log_is_enabled(Info, classpath)) { + ResourceMark rm; + outputStream* out = LogHandle(classpath)::info_stream(); + if (msg) { + out->print("%s", msg); + } + if (name) { + if (strlen(name) < 256) { + out->print("%s", name); + } else { + // For very long paths, we need to print each character separately, + // as print_cr() has a length limit + while (name[0] != '\0') { + out->print("%c", name[0]); + name++; + } } } - } - if (msg && msg[0] == '[') { - out->print_cr("]"); - } else { out->cr(); } } @@ -470,11 +467,13 @@ void ClassLoader::setup_bootstrap_search_path() { assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); const char* sys_class_path = Arguments::get_sysclasspath(); + const char* java_class_path = Arguments::get_appclasspath(); if (PrintSharedArchiveAndExit) { // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily // the same as the bootcp of the shared archive. } else { - trace_class_path(tty, "[Bootstrap loader class path=", sys_class_path); + trace_class_path("bootstrap loader class path=", sys_class_path); + trace_class_path("classpath: ", java_class_path); } #if INCLUDE_CDS if (DumpSharedSpaces) { @@ -578,9 +577,7 @@ } } } - if (TraceClassPaths) { - tty->print_cr("[Opened %s]", path); - } + log_info(classpath)("opened: %s", path); log_info(classload)("opened: %s", path); } else { // Directory