RFR(S) 8020675: Trying to print to a pdf file with PDFill PDF&Image Writer 10.0 Build 4
Ioi Lam
ioi.lam at oracle.com
Wed Aug 21 20:45:02 PDT 2013
Oh, and while you're at it. this also needs to be cleaned up. The path
argument to update_class_path_entry_list() shouldn't be const -- it may
be modified by os::native_path (see os_windows.cpp). Also,
update_class_path_entry_list() is called from a single place, where the
path is malloc'ed so it's definitely modifiable.
Thanks
- Ioi
--- a/src/share/vm/classfile/classLoader.cpp Mon Aug 05 10:29:35 2013
-0700
+++ b/src/share/vm/classfile/classLoader.cpp Wed Aug 21 20:40:29 2013
-0700
@@ -572,13 +572,13 @@
}
}
-void ClassLoader::update_class_path_entry_list(const char *path,
+void ClassLoader::update_class_path_entry_list(char *path,
bool
check_for_duplicates) {
struct stat st;
- if (os::stat((char *)path, &st) == 0) {
+ if (os::stat(path, &st) == 0) {
// File or directory found
ClassPathEntry* new_entry = NULL;
- create_class_path_entry((char *)path, st, &new_entry,
LazyBootClassLoader);
+ create_class_path_entry(path, st, &new_entry, LazyBootClassLoader);
// The kernel VM adds dynamically to the end of the classloader
path and
// doesn't reorder the bootclasspath which would break
java.lang.Package
// (see PackageInfo).
diff -r 055c29438400 src/share/vm/classfile/classLoader.hpp
--- a/src/share/vm/classfile/classLoader.hpp Mon Aug 05 10:29:35 2013
-0700
+++ b/src/share/vm/classfile/classLoader.hpp Wed Aug 21 20:40:29 2013
-0700
@@ -214,7 +214,7 @@
static bool get_canonical_path(char* orig, char* out, int len);
public:
// Used by the kernel jvm.
- static void update_class_path_entry_list(const char *path,
+ static void update_class_path_entry_list(char *path,
bool check_for_duplicates);
static void print_bootclasspath();
On 08/21/2013 08:35 PM, Ioi Lam wrote:
> On 08/21/2013 05:01 PM, Calvin Cheung wrote:
>> On 8/21/2013 2:01 PM, Ioi Lam wrote:
>>> Calvin,
>>>
>>> I have not looked at the code in detail, but will your code now
>>> repeatedly attempt to open the invalid JAR file? Maybe you can test
>>> that by adding multiple Class.forName() calls in your tests (and
>>> catching any exceptions).
>> public class test3 {
>> public static void main(String[] args) {
>> try {
>> Class cls = Class.forName("xxx");
>> System.out.println("Class = " + cls.getName());
>> cls = Class.forName("yyy");
>> System.out.println("Class = " + cls.getName());
>> } catch (ClassNotFoundException cnfe) {
>> cnfe.printStackTrace();
>> }
>> }
>> }
>>
> How about changing it to do this:
>
> try {
> Class.forName("xxx");
> } catch (ClassNotFoundException cnfe) {
> cnfe.printStackTrace();
> }
> try {
> Class.forName("yyy");
> } catch (ClassNotFoundException cnfe) {
> cnfe.printStackTrace();
> }
>
> I think you will find that create_class_path_entry will be called
> twice for the invalid JAR file with lazy==false.
>
>> With the above test case, CNFE will be thrown for xxx and it won't
>> try to load yyy.
>>>
>>> This is an error case (having an invalid JAR file in bootclasspath)
>>> so performance is not important. However, if there's a simple way to
>>> remember the result and never open the JAR file again that would be
>>> ideal.
>> There's the following method in ClassLoader:
>> void ClassLoader::update_class_path_entry_list(const char *path,
>> bool
>> check_for_duplicates) {
>> struct stat st;
>> if (os::stat((char *)path, &st) == 0) {
>> // File or directory found
>> ClassPathEntry* new_entry = NULL;
>> Thread* THREAD = Thread::current();
>> create_class_path_entry((char *)path, st, &new_entry,
>> LazyBootClassLoader, CHECK);
>> // The kernel VM adds dynamically to the end of the classloader
>> path and
>> // doesn't reorder the bootclasspath which would break
>> java.lang.Package
>> // (see PackageInfo).
>> // Add new entry to linked list
>> if (!check_for_duplicates || !contains_entry(new_entry)) {
>> add_to_list(new_entry);
>> }
>> }
>> }
>>
>> With my fix, if create_class_path_entry() fails, it'll return without
>> calling add_to_list().
>
> I think you should do this to avoid the repeated opening of the
> invalid JAR file:
>
> 317 ClassFileStream* LazyClassPathEntry::open_stream(const char* name) {
> 318 if (_meta_index != NULL &&
> 319 !_meta_index->may_contain(name)) {
> 320 return NULL;
> 321 }
> if (_has_error) { // add a new field bool
> LazyClassPathEntry::_has_error;
> return NULL;
> }
> 322 ClassPathEntry* cpe = resolve_entry();
> if (cpe == NULL) {
> _has_error = true;
> return NULL;
> } else {
> return cpe->open_stream(name);
> 324 }
>
> Also, since you're changing the signature of
> ClassLoader::create_class_path_entry(),
> I think you can perform onemore clean up:
>
> void ClassLoader::create_class_path_entry(char *path, const struct
> stat* st, ClassPathEntry **new_entry, bool lazy, TRAPS)
>
> =>
>
> ClassPathEntry* ClassLoader::create_class_path_entry(char *path,
> struct stat st, bool lazy, TRAPS)
>
> It just doesn't make sense to return void and set the returned value
> in a pointer ...
>
> Also, the st structure is pretty big (88 bytes on linux 32 bits, 144
> bytes on 64 bits). It's better to use a pointer. You can declare it
> const to make sure that the callee doesn't modify it.
>
>
> Thanks
> - Ioi
>
>>
>> thanks,
>> Calvin
>>
>>>
>>> Thanks
>>> - Ioi
>>>
>>> On 08/21/2013 11:49 AM, Calvin Cheung wrote:
>>>> Can someone review this?
>>>>
>>>> Latest version:
>>>> http://cr.openjdk.java.net/~ccheung/8020675/webrev/
>>>>
>>>> Previous version without using TRAPS:
>>>> http://cr.openjdk.java.net/~ccheung/8020675/webrev.00/
>>>>
>>>> thanks,
>>>> Calvin
>>>>
>>>> On 8/12/2013 11:19 PM, Calvin Cheung wrote:
>>>>> Hi David,
>>>>>
>>>>> I cloned the hotspot repo corresponding to 7u25 b15 and debugged a
>>>>> bit more and found that the error was thrown at a very early stage
>>>>> within the init_globals() called from create_vm(). Below is the
>>>>> call stack:
>>>>> jvm.dll!ClassLoader::create_class_path_entry(char * path,
>>>>> stat st, ClassPathEntry * * new_entry, bool lazy) Line 508 C++
>>>>> jvm.dll!LazyClassPathEntry::resolve_entry() Line 303 + 0x24
>>>>> bytes C++
>>>>> jvm.dll!LazyClassPathEntry::open_stream(const char * name)
>>>>> Line 322 + 0x8 bytes C++
>>>>> jvm.dll!ClassLoader::load_classfile(Symbol * h_name, Thread *
>>>>> __the_thread__) Line 898 + 0x17 bytes C++
>>>>> jvm.dll!SystemDictionary::load_instance_class(Symbol *
>>>>> class_name, Handle class_loader, Thread * __the_thread__) Line
>>>>> 1362 + 0x14 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_instance_class_or_null(Symbol *
>>>>> name, Handle class_loader, Handle protection_domain, Thread *
>>>>> __the_thread__) Line 758 + 0x18 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_or_null(Symbol *
>>>>> class_name, Handle class_loader, Handle protection_domain, Thread
>>>>> * __the_thread__) Line 206 + 0x15 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_or_null(Symbol *
>>>>> class_name, Thread * __the_thread__) Line 211 + 0x23 bytes C++
>>>>> jvm.dll!SystemDictionary::initialize_wk_klass(SystemDictionary::WKID
>>>>> id, int init_opt, Thread * __the_thread__) Line 1935 + 0xd
>>>>> bytes C++
>>>>> jvm.dll!SystemDictionary::initialize_wk_klasses_until(SystemDictionary::WKID
>>>>> limit_id, SystemDictionary::WKID & start_id, Thread *
>>>>> __the_thread__) Line 1949 + 0x11 bytes C++
>>>>> jvm.dll!SystemDictionary::initialize_preloaded_classes(Thread *
>>>>> __the_thread__) Line 2011 + 0xf bytes C++
>>>>> jvm.dll!SystemDictionary::initialize(Thread *
>>>>> __the_thread__) Line 1904 + 0x9 bytes C++
>>>>> jvm.dll!Universe::genesis(Thread * __the_thread__) Line 353 +
>>>>> 0x9 bytes C++
>>>>> jvm.dll!universe2_init() Line 1009 + 0x9 bytes C++
>>>>> > jvm.dll!init_globals() Line 114 C++
>>>>> jvm.dll!Threads::create_vm(JavaVMInitArgs * args, bool *
>>>>> canTryAgain) Line 3220 + 0x5 bytes C++
>>>>> jvm.dll!JNI_CreateJavaVM(JavaVM_ * * vm, void * * penv, void
>>>>> * args) Line 5133 + 0xd bytes C++
>>>>> java.exe!011013bd()
>>>>> [Frames below may be incorrect and/or missing, no symbols
>>>>> loaded for java.exe]
>>>>> java.exe!01101e2f()
>>>>> java.exe!0110c807()
>>>>> java.exe!0110a5a1()
>>>>> java.exe!0110c845()
>>>>> java.exe!0110a62b()
>>>>> kernel32.dll!767633aa()
>>>>> ntdll.dll!77739ef2()
>>>>> ntdll.dll!77739ec5()
>>>>>
>>>>> The error was thrown in the method below:
>>>>> bool Exceptions::special_exception(Thread* thread, const char*
>>>>> file, int line, Symbol* h_name, const char* message) {
>>>>> // bootstrapping check
>>>>> if (!Universe::is_fully_initialized()) {
>>>>> if (h_name == NULL) {
>>>>> // atleast an informative message.
>>>>> vm_exit_during_initialization("Exception", message);
>>>>> } else {
>>>>> vm_exit_during_initialization(h_name,
>>>>> message); <=====here
>>>>> }
>>>>> ShouldNotReachHere();
>>>>> }
>>>>> }
>>>>>
>>>>> Note that it happened in the early stage during create_vm(), so
>>>>> the (!Universe::is_fully_initialized()) was true.
>>>>>
>>>>> The class it was trying to load was sun/misc/AtomicLongCSImpl
>>>>> which I couldn't find in 7u25.
>>>>> It was going through all the jar files in the bootclasspath and
>>>>> finally got to the foo.jar which has 0-byte and got "error in
>>>>> opening jar file" and then THROW_MSG().
>>>>> So I think it's just a coincident in 7u25 where the correct error
>>>>> was thrown.
>>>>>
>>>>> In hs25, it didn't try to load the sun/misc/AtomicLongCSImpl class
>>>>> and thus it didn't hit the "error in opening jar file" (for the
>>>>> foo.jar) early until it passed the point when the vm is considered
>>>>> "initialized" - is_init_completed() is true. So when THROW_MSG()
>>>>> was called when it tried to load the class specified by the test
>>>>> case ("xxx"), it triggered the fatal error in ~ExceptionMark().
>>>>> Call stack up to the THROWN_MSG() as follows:
>>>>> jvm.dll!ClassLoader::create_class_path_entry(char * path,
>>>>> stat st, ClassPathEntry * * new_entry, bool lazy) Line 508 C++
>>>>> jvm.dll!LazyClassPathEntry::resolve_entry() Line 303 + 0x24
>>>>> bytes C++
>>>>> > jvm.dll!LazyClassPathEntry::open_stream(const char * name)
>>>>> Line 322 + 0x8 bytes C++
>>>>> jvm.dll!ClassLoader::load_classfile(Symbol * h_name, Thread *
>>>>> __the_thread__) Line 900 + 0x17 bytes C++
>>>>> jvm.dll!SystemDictionary::load_instance_class(Symbol *
>>>>> class_name, Handle class_loader, Thread * __the_thread__) Line
>>>>> 1301 + 0x14 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_instance_class_or_null(Symbol *
>>>>> name, Handle class_loader, Handle protection_domain, Thread *
>>>>> __the_thread__) Line 779 + 0x18 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_or_null(Symbol *
>>>>> class_name, Handle class_loader, Handle protection_domain, Thread
>>>>> * __the_thread__) Line 232 + 0x15 bytes C++
>>>>> jvm.dll!SystemDictionary::resolve_or_null(Symbol *
>>>>> class_name, Thread * __the_thread__) Line 237 + 0x23 bytes C++
>>>>> jvm.dll!JVM_FindClassFromBootLoader(JNIEnv_ * env, const char
>>>>> * name) Line 773 + 0x12 bytes C++
>>>>> java.dll!69461e8c()
>>>>> [Frames below may be incorrect and/or missing, no symbols
>>>>> loaded for java.dll]
>>>>> jvm.dll!GrowableArray<Metadata *>::append(Metadata * const &
>>>>> elem) Line 207 C++
>>>>> jvm.dll!os::write_memory_serialize_page(JavaThread * thread)
>>>>> Line 375 + 0x11 bytes C++
>>>>> jvm.dll!InterfaceSupport::serialize_memory(JavaThread *
>>>>> thread) Line 40 + 0x9 bytes C++
>>>>>
>>>>> I'll try using TRAPS all the way through the call chain probably
>>>>> starting from ClassLoader::load_classfile().
>>>>>
>>>>> thanks,
>>>>> Calvin
>>>>>
>>>>> On 8/11/2013 10:40 PM, David Holmes wrote:
>>>>>> Hi Calvin,
>>>>>>
>>>>>> I don't think this works. As I said previously the expectations
>>>>>> of this code with regard to Java exceptions seems to be that it
>>>>>> doesn't expect them at all. If you are using TRAPS etc then it
>>>>>> should be used all the way through the call chain. What we have
>>>>>> now is this call sequence:
>>>>>>
>>>>>> void ClassLoader::initialize() {
>>>>>> assert(_package_hash_table == NULL, "should have been
>>>>>> initialized by now.");
>>>>>> EXCEPTION_MARK;
>>>>>> ...
>>>>>> setup_bootstrap_search_path();
>>>>>> -> update_class_path_entry_list(path, false);
>>>>>> -> create_class_path_entry((char *)path, st, &new_entry,
>>>>>> LazyBootClassLoader, CHECK);
>>>>>>
>>>>>> So if we return after the call to create_class_path_entry with an
>>>>>> exception pending we will crash when we hit the EXCEPTION_MARK.
>>>>>>
>>>>>> It may be that the EXCEPTION_MARK needs replacing with an
>>>>>> explicit exception check and a vm_exit_during_initialization, if
>>>>>> this exception can readily occur at runtime. But further analysis
>>>>>> of all this code needs to be undertaken.
>>>>>>
>>>>>> David
>>>>>> -----
>>>>>>
>>>>>> On 10/08/2013 8:11 AM, Calvin Cheung wrote:
>>>>>>> I've updated the webrev with 2 changes:
>>>>>>> 1) added the TRAPS as the last parameter to the
>>>>>>> create_class_path_entry() method;
>>>>>>> 2) added a jtreg test case.
>>>>>>>
>>>>>>> http://cr.openjdk.java.net/~ccheung/8020675/webrev/
>>>>>>>
>>>>>>> Please take a look again.
>>>>>>>
>>>>>>> One more response in-lined below...
>>>>>>>
>>>>>>> On 8/8/2013 4:11 PM, Ioi Lam wrote:
>>>>>>>> |I found one version of JDK7 that does not crash:||
>>>>>>>> ||
>>>>>>>> sc11136754 ~$
>>>>>>>> /net/jre.us.oracle.com/p/v31/jdk/7/all/b24/binaries/linux-amd64/bin/java
>>>>>>>>
>>>>>>>> -showversion -cp . -Xbootclasspath/a:foo.jar test2
>>>>>>>> Error occurred during initialization of VM
>>>>>>>> java/lang/ClassNotFoundException: error in opening JAR file
>>>>>>>> foo.jar
>>>>>>>> |
>>>>>>>
>>>>>>> |I noticed that it started breaking in 7u40 b01; it was still
>>>>>>> working
>>>>>>> with 7u25.
>>>>>>> It may have something to do with when the set_init_completed()
>>>>>>> is called:
>>>>>>> ExceptionMark::~ExceptionMark() {
>>>>>>> if (_thread->has_pending_exception()) {
>>>>>>> Handle exception(_thread, _thread->pending_exception());
>>>>>>> _thread->clear_pending_exception(); // Needed to avoid
>>>>>>> infinite
>>>>>>> recursion
>>>>>>> if (is_init_completed()) {
>>>>>>> exception->print();
>>>>>>> fatal("ExceptionMark destructor expects no pending
>>>>>>> exceptions");
>>>>>>> } else {
>>>>>>> vm_exit_during_initialization(exception);
>>>>>>> }
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> Before 7u40, I think the code path got to the "else" branch of
>>>>>>> ~ExceptionMark() and we just printed an error and exit.
>>>>>>>
>>>>>>> set_init_completed() is only called from Threads::create_vm()
>>>>>>> and that
>>>>>>> method didn't change much between 7u25 and 7u40 except for some NMT
>>>>>>> initialization - MemTracker::bootstrap_single_thread(),
>>>>>>> MemTracker::start(), etc. But I thought NMT isn't enabled by
>>>>>>> default?
>>>>>>>
>>>>>>> Debugging with hs25, the set_init_completed() always happened
>>>>>>> before
>>>>>>> create_class_path_entry() and both calls were done within the same
>>>>>>> thread - "vm startup".
>>>>>>>
>>>>>>> thanks,
>>>>>>> Calvin
>>>>>>>
>>>>>>>
>>>>>>> |
>>>>>>>> |||
>>>>>>>> ||
>>>>>>>> ||- Ioi
>>>>>>>> |
>>>>>>>> On 08/08/2013 02:26 PM, Ioi Lam wrote:
>>>>>>>>> |I found an official version that's closest to the Redhat version
>>>>>>>>> (OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode). It still
>>>>>>>>> crashes.||
>>>>>>>>> ||
>>>>>>>>> ||sc11136754 ~$
>>>>>>>>> /java/re/jdk/6_25/latest/binaries/linux-amd64/bin/java
>>>>>>>>> -showversion
>>>>>>>>> -cp . -Xbootclasspath/a:foo.jar test2||
>>>>>>>>> ||java version "1.6.0_25"||
>>>>>>>>> ||Java(TM) SE Runtime Environment (build 1.6.0_25-b06)||
>>>>>>>>> ||Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed
>>>>>>>>> mode)||
>>>>>>>>> ||
>>>>>>>>> ||java.lang.ClassNotFoundException ||
>>>>>>>>> || - klass: 'java/lang/ClassNotFoundException'||
>>>>>>>>> ||#||
>>>>>>>>> ||# A fatal error has been detected by the Java Runtime
>>>>>>>>> Environment:||
>>>>>>>>> ||#||
>>>>>>>>> ||# Internal Error (exceptions.cpp:397), pid=29955,
>>>>>>>>> tid=140608485558016||
>>>>>>>>> ||# fatal error: ExceptionMark destructor expects no pending
>>>>>>>>> exceptions||
>>>>>>>>> ||#||
>>>>>>>>> ||# JRE version: 6.0_25-b06||
>>>>>>>>> ||# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.0-b11 mixed
>>>>>>>>> mode
>>>>>>>>> linux-amd64 compressed oops)||
>>>>>>>>> ||# An error report file with more information is saved as:||
>>>>>>>>> ||# /home/iklam/hs_err_pid29955.log||
>>>>>>>>> ||#||
>>>>>>>>> ||# If you would like to submit a bug report, please visit:||
>>>>>>>>> ||# http://java.sun.com/webapps/bugreport/crash.jsp||
>>>>>>>>> ||#||
>>>>>>>>> ||Aborted (core dumped)||
>>>>>>>>> |
>>>>>>>>> - Ioi
>>>>>>>>>
>>>>>>>>> On 08/08/2013 02:18 PM, David Holmes wrote:
>>>>>>>>>> On 9/08/2013 4:52 AM, Ioi Lam wrote:
>>>>>>>>>>> |Hmmm, I used JDK6 from OEL 6.0 (derived from RedHat), which
>>>>>>>>>>> apparently
>>>>>>>>>>> works differently
>>>>>>>>>>> (better?) than the official JDK6 build. Maybe Redhat fixed
>>>>>>>>>>> this in
>>>>>>>>>>> their
>>>>>>>>>>> own repo??||
>>>>>>>>>>
>>>>>>>>>> Their hotspot version is much later - hs20 vs hs17
>>>>>>>>>>
>>>>>>>>>> David
>>>>>>>>>> -----
>>>>>>>>>>
>>>>>>>>>>> ||
>>>>>>>>>>> |
>>>>>>>>>>> |==OEL6================================================
>>>>>>>>>>> ||
>>>>>>>>>>> ||sc11136754 ~$ uname -a||
>>>>>>>>>>> ||Linux sc11136754 2.6.39-100.5.1.el6uek.x86_64 #1 SMP Tue
>>>>>>>>>>> Mar 6
>>>>>>>>>>> 20:26:00 EST 2012 x86_64 x86_64 x86_64 GNU/Linux||
>>>>>>>>>>> ||sc11136754 ~$ type java||
>>>>>>>>>>> ||java is hashed (/usr/bin/java)||
>>>>>>>>>>> ||sc11136754 ~$ java -version||
>>>>>>>>>>> ||java version "1.6.0_22"||
>>>>>>>>>>> ||OpenJDK Runtime Environment (IcedTea6 1.10.4)
>>>>>>>>>>> (rhel-1.41.1.10.4.el6-x86_64)||
>>>>>>>>>>> ||OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)||
>>>>>>>>>>> ||sc11136754 ~$ java -showversion -cp .
>>>>>>>>>>> -Xbootclasspath/a:foo.jar
>>>>>>>>>>> test2||
>>>>>>>>>>> ||Error occurred during initialization of VM||
>>>>>>>>>>> ||java/lang/ClassNotFoundException: error in opening JAR file
>>>>>>>>>>> foo.jar||
>>>>>>>>>>> ||
>>>>>>>>>>> ==OFFICIAL============================================
>>>>>>>>>>> ||
>>>>>>>>>>> sc11136754 ~$
>>>>>>>>>>> /java/re/jdk/6_22/latest/binaries/linux-amd64/bin/java
>>>>>>>>>>> -showversion -cp . -Xbootclasspath/a:foo.jar test2
>>>>>>>>>>> java version "1.6.0_22"
>>>>>>>>>>> Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
>>>>>>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)
>>>>>>>>>>>
>>>>>>>>>>> #
>>>>>>>>>>> # A fatal error has been detected by the Java Runtime
>>>>>>>>>>> Environment:
>>>>>>>>>>> #
>>>>>>>>>>> # Internal Error (exceptions.cpp:367), pid=25167,
>>>>>>>>>>> tid=140510319580928
>>>>>>>>>>> # Error: ExceptionMark destructor expects no pending
>>>>>>>>>>> exceptions
>>>>>>>>>>> #
>>>>>>>>>>> # JRE version: 6.0_22-b04
>>>>>>>>>>> # Java VM: Java HotSpot(TM) 64-Bit Server VM (17.1-b03 mixed
>>>>>>>>>>> mode
>>>>>>>>>>> linux-amd64 )
>>>>>>>>>>> # An error report file with more information is saved as:
>>>>>>>>>>> # /home/iklam/hs_err_pid25167.log
>>>>>>>>>>> #
>>>>>>>>>>> # If you would like to submit a bug report, please visit:
>>>>>>>>>>> # http://java.sun.com/webapps/bugreport/crash.jsp
>>>>>>>>>>> #
>>>>>>>>>>> |
>>>>>>>>>>> |======================================================
>>>>>>>>>>> ||
>>>>>>>>>>> ||- Ioi|
>>>>>>>>>>>
>>>>>>>>>>> On 08/08/2013 11:08 AM, Calvin Cheung wrote:
>>>>>>>>>>>> Hi Ioi, David,
>>>>>>>>>>>>
>>>>>>>>>>>> On 8/7/2013 7:15 PM, Ioi Lam wrote:
>>>>>>>>>>>>> |JDK6 seems to handle this better. I have written a simple
>>>>>>>>>>>>> stand-alone test case that doesn't require truncating JAR
>>>>>>>>>>>>> files in
>>>>>>>>>>>>> the JDK:||
>>>>>>>>>>>>> ||
>>>>>>>>>>>>> ||=========================||
>>>>>>>>>>>>> ||/*||
>>>>>>>>>>>>> ||javac test2.java||
>>>>>>>>>>>>> ||rm -f foo.jar||
>>>>>>>>>>>>> ||java -cp . -Xbootclasspath/a:foo.jar test2||
>>>>>>>>>>>>> ||touch foo.jar||
>>>>>>>>>>>>> ||java -cp . -Xbootclasspath/a:foo.jar test2||
>>>>>>>>>>>>> ||*/||
>>>>>>>>>>>>> ||
>>>>>>>>>>>>> ||public class test2 {||
>>>>>>>>>>>>> || public static void main(String args[]) {||
>>>>>>>>>>>>> || try {||
>>>>>>>>>>>>> ||System.out.println(Class.forName("javax.crypto.MacSpi"));||
>>>>>>>>>>>>> ||System.out.println(Class.forName("xxx"));||
>>>>>>>>>>>>> || } catch (Throwable t) {||
>>>>>>>>>>>>> || t.printStackTrace();||
>>>>>>>>>>>>> || }||
>>>>>>>>>>>>> || }||
>>>>>>>>>>>>> ||}||
>>>>>>>>>>>>> ||=========================||
>>>>>>>>>>>>> | |
>>>>>>>>>>>>> ||JDK6 works fine, but JDK7 would crash with the second
>>>>>>>>>>>>> "java -cp .
>>>>>>>>>>>>> -Xbootclasspath/a:foo.jar test2" command.||
>>>>>>>>>>>>> |
>>>>>>>>>>>> |I saw crash with the latest 6 update release with both
>>>>>>>>>>>> test cases.
>>>>>>>>>>>> The crash seems to be at the same spot.
>>>>>>>>>>>> |
>>>>>>>>>>>>> |||
>>>>>>>>>>>>> ||So I think the correct fix is to restore the JDK6
>>>>>>>>>>>>> behavior (not
>>>>>>>>>>>>> sure if it's already the same with your patch, but worth
>>>>>>>>>>>>> checking),
>>>>>>>>>>>>> and also add a new jtreg test into hotspot.||
>>>>>>>>>>>>> |
>>>>>>>>>>>> |I checked the jdk 6 code and those 3 methods which I
>>>>>>>>>>>> changed look
>>>>>>>>>>>> the
>>>>>>>>>>>> same as jdk 8.
>>>>>>>>>>>> Sure, I can add a jtreg test.
>>>>>>>>>>>> |
>>>>>>>>>>>>> |||
>>>>>>>>>>>>> ||Thanks||
>>>>>>>>>>>>> ||- Ioi||
>>>>>>>>>>>>> ||
>>>>>>>>>>>>> ||On 08/07/2013 06:47 PM, David Holmes wrote:||
>>>>>>>>>>>>> |
>>>>>>>>>>>>>> |Hi Calvin, ||
>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>> ||It seems to me that this code has a general problem with
>>>>>>>>>>>>>> exceptions. If exceptions can be posted then methods
>>>>>>>>>>>>>> should be
>>>>>>>>>>>>>> declared with a last parameter of TRAPS and called with a
>>>>>>>>>>>>>> CHECK_
>>>>>>>>>>>>>> macro. The way this code is written it does not seem to
>>>>>>>>>>>>>> expect any
>>>>>>>>>>>>>> exceptions to be possible. I would check with Karen on
>>>>>>>>>>>>>> this. ||
>>>>>>>>>>>>>> |
>>>>>>>>>>>> |I was thinking about that but that would involves a bit more
>>>>>>>>>>>> changes.
>>>>>>>>>>>> I can give it a try.
>>>>>>>>>>>> |
>>>>>>>>>>>>>> || |
>>>>>>>>>>>>>> ||This addition seems unused: ||
>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>> ||+ Thread* THREAD = thread; ||
>>>>>>>>>>>>>> |
>>>>>>>>>>>> |It is required for the THROW_MSG().
>>>>>>>>>>>> It won't be needed if the method is declared with TRAPS as
>>>>>>>>>>>> the last
>>>>>>>>>>>> parameter (I think).
>>>>>>>>>>>>
>>>>>>>>>>>> thanks,
>>>>>>>>>>>> Calvin
>>>>>>>>>>>> |
>>>>>>>>>>>>>> || |
>>>>>>>>>>>>>> ||Thumbs up on the removal of the EXCEPTION_MARKs prior
>>>>>>>>>>>>>> to throwing
>>>>>>>>>>>>>> exceptions - don't know what the thought process was
>>>>>>>>>>>>>> there :) ||
>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>> ||David ||
>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>> ||On 8/08/2013 10:25 AM, Calvin Cheung wrote: ||
>>>>>>>>>>>>>> |
>>>>>>>>>>>>>>> |Please review this small fix for fixing a fatal error
>>>>>>>>>>>>>>> in ||
>>>>>>>>>>>>>>> ||~ExceptionMark() triggered by ClassNotFoundException
>>>>>>>>>>>>>>> in ||
>>>>>>>>>>>>>>> ||ClassLoader::create_class_path_entry(). I could reproduce
>>>>>>>>>>>>>>> similar
>>>>>>>>>>>>>>> crash ||
>>>>>>>>>>>>>>> ||by trying to load a class from an empty jar which is
>>>>>>>>>>>>>>> in the ||
>>>>>>>>>>>>>>> ||bootclasspath. The following program can trigger the
>>>>>>>>>>>>>>> crash if
>>>>>>>>>>>>>>> the ||
>>>>>>>>>>>>>>> ||jce.jar is invalid (e.g. 0-byte): ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||public class TestForName { ||
>>>>>>>>>>>>>>> || public static void main(String[] args) { ||
>>>>>>>>>>>>>>> || try { ||
>>>>>>>>>>>>>>> || Class cls =
>>>>>>>>>>>>>>> Class.forName("javax.crypto.KeyGenerator"); ||
>>>>>>>>>>>>>>> || System.out.println("Class = " + cls.getName()); ||
>>>>>>>>>>>>>>> || } catch (ClassNotFoundException cnfe) { ||
>>>>>>>>>>>>>>> || cnfe.printStackTrace(); ||
>>>>>>>>>>>>>>> || } ||
>>>>>>>>>>>>>>> || } ||
>>>>>>>>>>>>>>> ||} ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||The fix also changes the assert() in
>>>>>>>>>>>>>>> LazyClassPathEntry::resolve_entry() ||
>>>>>>>>>>>>>>> ||to a NULL check. Otherwise, the assert() will fail
>>>>>>>>>>>>>>> under the
>>>>>>>>>>>>>>> above test ||
>>>>>>>>>>>>>>> ||scenario. ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||With the fix, the following ClassNotFoundException
>>>>>>>>>>>>>>> will be
>>>>>>>>>>>>>>> thrown ||
>>>>>>>>>>>>>>> ||instead of a crash: ||
>>>>>>>>>>>>>>> ||java.lang.ClassNotFoundException:
>>>>>>>>>>>>>>> javax.crypto.KeyGenerator ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.net.URLClassLoader$1.run(URLClassLoader.java:365) ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.net.URLClassLoader$1.run(URLClassLoader.java:354) ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.security.AccessController.doPrivileged(Native
>>>>>>>>>>>>>>> Method) ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.net.URLClassLoader.findClass(URLClassLoader.java:353)
>>>>>>>>>>>>>>> ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.lang.ClassLoader.loadClass(ClassLoader.java:423) ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
>>>>>>>>>>>>>>> ||
>>>>>>>>>>>>>>> || at
>>>>>>>>>>>>>>> java.lang.ClassLoader.loadClass(ClassLoader.java:356) ||
>>>>>>>>>>>>>>> || at java.lang.Class.forName0(Native Method) ||
>>>>>>>>>>>>>>> || at java.lang.Class.forName(Class.java:258) ||
>>>>>>>>>>>>>>> || at TestForName.main(TestForName.java:6) ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||webrev:
>>>>>>>>>>>>>>> http://cr.openjdk.java.net/~ccheung/8020675/webrev/ ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||JBS: https://jbs.oracle.com/bugs/browse/JDK-8020675 ||
>>>>>>>>>>>>>>> ||bug: http://bugs.sun.com/view_bug.do?bug_id=8020675 ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||Tests: ||
>>>>>>>>>>>>>>> || jprt, vm.quick.testlist ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> ||thanks, ||
>>>>>>>>>>>>>>> ||Calvin ||
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> | |
>>>>>>>>>>>>>>> |
>>>>>>>>>>>>> |
>>>>>>>>>>>>> |
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>
>>>>
>>>
>>
>
More information about the hotspot-runtime-dev
mailing list