rilian-la-te/java-swing-ayatana

NPE in new JTextPane() when running with JAyatany (caused by Thred.getContextClassLoader() returning null)

GoogleCodeExporter opened this issue · 3 comments

What steps will reproduce the problem?
1. Compile attached file to a class file
2. make sure is set to 
JAVA_TOOL_OPTIONS="-javaagent:/usr/share/java/jayatanaag.jar"
2. Start by running "java bugs.NpeInJTextPaneInit"
3. Open a random file by selecting "File/Open" from the menu

What is the expected output? What do you see instead?
   The expected output is none. However, if jayatana is used, I get an NPE most of the cases (might have to try several times to reproduce. Be sure to end the program and start a new instance for each try). See attached output for details.

What version of the product are you using? On what operating system?

  axel@kotak:~$ uname -a
  Linux kotak 3.19.0-16-generic #16-Ubuntu SMP Thu Apr 30 16:09:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
  axel@kotak:~$ java -version
  Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 
  openjdk version "1.8.0_45-internal"
  OpenJDK Runtime Environment (build 1.8.0_45-internal-b14)
  OpenJDK 64-Bit Server VM (build 25.45-b02, mixed mode)
  axel@kotak:~$ javac -version
  Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 
  javac 1.8.0_45-internal
  axel@kotak:~$ dpkg -s jayatana | grep Version
  Version: 2.7-0ubuntu3

Please provide any additional information below.

I looked at the stack trace and found that the NPE is caused by 
Thread.currentThread().getContextClassLoader(). Here is the relevant part of 
the stack trace with the actual line marked by "-->":

java.util.Hashtable.put(Hashtable.java:459)
        // Make sure the value is not null
        if (value == null) {
-->         throw new NullPointerException();
        }

javax.swing.JEditorPane.registerEditorKitForContentType(JEditorPane.java:1247)
    public static void registerEditorKitForContentType(String type, String classname, ClassLoader loader) {
        getKitTypeRegistry().put(type, classname);
-->     getKitLoaderRegistry().put(type, loader);
        getKitRegisty().remove(type);
    }

javax.swing.JEditorPane.registerEditorKitForContentType(JEditorPane.java:1229)
    public static void registerEditorKitForContentType(String type, String classname) {
-->     registerEditorKitForContentType(type, classname,Thread.currentThread().
                                        getContextClassLoader());
    }

The code for Thred.getContextClassLoader() is this:
    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                                                   Reflection.getCallerClass());
        }
        return contextClassLoader;
    }

The member contextClassLoader is private in Thread, so can only be set from 
within the class itself, in this case that means either 
Thread.setContextClassLoader() or Thread.init(). Don't know how to go on from 
here...

Original issue reported on code.google.com by mailxze...@gmail.com on 14 May 2015 at 12:57

Attachments:

This a very strange

Original comment by danjaredg on 8 Jun 2015 at 3:10

  • Changed state: Started
Can you help me test the correction?

Execute the next commands to try.

sudo apt-get install libglib2.0-dev libxt-dev libdbusmenu-glib-dev 
openjdk-7-jdk ant
svn checkout -r 277 http://java-swing-ayatana.googlecode.com/svn/branches/2.0 
/tmp/jayatana/
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
cd /tmp/jayatana/libjayatanaag ; make BUILD=debug
cd /tmp/jayatana/libjayatana ; make BUILD=debug
cd /tmp/jayatana/jayatanaag ; make
cd /tmp/jayatana/jayatana ; make
export 
JAVA_TOOL_OPTIONS=-javaagent:/tmp/jayatana/jayatanaag/target/jayatanaag.jar
export JAYATANA_LIBAGPATH=/tmp/jayatana/libjayatanaag/libjayatanaag.so
export JAYATANA_NATIVEPATH=/tmp/jayatana/libjayatana/libjayatana.so
export JAYATANA_JAVAPATH=/tmp/jayatana/jayatana/target/jayatana.jar

unset JAVA_HOME
export PATH=/usr/lib/jvm/java-8-openjdk-amd64/bin:$PATH


Then try any java swing application

Original comment by danjaredg on 8 Jun 2015 at 5:32

Ok, I built the library and tried to reproduce like this:
1) I tried several times without resetting the JAVA_TOOL_OPTIONS etc. The 
exception came in about 10% of runs.
2) I reset JAVA_TOOL_OPTIONS etc as you explained and tried again. I could not 
reproduce the exception.

So it seems like it works.

But one more remark: You said "try any java swing application". That's not 
enough. I never got the exception when running netbeans. I first observed it in 
an application I wrote myself and found out that it only happened when the file 
dialog was shown before any instance of JEditorPane was used. If I started my 
application with a command line argument to load a document on startup, the 
exception was never thrown - even if I opened another document afterwards. The 
attached file is the simplest thing I could create to reproduce the problem. So 
it seems to be a very special case. However I hope this is fixed now.

Thanks for your quick response and your work on jayatana.

Original comment by mailxze...@gmail.com on 11 Jun 2015 at 9:33