Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4868493

(thread spec) Clarify semantics of thread "context class loaders"

    Details

    • Subcomponent:
    • Understanding:
      Fix Understood
    • CPU:
      x86
    • OS:
      windows_2000

      Description

      Name: nt126004 Date: 05/22/2003


      FULL PRODUCT VERSION :
      C:\jdk1.4.0\bin>java -version
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

      FULL OS VERSION :
      Microsoft Windows 2000 [Version 5.00.2195]

      A DESCRIPTION OF THE PROBLEM :
      settings a ClassLoader to a Thread doesn't work !

      I have an object called 'AnObject' which is *not* part of the application classpath , i am trying to access this object via a thread which i customized
      to use a specific ClassLoader,ClassLoader which *does* include this object.

      What i found is :
      1 - in the thread , using 'new AnObject()' ends with NoClassDefFoundError.
      2 - in the thread , using Class.forName() to load the AnObject Class ends with
          ClassNotFoundException.
      3 - in the thread , when using Class.forName() with the context ClassLoader ,
          the AnObject class is finnaly avaiable.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The source code contains 2 files :

      1 - ThreadContextClassLoaderTester
      2 - AnObject

      Run the ThreadContextClassLoaderTester and follow the popup dialogs.

      Note :
      1 - When compiling the ThreadContextClassLoaderTester , the AnObject class
      should be in the classpath , *BUT* when running it shouldn't be in the
      classpath , therefor before running make sure you remove the AnObject.class
      from the classpath.
      2 - ThreadContextClassLoaderTester takes as argument a dir which contains
      the AnObject.class


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect that the JVM will use the thread context ClassLoader making
      new AnObject() , Class.forName() avaiable.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      //
      // save in 2 public classes , 2 java files :
      // 1 - ThreadContextClassLoaderTester
      // 2 - AnObject
      //

      import java.io.*;
      import java.net.*;
      import javax.swing.*;
      import java.lang.reflect.*;

      /** This tests the Thread Context ClassLoader , it attached
      * a ClassLoader ,with a classpath to the 'AnObject' class , to an
      * executing Thread which tries to access the 'AnObject' class
      * (which is *not* on the application classpath.)
      *
      */
      public class ThreadContextClassLoaderTester {

      public static void main(String args[]) throws MalformedURLException {
      if (args == null || args.length == 0) {
      System.err.println( "Usage : ThreadContextClassLoaderTester <dir>\n"
      +"where dir is the directory which contains the "
      +"'AnObject' class , this dir should *not* be in "
      +"the classpath.");
      System.exit(0);
      }
      new ThreadContextClassLoaderTester().run(args[0]);
      }//main

      public void run(String dirWithResourcesNotInClassPath)
      throws MalformedURLException {

      try {
      new AnObject();
      JOptionPane.showMessageDialog(null,"The 'AnObject' class is on "
      +"your classpath remove it from the classpath.");
      System.exit(1);
      } catch (Throwable e) {
      if (e instanceof NoClassDefFoundError) {
      //its ok , AnObject is not on classpath
      }
      }

      //create the thread classloader
      File dir = new File(dirWithResourcesNotInClassPath);
      URL[] urls = new URL[] {dir.toURL()};
      URLClassLoader threadCL = URLClassLoader.newInstance(urls,null);

      Thread t = new Thread() {
      public void run() {
      //test if the JVM uses the thread classloader when using the new
      //keyword
      JOptionPane.showMessageDialog(null,"Press to test if the JVM "
                           +"is using the Thread Context ClassLoader on new() ...");

      try {
      new AnObject();
      } catch (Throwable e) {
      if (e instanceof NoClassDefFoundError) {
      JOptionPane.showMessageDialog(null,"The 'AnObject'"
      +" class wasn't found on by the thread class loader!");
      }
      }

      //test if the JVM uses the thread classloader when using
                      // Class.forName
      JOptionPane.showMessageDialog(null,"Press to test if the JVM is"
      +" using the Thread Context ClassLoader on "
                                  +"Class.forName() ...");
      try {
      Class clazz = Class.forName("AnObject");
      Object o = clazz.newInstance();
      Method m = clazz.getMethod("echo",null);
      m.invoke(o,null);
      System.exit(1);
      } catch (ClassNotFoundException e) {
      JOptionPane.showMessageDialog(null,"The 'AnObject' class "
      +"wasn't found on by the thread class loader!");
      } catch (Exception e) {
      e.printStackTrace();
      }

      //try using the thread classloader directly
      JOptionPane.showMessageDialog(null,"Press to test when "
      +"explicitly using the Thread Context ClassLoader on"
                                 +" Class.forName() ...");
      try {
      Class clazz = Class.forName("AnObject",true
      ,Thread.currentThread().getContextClassLoader());
      Object o = clazz.newInstance();
      Method m = clazz.getMethod("echo",null);
      m.invoke(o,null);
      System.exit(1);
      } catch (ClassNotFoundException e) {
      JOptionPane.showMessageDialog(null,"The 'AnObject' class"
      +" wasn't found on by the thread class loader!");
      } catch (Exception e) {
      e.printStackTrace();
      }
      }//run
      };

      t.setContextClassLoader(threadCL);
      t.start();

      try {
      t.join();
      } catch (InterruptedException e) {
      }

      System.exit(0);
      }//main
      }//class






      public class AnObject {
      public void echo() {
      javax.swing.JOptionPane.showMessageDialog(null,"This is hello from AnObject :-)");
      }
      }//class
      ---------- END SOURCE ----------
      (Review ID: 185788)
      ======================================================================

        Attachments

          Activity

            People

            • Assignee:
              chegar Chris Hegarty
              Reporter:
              nthompsosunw Nathanael Thompson (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Imported:
                Indexed: