dynamically test jar availability?


    Jul 12 2006 | 3:07 am
    I have an mxj external that links against the apache commons net library. things work great when the jar file is present in the classpath, everything load and runs nicely. if I remove it from the path, max bombs when I try to load my object. I tried to safety-check it with the following code:
    try { Class.forName("org.apache.commons.net.telnet.TelnetClient"); } catch (ClassNotFoundException ex) { bail("commons net lib not found"); } // ok to use the loaded class tc = new TelnetClient();
    but the bail doesn't seem to be effective. if I duplicate that code into a command-line test project, the jvm doesn't lock up. if I comment out the new TelnetClient() completely, max still bombs. I guess because I've got a class variable that references it? I haven't tried stripping all that out as well, as that would break the object beyond usefulness.
    any ideas or suggestions?
    console.log:
    Exception in thread "AWT-AppKit" Exception in thread "AWT-AppKit" Exception in thread "AWT-AppKit" Jul 11 01:45:24 thrustty /Volumes/ userdata/apps/audio/MaxMSP 4.5/MaxMSP 4.5.app: An unexpected Java error has been detected by HotSpot Virtual Machine. Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: If this error is reproducible, please report it with the following information: Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: 1. Provide the steps to reproduce, a test case, and any relevant information Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: 2. The corresponding JavaNativeCrash_pid.crash.log (Java state) Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: 3. The corresponding .crash.log (native state; generated by CrashReporter) Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: 4. This data: Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: Java VM: Java HotSpot(TM) Client VM (1.5.0_06-57 mixed mode) Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: Bus Error (0xa) at pc=0x05225c14 Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: Process ID: 1050, Current Thread: 25492480 Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: File report at: http://bugreport.apple.com/ Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: An error report file has been written to: Jul 11 01:45:24 thrustty /Volumes/userdata/apps/audio/MaxMSP 4.5/ MaxMSP 4.5.app: /Volumes/userdata/users/thrust/Library/Logs/Java/ JavaNativeCrash_pid1050.crash.log Jul 11 01:45:30 thrustty crashdump[1059]: MaxMSP 4.5.app crashed Jul 11 01:45:31 thrustty crashdump[1059]: crash report written to: / Volumes/userdata/users/thrust/Library/Logs/CrashReporter/MaxMSP 4.5.app.crash.log ...
    JavaNativeCrash_pid1050.crash.log
    Local Time = Tue Jul 11 01:45:24 2006
    # This JavaNativeCrash log describes the Java state at a Native Crash in a Java application. # The corresponding native state can be found in the crash log generated by CrashReporter.
    # If this error is reproducible, please report it with the following information: # 1. Provide the steps to reproduce, a test case, and any relevant information # 2. This JavaNativeCrash_pid.crash.log (Java state) # 3. The corresponding .crash.log (native state; generated by CrashReporter) # File report at: http://bugreport.apple.com/
    # An unexpected Java error has been detected by HotSpot Virtual Machine: # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-57 mixed mode) # # Bus Error (0xa) at pc=0x05225c14, pid=1050, tid=25492480
    --------------- T H R E A D ---------------
    Current thread (0x053014e0): JavaThread "AWT- AppKit" [_thread_in_native, id=-1610551912]
    Stack: [0xbf800000,0xc0000000)
    --------------- P R O C E S S ---------------
    Java Threads: ( => current thread ) 0x0530d700 JavaThread "AWT-Shutdown" [_thread_blocked, id=25537024] 0x0530a7c0 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=25849344] 0x05309e80 JavaThread "CompilerThread0" daemon [_thread_blocked, id=25860608] 0x053099e0 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=25859584] 0x05309710 JavaThread "Surrogate Locker Thread (CMS)" daemon [_thread_blocked, id=25866240] 0x05308da0 JavaThread "Finalizer" daemon [_thread_blocked, id=25864192] 0x053089c0 JavaThread "Reference Handler" daemon [_thread_blocked, id=25858560] =>0x053014e0 JavaThread "AWT-AppKit" [_thread_in_native, id=-1610551912]
    Other Threads: 0x053081d0 VMThread [id=25539072] 0x0530be80 WatcherThread [id=25850368]
    VM state:not at safepoint (normal execution)
    VM Mutex/Monitor currently owned by a thread: None
    Heap def new generation total 4032K, used 1268K [0x099e0000, 0x09de0000, 0x09de0000) eden space 3968K, 31% used [0x099e0000, 0x09b1d3b8, 0x09dc0000) from space 64K, 0% used [0x09dd0000, 0x09dd0000, 0x09de0000) to space 64K, 0% used [0x09dc0000, 0x09dc0000, 0x09dd0000) concurrent mark-sweep generation total 12288K, used 265K [0x09de0000, 0x0a9e0000, 0x199e0000) concurrent-mark-sweep perm gen total 8192K, used 2748K [0x199e0000, 0x1a1e0000, 0x1d9e0000)
    Dynamic libraries and executable: [0x000019e0-0x000027f8] /System/Library/Frameworks/Carbon.framework/ Versions/A/Support/LaunchCFMApp [0x908dbe74-0x908dbf44] /System/Library/Frameworks/ CoreServices.framework/Versions/A/CoreServices [0x92f02e68-0x92f02f38] /System/Library/Frameworks/Carbon.framework/ Versions/A/Carbon [0x947353a0-0x94962c40] /System/Library/Frameworks/ QuickTime.framework/Versions/A/QuickTime ...
    max crash log:
    Host Name: thrustty Date/Time: 2006-07-11 01:45:24.504 -0300 OS Version: 10.4.7 (Build 8J135) Report Version: 4
    Command: MaxMSP 4.5.app Path: /Volumes/userdata/apps/audio/MaxMSP 4.5/MaxMSP 4.5.app Parent: WindowServer [66]
    Version: 4.5.6 (4.5.6 - 27 October 2005)
    PID: 1050 Thread: 0
    Exception: EXC_BAD_ACCESS (0x0001) Codes: KERN_PROTECTION_FAILURE (0x0002) at 0x00000010
    Thread 0 Crashed: 0 mxj[ 0x05225c14 construct + 256 1 mxj[ 0x0522526c maxjava_new + 1368 2 MaxPPC3.1pwpc 0x00436e00 typedmess_fun + 152 3 MaxPPC3.1pwpc 0x005355a4 object_new_typed + 164 4 MaxPPC3.1pwpc 0x00429738 auxtable_search + 156 5 MaxPPC3.1pwpc 0x0042bc54 newload_internal + 64 6 MaxPPC3.1pwpc 0x0042bbc8 newload + 52 7 MaxPPC3.1pwpc 0x00436e00 typedmess_fun + 152 8 MaxPPC3.1pwpc 0x00436ae8 typedmess + 92 9 MaxPPC3.1pwpc 0x00438088 aeval + 1264 10 MaxPPC3.1pwpc 0x0040bfe0 atombuf_eval + 156 11 MaxPPC3.1pwpc 0x004d6708 patcher_vnewex + 160 12 MaxPPC3.1pwpc 0x00436e30 typedmess_fun + 200 13 MaxPPC3.1pwpc 0x00436ae8 typedmess + 92 14 MaxPPC3.1pwpc 0x00438088 aeval + 1264 15 MaxPPC3.1pwpc 0x004109d8 bf_fastload + 692 16 MaxPPC3.1pwpc 0x0042a940 lowload_type__FPcslsP4atoms + 500 17 MaxPPC3.1pwpc 0x0042b414 fileload_extended + 176 18 MaxPPC3.1pwpc 0x0042b330 fileload_type + 68 19 MaxPPC3.1pwpc 0x0042ae60 dropload + 404 20 MaxPPC3.1pwpc 0x00409a90 ae_openfile__FP6FSSpec + 28 21 MaxPPC3.1pwpc 0x004ecdb4 sysiac_iterate + 264 22 MaxPPC3.1pwpc 0x00409c4c ae_docopen + 44 23 com.apple.AE 0x914f8960 aeDispatchAppleEvent (AEDesc const*, AEDesc*, unsigned long, unsigned char*) + 208 24 com.apple.AE 0x914f87fc dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 44 25 com.apple.AE 0x914f8654 aeProcessAppleEvent + 284 26 com.apple.HIToolbox 0x931e8eb0 AEProcessAppleEvent + 60 27 com.apple.HIToolbox 0x9322cb24 ProcessHighLevelEvent + 140 28 com.apple.HIToolbox 0x9322ca7c StandardApplicationEventHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 328 29 com.apple.HIToolbox 0x931e5554 DispatchEventToHandlers (EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 692 30 com.apple.HIToolbox 0x931e4cac SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 372 31 com.apple.HIToolbox 0x931e4b28 SendEventToEventTargetWithOptions + 40 32 com.apple.HIToolbox 0x931ebe9c ToolboxEventDispatcherHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) + 704 33 com.apple.HIToolbox 0x931e57a4 DispatchEventToHandlers (EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) + 1284 34 com.apple.HIToolbox 0x931e4cac SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) + 372 35 com.apple.HIToolbox 0x931eba60 SendEventToEventTarget + 40 36 com.apple.HIToolbox 0x9322c7a0 ToolboxEventDispatcher + 92 37 com.apple.HIToolbox 0x9322c72c HLTBEventDispatcher + 16 38 com.apple.HIToolbox 0x9322ace4 RunApplicationEventLoop + 148 39 MaxPPC3.1pwpc 0x0042d4fc app_run + 48 40 MaxPPC3.1pwpc 0x0042c2e0 main + 796 ...

    • Jul 12 2006 | 10:18 am
      On 12 Jul 2006, at 05:07, ritchie wrote:
      > if I remove it from the path, max bombs when I try to load my object.
      For what it's worth, it looks like a fault in the JVM, not in Max. Your code looks fine... However, perhaps you're getting the wrong class loader? MXJClassLoader.getInstance() will get you a/the MXJ class loader (although I thought there were two: one static, one dynamic?).
      nick rothwell -- composition, systems, performance -- http:// www.cassiel.com
    • Jul 12 2006 | 4:09 pm
      On 06-07-12, at 0718, Nick Rothwell wrote: > > For what it's worth, it looks like a fault in the JVM, not in Max. > Your code looks fine... However, perhaps you're getting the wrong > class loader? MXJClassLoader.getInstance() will get you a/the MXJ > class loader (although I thought there were two: one static, one > dynamic?). > ok, I've narrowed it down a little. using MXJClassLoader.getInstance ().getClazz() behaves the same as Class.forName() - it detects that the class isn't present. the problem seems to be how threading is handled, though I'm not sure I fully understand it. I've included code for a minimal test case.
      compile all three files, and run TestLoader from the commandline and TestMaxLoader from max. you can send "test" to the mxj object if you like, it doesn't really matter. then quit max and delete MissingClass.class, and re-run the above test. when you try to instantiate [mxj TestMaxLoader] max bombs, you don't even get a chance to press 'test'. running at the command line doesn't crash at all, and the thread prints out "no class found" as expected.
      given that things work fine outside max, I'm a little suspicious that this problem is entirely within the jvm, but I will gather up the crashlogs and send them in to apple. if you can't reproduce the problem I can send crashlogs to the list as well. I'm running os10.4.7, max4.5.7 and java1.5.0_06 on ppc.
      // TestMaxLoader.java import com.cycling74.max.MaxObject;
      public class TestMaxLoader extends MaxObject { private volatile MissingClass mc = null;
      public TestMaxLoader() { System.out.println("searching for MissingClass"); try { Class.forName("MissingClass"); } catch (ClassNotFoundException ex) { System.out.println("MissingClass not found"); return; } // use the loaded class mc = new MissingClass(); }
      public void test() { new Thread() { public void run() { try { System.out.println("the class says: " + mc.test()); } catch (NoClassDefFoundError e) { System.out.println("no class found"); } } }.start(); } }
      // TestLoader.java public class TestLoader { private volatile MissingClass mc = null;
      public TestLoader() { System.out.println("searching for MissingClass"); try { Class.forName("MissingClass"); } catch (ClassNotFoundException ex) { System.out.println("MissingClass not found"); return; } // use the loaded class mc = new MissingClass(); }
      public void test() { new Thread() { public void run() { try { System.out.println("the class says: " + mc.test()); } catch (NoClassDefFoundError e) { System.out.println("no class found"); } } }.start(); }
      public static void main(String args[]) { TestLoader tr = new TestLoader(); tr.test(); } }
      // MissingClass.java public class MissingClass { public String test() { return "it works!"; } }
    • Jul 12 2006 | 5:35 pm
      On 06-07-12, at 1309, ritchie wrote: > > given that things work fine outside max, I'm a little suspicious > that this problem is entirely within the jvm, but I will gather up > the crashlogs and send them in to apple. if you can't reproduce the > problem I can send crashlogs to the list as well. I'm running > os10.4.7, max4.5.7 and java1.5.0_06 on ppc. > little more: it bombs max4.5.7 on windows xp running java1.5.0_07, and max4.6b11 with java1.5.0_06 on os10.4.7.
      the command-line test app also works fine on windows.
      best regards, r.
    • Jul 12 2006 | 6:55 pm
      Ill look into this today and see if I can reproduce and further enlighten. topher
      On Jul 12, 2006, at 09:09 AM, ritchie wrote:
      > On 06-07-12, at 0718, Nick Rothwell wrote: >> >> For what it's worth, it looks like a fault in the JVM, not in Max. >> Your code looks fine... However, perhaps you're getting the wrong >> class loader? MXJClassLoader.getInstance() will get you a/the MXJ >> class loader (although I thought there were two: one static, one >> dynamic?). >> > ok, I've narrowed it down a little. using MXJClassLoader.getInstance > ().getClazz() behaves the same as Class.forName() - it detects that > the class isn't present. the problem seems to be how threading is > handled, though I'm not sure I fully understand it. I've included > code for a minimal test case. > > compile all three files, and run TestLoader from the commandline > and TestMaxLoader from max. you can send "test" to the mxj object > if you like, it doesn't really matter. then quit max and delete > MissingClass.class, and re-run the above test. when you try to > instantiate [mxj TestMaxLoader] max bombs, you don't even get a > chance to press 'test'. running at the command line doesn't crash > at all, and the thread prints out "no class found" as expected. > > given that things work fine outside max, I'm a little suspicious > that this problem is entirely within the jvm, but I will gather up > the crashlogs and send them in to apple. if you can't reproduce the > problem I can send crashlogs to the list as well. I'm running > os10.4.7, max4.5.7 and java1.5.0_06 on ppc. > > // TestMaxLoader.java > import com.cycling74.max.MaxObject; > > public class TestMaxLoader extends MaxObject { > private volatile MissingClass mc = null; > > public TestMaxLoader() { > System.out.println("searching for MissingClass"); > try { > Class.forName("MissingClass"); > } catch (ClassNotFoundException ex) { > System.out.println("MissingClass not found"); > return; > } > // use the loaded class > mc = new MissingClass(); > } > > public void test() { > new Thread() { > public void run() { > try { > System.out.println("the class says: " + mc.test()); > } catch (NoClassDefFoundError e) { > System.out.println("no class found"); > } > } > }.start(); > } > } > > > // TestLoader.java > public class TestLoader { > private volatile MissingClass mc = null; > > public TestLoader() { > System.out.println("searching for MissingClass"); > try { > Class.forName("MissingClass"); > } catch (ClassNotFoundException ex) { > System.out.println("MissingClass not found"); > return; > } > // use the loaded class > mc = new MissingClass(); > } > > public void test() { > new Thread() { > public void run() { > try { > System.out.println("the class says: " + mc.test()); > } catch (NoClassDefFoundError e) { > System.out.println("no class found"); > } > } > }.start(); > } > > public static void main(String args[]) { > TestLoader tr = new TestLoader(); > tr.test(); > } > } > > > // MissingClass.java > public class MissingClass { > public String test() { > return "it works!"; > } > } >
    • Jul 14 2006 | 2:00 pm
      On 06-07-12, at 1557, topher lafata wrote: > Ill look into this today and see if I can reproduce and further > enlighten. > hey topher, it looks like it's choking on anonymous inner classes. if I re-write so it doesn't generate a TestMaxLoader$1.class file, things work ok. uncomment the anonymous thread and it crashes. I presume this doesn't have anything to do with threading, and the test case can likely be shrunk to just use anonymous inner classes.
      best, r.
      // TestMaxLoader.java import com.cycling74.max.MaxObject;
      public class TestMaxLoader extends MaxObject implements Runnable { private MissingClass mc = null;
      public TestMaxLoader() { System.out.println("searching for MissingClass"); try { Class.forName("MissingClass"); } catch (ClassNotFoundException ex) { System.out.println("MissingClass not found"); return; } // use the loaded class mc = new MissingClass(); }
      public void test() { // new Thread() { // public void run() { // try { // System.out.println("anon.run(): " + mc.test()); // } catch (NoClassDefFoundError e) { // System.out.println("anon.run(): no class found"); // } // } // }.start();
      new Thread(this).start(); }
      public void run() { try { System.out.println("TestMaxLoader.run(): " + mc.test()); } catch (NoClassDefFoundError e) { System.out.println("TestMaxLoader.run(): no class found"); } } }
    • Jul 14 2006 | 8:06 pm
      I have been looking into it as well and something weird is definitely going on. I havent been able to pinpoint it yet. Thanks for the additional info. Topher
      On Jul 14, 2006, at 07:00 AM, ritchie wrote:
      > On 06-07-12, at 1557, topher lafata wrote: >> Ill look into this today and see if I can reproduce and further >> enlighten. >> > hey topher, it looks like it's choking on anonymous inner classes. > if I re-write so it doesn't generate a TestMaxLoader$1.class file, > things work ok. uncomment the anonymous thread and it crashes. I > presume this doesn't have anything to do with threading, and the > test case can likely be shrunk to just use anonymous inner classes. > > best, > r. > > > > // TestMaxLoader.java > import com.cycling74.max.MaxObject; > > public class TestMaxLoader extends MaxObject implements Runnable { > private MissingClass mc = null; > > public TestMaxLoader() { > System.out.println("searching for MissingClass"); > try { > Class.forName("MissingClass"); > } catch (ClassNotFoundException ex) { > System.out.println("MissingClass not found"); > return; > } > // use the loaded class > mc = new MissingClass(); > } > > public void test() { > // new Thread() { > // public void run() { > // try { > // System.out.println("anon.run(): " + mc.test()); > // } catch (NoClassDefFoundError e) { > // System.out.println("anon.run(): no class found"); > // } > // } > // }.start(); > > new Thread(this).start(); > } > > public void run() { > try { > System.out.println("TestMaxLoader.run(): " + mc.test()); > } catch (NoClassDefFoundError e) { > System.out.println("TestMaxLoader.run(): no class found"); > } > } > } >