java - NoClassDefFoundError sometimes for a standard class after System.out.close() -


my java program mysteriously crashes due noclassdeffounderror. mystery exception message indicates problematic class java/util/concurrent/copyonwritearraylist$cowiterator, part of jre. exception thrown after other jre classes have been loaded without problems.

the exception thrown logback (version 1.1.3), seemingly when iterating through list of appenders write (i guess uses copyonwritearraylist hold list of appenders):

thread [main] (suspended (exception noclassdeffounderror))   copyonwritearraylist<e>.iterator() line: 959     appenderattachableimpl<e>.appendlooponappenders(e) line: 47  logger.appendlooponappenders(iloggingevent) line: 273    logger.callappenders(iloggingevent) line: 260    logger.buildloggingeventandappend(string, marker, level, string, object[], throwable) line: 442  logger.filterandlog_0_or3plus(string, marker, level, string, object[], throwable) line: 396  logger.info(string) line: 600    myprogramtextlogger.logstarting() line: 303  myprogram.run() line: 1686   myprogram.runprogram(myprogram) line: 790    myprogram.main(string[]) line: 712   

of course, logback code must have loaded copyonwritearraylist class when created list trying iterate over, classloader must have done job @ point.

to further add mystery problem not occur if run program in foreground, or daemon process controlled systemd. manifests when run program child of daemon process started systemd.

experimentation (by using static code block) showed main thread classloader load copyonwritearraylist$cowiterator class ok on program start (the program throws noclassdeffounderror different jre class). it's if classloader had decided lose ability load classes.

i not pass special arguments java program. have used full path-name java option , provided -showversion option ensure using same jvm , jre each time. command-line simply:

 /usr/bin/java \  -showversion \  -jar /home/myuser/lib/my-app.jar --1 --latest 

java reports version be

 java version "1.7.0_75"  openjdk runtime environment (rhel-2.5.4.2.el7_0-x86_64 u75-b13)  openjdk 64-bit server vm (build 24.75-b04, mixed mode) 

my program not explicit class loading, nor have custom class loader: uses default class loader. however, bkail has pointed out should not matter if did, because java platform classes should loaded boot class loader rather application class loader.

at point program fails code has not created threads. code not include native code, , no "external" threads confuse things. believe logback creates threads, however, , of course there normal java daemon threads.

and mysterious aspect. in between creating logback logger (using org.slf4j.loggerfactory.getlogger(myprogram.class)) , calling logger.info(string) method results in exception, application close standard input, standard output , standard error output streams, using call method:

 private static void closesystemstreams() {     try {        system.in.close();     } catch (ioexception e) {        // nothing; should never happen, , there nothing can if        //     }     system.out.close();     system.err.close();  } 

if omit closing code, program runs ok. now, can understand closing streams might fail in circumstances (and some recommend against it), why should interfere bootstrap class loader?

what have ensure logback or jvm not have these kinds of classloading problems?

it seems of java library code gets confused if standard streams closed. perhaps there hard coded check of value of file descriptor somewhere. might or might not bug, depending on how generously interpret behaviour. seem safest not close standard streams.


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -