Workaround for JAX-WS NullPointerException when calling web service from embedded Java 8 JVM

[Note: I originally posted this solution to Stackoverflow.com]

Problem:

When connecting to a SOAP based web service from a Java 8 embedded JVM using JAX-WS dynamic generation of the client stubs, you get this NullPointerException:

If your problem is the same as mine, you will also have the symptom that this problem did not occur under Java 6, but now all of a sudden is happening under Java 8.

Solution:

For me, the main conditions under which this problem occurs is:

  1. Java 8 running as an embedded JVM via jvm.dll from within a Windows program. I tried to reproduce the problem running in a standalone Java 8 JVM and I couldn’t get it to happen. Running standalone was very helpful in diagnosing the problem, however.
  2. Using the proxy method of initializing the connection to a JAX-WS web service, which dynamically creates the stub on the client side using the WSDL hosted on the server side.

Workaround:

When you invoke the call to Service.getPort(Class<T>) it needs to be done in its own thread, separate from the thread you had the call running in previously. What this allows for you is an opportunity to set the ClassLoader on that thread to a ClassLoader that is not the bootstrap classloader, which is the crux of the problem in ClientContainer.java (more explanation on that below). Here is some sample code that is working for me. You will have to modify it to suit your needs.

Additional Background and Details:

The difficulty in diagnosing this for me was that the problem only occurred inside of a Windows product which launches an embedded JVM. Without remote debugging on that JVM, it would have taken much longer to get to the bottom of the problem. Once I saw that 1) when I ran the same code which invokes the call to Service.getPort(Class<T>) inside of a standalone JVM (outside of the Windows product) and, 2) that the ClientContainer class was able to get the current thread’s ClassLoader and, 3) that the ClassLoader returned wasn’t the bootstrap ClassLoader (i.e., not null), it made me realize that I had to find a way to ensure that the thread that the ClientContainer was running in would not get the bootstrap ClassLoader. The goal then became to see if I could find a way to alter the ClassLoader resolved by the ClientContainercode.

ClientContainer source: click to view

Notice in the ClientContainer source that there are two attempts to resolve a classloader. The problem is that if both of those attempts return the bootstrap classloader, a NullPointerException will result on line 45 since cl will be null:

This workaround ensures that the classloader resolved by the ClientContainer code will be the classloader that you set on your thread.

I’ve filed a ticket for the JAX-WS team to investigate the problem here: https://java.net/jira/browse/JAX_WS-1178

This entry was posted in Java and tagged , , , , , , . Bookmark the permalink.

2 Responses to "Workaround for JAX-WS NullPointerException when calling web service from embedded Java 8 JVM"

Leave a Reply