JBUG Milan: first meeting will focus on AS7

We (alessio and me) are going to have a speech on AS7 during the first JBUG Milan’s meeting next 20 Septmber.

If you are around Milan join us it will be a lot of fun. For your convenience I have pasted here the full agenda, but don’t forget to visit the official group and sign in for partecipation.

9.30: Welcome coffee
9.45: Welcome and first infos about JBUG
10.15: JBoss AS7
11.00: Coffee Break
11.15: JBoss AS7 and webservices
12.00: JBoss in cloud with OpenShift
12.45: Closing
13.00: luch
14:00: Hacking AS7

And don’t miss the hacking party we will have in the afternoon: Alessio and me will be in the public area of Red Hat office working on JBoss AS7, and would be cool to have you hacking with us. Don’t leave your laptop at home, join the community and send your first patch in that afternoon.

 

And now, for our italian reader, for this italian event…the post in italian language:

Alessio ed io faremo due presentazioni su AS7 durante il primo meeting del JBUG di Milano il prossimo 20 Settembre.

Se passte da Milano, non perdetevi l’evento, ci divertiremo. Per vostra comodità riporto qui l’agenda definitiva dell’incontro, ma non scordatevi di fare un giro sul gruppo ufficiale del JBUG ed iscrivetevi all’evento mandando la mail come indicato in uno dei messaggi.

9.30: Welcome coffee
9.45: Benvenuto e prime informazioni sul JBUG
10.15: JBoss AS7
11.00: Coffee Break
11.15: JBoss AS7 e i webservices
12.00: JBoss in cloud con OpenShift
12.45: Closing
13.00: Pranzo a buffet
14:00: Sviluppo di AS7

E mi raccomando, non perdetevi l’hacking su AS7 nel pomeriggio. Io ed Alessio ci fermeremo in area pubblica dell’ufficio Red Hat di Milano a lavorare su JBoss AS7. E sarebbe bello sviluppare insieme a voi. Non dimenticatevi il computer , partecipate alla community mandando il pomeriggio stesso la vostra prima patch ;)

 

See you there!

Ci vediamo li!

How to create and manage datasources in AS7

In this post I’ll try to describe how to add and configure datasources in AS7, and related concepts like add/configure jdbc drivers and test connection of a created datasource.

As you probably already know AS7 has been announced by Red Hat officialy here. I’ll not go in deep details of what is new, cool and fast in AS7. Just have a look to the announce page to get a bird eye view of all the cool stuffs you can find there.
Before start with main contets about data source I just want to recall you 2 main concept in AS7 we will have to deal with in this article:

  1. Modular core: JBoss Modules offers true application isolation, hiding server implementation classes and only loads the classes your application needs. Class loading is concurrent for extreme performance. OSGi support is available the moment you install the application server. We will learn in this article to create a new module for new jdbc drivers, and we compare this approach to hot deployed driver analyzing plus and minus of each.
  2. Elegant administration Consistent and powerful management is available, ranging from a polished, user-friendly web console to Java and HTTP APIs to a command line tool to direct XML edits. Configuration data is centralized and user-focused. We will learn in this artcile how to add and manage datasources with all three approaches.
  3. Domain management JBoss AS 7 can be launched in two different modes. Domain mode allows you to run and manage a multi-server topology. Standalone mode runs a single server instance, a convenience choice for development. Many settings, such as port offsets and network interfaces, can be controlled with a single attribute. Rolling deployments are available. In this article we will discuss how to add and manage datasources in both mode, providing sample for both too. Domain mode is one of the main new concept and coolest feature to learn about AS7. If you want more info read documentation about this concepts here.

Read the rest of this entry »

Chasing reason for a deadlock in JDK

Last week I spent a couple of days on a strange deadlock issue revealed during JBossWS testsuite runs on my Husdon QA environment.

This kind of issues usually pops up through a test / section of the software that simply hangs without no evident reason. You don’t get continuous integration results for a day or such, then wonder what’s happening, go and check Hudson and start thinking and asking yourself what might have gone bad. In my case it was really “asking yourself” as of course this happened exactly when I was back from a vacation week and my colleagues that were working on the project were not online ;-)   (to be honest at the end it turned out not to be their fault at all)

OK, so you start by getting a thread dump to confirm you’re seeing a deadlock; that’s a simple “kill -3 pid” when running on Linux. Here is mine:

[junit] Found one Java-level deadlock:
[junit] =============================
[junit] "pool-1-thread-1":
[junit]   waiting to lock monitor 0x000000005d2c60c0 (object 0x00002aaadfb10fd8,
                                          a sun.net.www.protocol.file.Handler),
[junit]   which is held by "main"
[junit] "main":
[junit]   waiting to lock monitor 0x000000005cb02a58 (object 0x00002aaadfb10e38,
                                          a sun.misc.Launcher$AppClassLoader),
[junit]   which is held by "pool-1-thread-1"
[junit]
[junit] Java stack information for the threads listed above:
[junit] ===================================================
[junit] "pool-1-thread-1":
[junit] 	at java.net.URLStreamHandler.getHostAddress(URLStreamHandler.java:412)
[junit] 	- waiting to lock <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
[junit] 	at java.net.URLStreamHandler.hostsEqual(URLStreamHandler.java:439)
[junit] 	at sun.net.www.protocol.file.Handler.hostsEqual(Handler.java:117)
[junit] 	at java.net.URLStreamHandler.sameFile(URLStreamHandler.java:396)
[junit] 	at java.net.URLStreamHandler.equals(URLStreamHandler.java:316)
[junit] 	at java.net.URL.equals(URL.java:842)
[junit] 	at java.security.CodeSource.equals(CodeSource.java:135)
[junit] 	at java.util.HashMap.get(HashMap.java:305)
[junit] 	at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:233)
[junit] 	- locked <0x00002aaadfb11120> (a java.util.HashMap)
[junit] 	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
[junit] 	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
[junit] 	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
[junit] 	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
[junit] 	at java.security.AccessController.doPrivileged(Native Method)
[junit] 	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
[junit] 	- locked <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
[junit] 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[junit] 	- locked <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
[junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
[junit] 	at org.xnio.nio.AbstractNioChannelThread.cancelKey(AbstractNioChannelThread.java:298)
[junit] 	at org.xnio.nio.NioHandle.cancelKey(NioHandle.java:56)
[junit] 	at org.xnio.nio.AbstractNioStreamChannel.cancelWriteKey(AbstractNioStreamChannel.java:241)
[junit] 	at org.xnio.nio.NioTcpChannel.shutdownWrites(NioTcpChannel.java:164)
[junit] 	at org.xnio.channels.TranslatingSuspendableChannel.shutdownWrites(TranslatingSuspendableChannel.java:358)
[junit] 	at org.xnio.channels.FramedMessageChannel.shutdownWrites(FramedMessageChannel.java:255)
[junit] 	- locked <0x00002aaadfb11978> (a org.xnio.ByteBufferSlicePool$PooledByteBuffer)
[junit] 	at org.jboss.remoting3.remote.RemoteConnection$RemoteWriteListener.send(RemoteConnection.java:267)
[junit] 	- locked <0x00002aaadfb119a0> (a org.jboss.remoting3.remote.RemoteConnection)
[junit] 	at org.jboss.remoting3.remote.RemoteConnection.sendCloseRequest(RemoteConnection.java:164)
[junit] 	at org.jboss.remoting3.remote.RemoteConnection.handleOutboundCloseRequest(RemoteConnection.java:149)
[junit] 	at org.jboss.remoting3.remote.RemoteConnectionHandler.closeAction(RemoteConnectionHandler.java:173)
[junit] 	at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:354)
[junit] 	at org.jboss.remoting3.ConnectionImpl.closeAction(ConnectionImpl.java:48)
[junit] 	at org.jboss.remoting3.spi.AbstractHandleableCloseable.close(AbstractHandleableCloseable.java:149)
[junit] 	at org.xnio.IoUtils.safeClose(IoUtils.java:134)
[junit] 	at org.jboss.as.protocol.ProtocolChannelClient.close(ProtocolChannelClient.java:176)
[junit] 	at org.xnio.IoUtils.safeClose(IoUtils.java:134)
[junit] 	at org.jboss.as.protocol.mgmt.ManagementClientChannelStrategy$Establishing.requestDone(ManagementClientChannelStrategy.java:138)
[junit] 	at org.jboss.as.protocol.mgmt.ManagementRequest$DelegatingResponseHandler.readResponse(ManagementRequest.java:178)
[junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel$ResponseReceiver.handleResponse(ManagementChannel.java:375)
[junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel$ResponseReceiver.access$400(ManagementChannel.java:357)
[junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel.doHandle(ManagementChannel.java:120)
[junit] 	at org.jboss.as.protocol.ProtocolChannel.handleMessage(ProtocolChannel.java:158)
[junit] 	at org.jboss.remoting3.remote.RemoteConnectionChannel$4.run(RemoteConnectionChannel.java:224)
[junit] 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[junit] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[junit] 	at java.lang.Thread.run(Thread.java:619)
[junit] "main":
[junit] 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:293)
[junit] 	- waiting to lock <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
[junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
[junit] 	at java.net.URL.getURLStreamHandler(URL.java:1144)
[junit] 	at java.net.URL.<init>(URL.java:393)
[junit] 	at java.net.URL.<init>(URL.java:283)
[junit] 	at java.net.URL.<init>(URL.java:306)
[junit] 	at sun.net.www.protocol.file.Handler.openConnection(Handler.java:74)
[junit] 	- locked <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
[junit] 	at sun.net.www.protocol.file.Handler.openConnection(Handler.java:55)
[junit] 	- locked <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
[junit] 	at java.net.URL.openConnection(URL.java:945)
[junit] 	at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:66)
[junit] 	at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
[junit] 	at java.net.URL.openConnection(URL.java:945)
[junit] 	at org.apache.cxf.common.logging.JDKBugHacks.doHacks(JDKBugHacks.java:67)
[junit] 	at org.apache.cxf.common.logging.LogUtils.<clinit>(LogUtils.java:66)
[junit] 	at org.apache.cxf.jaxws.spi.ProviderImpl.<clinit>(ProviderImpl.java:61)
[junit] 	at java.lang.Class.forName0(Native Method)
[junit] 	at java.lang.Class.forName(Class.java:247)
[junit] 	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:345)
[junit] 	at java.util.ServiceLoader$1.next(ServiceLoader.java:421)
[junit] 	at javax.xml.ws.spi.Provider.getProviderUsingServiceLoader(Provider.java:146)
[junit] 	at javax.xml.ws.spi.Provider.provider(Provider.java:106)
[junit] 	at javax.xml.ws.Service.<init>(Service.java:57)
[junit] 	at javax.xml.ws.Service.create(Service.java:687)
[junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionEJB3Helper.getProxy(ExceptionEJB3Helper.java:48)
[junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionHelper.testRuntimeException(ExceptionHelper.java:81)
[junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionTestCase.testRuntimeException(ExceptionTestCase.java:45)
[junit] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[junit] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[junit] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[junit] 	at java.lang.reflect.Method.invoke(Method.java:597)
[junit] 	at junit.framework.TestCase.runTest(TestCase.java:154)
[junit] 	at junit.framework.TestCase.runBare(TestCase.java:127)
[junit] 	at junit.framework.TestResult$1.protect(TestResult.java:106)
[junit] 	at junit.framework.TestResult.runProtected(TestResult.java:124)
[junit] 	at junit.framework.TestResult.run(TestResult.java:109)
[junit] 	at junit.framework.TestCase.run(TestCase.java:118)
[junit] 	at junit.framework.TestSuite.runTest(TestSuite.java:208)
[junit] 	at junit.framework.TestSuite.run(TestSuite.java:203)
[junit] 	at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
[junit] 	at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
[junit] 	at junit.framework.TestResult.runProtected(TestResult.java:124)
[junit] 	at junit.extensions.TestSetup.run(TestSetup.java:23)
[junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:420)
[junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:911)
[junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:768)
[junit]
[junit] Found 1 deadlock.

Confirmed, it was really a deadlock. Not a straightforward one to solve, at least to me, given the blocking part were a bit deep into the JDK (1.6) sources.

A bit of background on what’s been developed here and which are the game “players”: JBossWS provides and integration layer for running Apache CXF on top of JBoss Application Server. The testcase being executed above (in thread “main”) is a simple standard JAX-WS client application that creates a java.xml.ws.Service instance for consuming an endpoint that’s deployed on JBoss AS. The “pool-1-thread-1″ thread should instead be spawned by the remote deployment request that’s issued by the testsuite to deploy a WS endpoint jar archive on JBoss AS before actually running the client test.

The problem was not easily and consistently reproducible locally, so I used a debugger to force the “evil” timing that causes the deadlock: you set a breakpoint on the code executed by both threads above, before each of them goes through one of the “- locked <…>” points. Then have each of them acquire the first lock and you’re done, sure deadlock when each thread later wants the other lock.

So, carefully analysing the problem I understood what was really happening. The deadlock above is between the system classloader and sun.net.www.protocol.file.Handler, due to their synchronized Classloader::loadClass() and Handler::openConnection()/Handler::getHostAddress() methods. During initialization, Apache CXF performs some hacks, including disabling url caching; to achieve that, it opens a new connection as JDK does not have a static method for setting that, despite the flag being actually static. The process of opening a connection goes through the Handler’s synchronized openConnection() method and in there ends up needing the system classloader for loading a class. Unfortunately, the lock on the system classloader might be taken by another thread invoking the synchronized loadClass() on it and also needing to use the CodeSource for locating the class to be loaded. That eventually ends up in needing the URLStreamHandler / Handler for comparing URL instances.

URLStreamHandler? For those not having experience here, Java comes with a configurable architecture for resolving URLs. Simplifying things a lot, the URLStreamHandler is created using the specified URLStreamHandlerFactory, which can be configured setting the java.protocol.handler.pkgs system property. Why is this relevant here? Basically because JBoss needs and uses this mechanism for installing his own handler to deal with vfs URLs. Looking at the code for the configured factory, the returned handler is basically a singleton. Hence the deadlock, regardless of the vfs-aware handler not being needed here.

How to solve the issue? While it might be arguable whether having singleton protocol handler is a good choice or not, I couldn’t change that quickly and easily, as it was “out of my area of action”. I ended up changing the Apache CXF code after having had a chat with Dan Kulp (CXF project lead): instead of actually opening a connection to get an handle to a URLConnection instance for the sake of disabling URL caching, we now simply create a concrete extension of the abstract URLConnection that is only used for setting the static member through its setDefaultUseCaches() non-static method.

The fix is effective for the specific issue I had and in general for reducing the chances of running into deadlock because of Apache CXF. However, few considerations / caveats are still valid:

  • be careful when designing and providing your own protocol handlers, as that can have really unexpected side effects
  • opening a connection can be time consuming even before URLConnection::connect() due to all the locking that’s required in there; obviously another reason for checking twice if you really need opening a connection before actually doing that
  • is JDK really well designed here? (non-static URLConnection.setDefaultUseCaches(..))

It’s been a nice debugging in any case :-)

[junit] Found one Java-level deadlock:
    [junit] =============================
    [junit] "pool-1-thread-1":
    [junit]   waiting to lock monitor 0x000000005d2c60c0 (object 0x00002aaadfb10fd8, a sun.net.www.protocol.file.Handler),
    [junit]   which is held by "main"
    [junit] "main":
    [junit]   waiting to lock monitor 0x000000005cb02a58 (object 0x00002aaadfb10e38, a sun.misc.Launcher$AppClassLoader),
    [junit]   which is held by "pool-1-thread-1"
    [junit]
    [junit] Java stack information for the threads listed above:
    [junit] ===================================================
    [junit] "pool-1-thread-1":
    [junit] 	at java.net.URLStreamHandler.getHostAddress(URLStreamHandler.java:412)
    [junit] 	- waiting to lock <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
    [junit] 	at java.net.URLStreamHandler.hostsEqual(URLStreamHandler.java:439)
    [junit] 	at sun.net.www.protocol.file.Handler.hostsEqual(Handler.java:117)
    [junit] 	at java.net.URLStreamHandler.sameFile(URLStreamHandler.java:396)
    [junit] 	at java.net.URLStreamHandler.equals(URLStreamHandler.java:316)
    [junit] 	at java.net.URL.equals(URL.java:842)
    [junit] 	at java.security.CodeSource.equals(CodeSource.java:135)
    [junit] 	at java.util.HashMap.get(HashMap.java:305)
    [junit] 	at java.security.SecureClassLoader.getProtectionDomain(SecureClassLoader.java:233)
    [junit] 	- locked <0x00002aaadfb11120> (a java.util.HashMap)
    [junit] 	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    [junit] 	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    [junit] 	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    [junit] 	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    [junit] 	at java.security.AccessController.doPrivileged(Native Method)
    [junit] 	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    [junit] 	- locked <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
    [junit] 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    [junit] 	- locked <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
    [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    [junit] 	at org.xnio.nio.AbstractNioChannelThread.cancelKey(AbstractNioChannelThread.java:298)
    [junit] 	at org.xnio.nio.NioHandle.cancelKey(NioHandle.java:56)
    [junit] 	at org.xnio.nio.AbstractNioStreamChannel.cancelWriteKey(AbstractNioStreamChannel.java:241)
    [junit] 	at org.xnio.nio.NioTcpChannel.shutdownWrites(NioTcpChannel.java:164)
    [junit] 	at org.xnio.channels.TranslatingSuspendableChannel.shutdownWrites(TranslatingSuspendableChannel.java:358)
    [junit] 	at org.xnio.channels.FramedMessageChannel.shutdownWrites(FramedMessageChannel.java:255)
    [junit] 	- locked <0x00002aaadfb11978> (a org.xnio.ByteBufferSlicePool$PooledByteBuffer)
    [junit] 	at org.jboss.remoting3.remote.RemoteConnection$RemoteWriteListener.send(RemoteConnection.java:267)
    [junit] 	- locked <0x00002aaadfb119a0> (a org.jboss.remoting3.remote.RemoteConnection)
    [junit] 	at org.jboss.remoting3.remote.RemoteConnection.sendCloseRequest(RemoteConnection.java:164)
    [junit] 	at org.jboss.remoting3.remote.RemoteConnection.handleOutboundCloseRequest(RemoteConnection.java:149)
    [junit] 	at org.jboss.remoting3.remote.RemoteConnectionHandler.closeAction(RemoteConnectionHandler.java:173)
    [junit] 	at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:354)
    [junit] 	at org.jboss.remoting3.ConnectionImpl.closeAction(ConnectionImpl.java:48)
    [junit] 	at org.jboss.remoting3.spi.AbstractHandleableCloseable.close(AbstractHandleableCloseable.java:149)
    [junit] 	at org.xnio.IoUtils.safeClose(IoUtils.java:134)
    [junit] 	at org.jboss.as.protocol.ProtocolChannelClient.close(ProtocolChannelClient.java:176)
    [junit] 	at org.xnio.IoUtils.safeClose(IoUtils.java:134)
    [junit] 	at org.jboss.as.protocol.mgmt.ManagementClientChannelStrategy$Establishing.requestDone(ManagementClientChannelStrategy.java:138)
    [junit] 	at org.jboss.as.protocol.mgmt.ManagementRequest$DelegatingResponseHandler.readResponse(ManagementRequest.java:178)
    [junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel$ResponseReceiver.handleResponse(ManagementChannel.java:375)
    [junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel$ResponseReceiver.access$400(ManagementChannel.java:357)
    [junit] 	at org.jboss.as.protocol.mgmt.ManagementChannel.doHandle(ManagementChannel.java:120)
    [junit] 	at org.jboss.as.protocol.ProtocolChannel.handleMessage(ProtocolChannel.java:158)
    [junit] 	at org.jboss.remoting3.remote.RemoteConnectionChannel$4.run(RemoteConnectionChannel.java:224)
    [junit] 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    [junit] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    [junit] 	at java.lang.Thread.run(Thread.java:619)
    [junit] "main":
    [junit] 	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:293)
    [junit] 	- waiting to lock <0x00002aaadfb10e38> (a sun.misc.Launcher$AppClassLoader)
    [junit] 	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    [junit] 	at java.net.URL.getURLStreamHandler(URL.java:1144)
    [junit] 	at java.net.URL.<init>(URL.java:393)
    [junit] 	at java.net.URL.<init>(URL.java:283)
    [junit] 	at java.net.URL.<init>(URL.java:306)
    [junit] 	at sun.net.www.protocol.file.Handler.openConnection(Handler.java:74)
    [junit] 	- locked <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
    [junit] 	at sun.net.www.protocol.file.Handler.openConnection(Handler.java:55)
    [junit] 	- locked <0x00002aaadfb10fd8> (a sun.net.www.protocol.file.Handler)
    [junit] 	at java.net.URL.openConnection(URL.java:945)
    [junit] 	at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:66)
    [junit] 	at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:24)
    [junit] 	at java.net.URL.openConnection(URL.java:945)
    [junit] 	at org.apache.cxf.common.logging.JDKBugHacks.doHacks(JDKBugHacks.java:67)
    [junit] 	at org.apache.cxf.common.logging.LogUtils.<clinit>(LogUtils.java:66)
    [junit] 	at org.apache.cxf.jaxws.spi.ProviderImpl.<clinit>(ProviderImpl.java:61)
    [junit] 	at java.lang.Class.forName0(Native Method)
    [junit] 	at java.lang.Class.forName(Class.java:247)
    [junit] 	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:345)
    [junit] 	at java.util.ServiceLoader$1.next(ServiceLoader.java:421)
    [junit] 	at javax.xml.ws.spi.Provider.getProviderUsingServiceLoader(Provider.java:146)
    [junit] 	at javax.xml.ws.spi.Provider.provider(Provider.java:106)
    [junit] 	at javax.xml.ws.Service.<init>(Service.java:57)
    [junit] 	at javax.xml.ws.Service.create(Service.java:687)
    [junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionEJB3Helper.getProxy(ExceptionEJB3Helper.java:48)
    [junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionHelper.testRuntimeException(ExceptionHelper.java:81)
    [junit] 	at org.jboss.test.ws.jaxws.samples.exception.ExceptionTestCase.testRuntimeException(ExceptionTestCase.java:45)
    [junit] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    [junit] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    [junit] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    [junit] 	at java.lang.reflect.Method.invoke(Method.java:597)
    [junit] 	at junit.framework.TestCase.runTest(TestCase.java:154)
    [junit] 	at junit.framework.TestCase.runBare(TestCase.java:127)
    [junit] 	at junit.framework.TestResult$1.protect(TestResult.java:106)
    [junit] 	at junit.framework.TestResult.runProtected(TestResult.java:124)
    [junit] 	at junit.framework.TestResult.run(TestResult.java:109)
    [junit] 	at junit.framework.TestCase.run(TestCase.java:118)
    [junit] 	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    [junit] 	at junit.framework.TestSuite.run(TestSuite.java:203)
    [junit] 	at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
    [junit] 	at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
    [junit] 	at junit.framework.TestResult.runProtected(TestResult.java:124)
    [junit] 	at junit.extensions.TestSetup.run(TestSetup.java:23)
    [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:420)
    [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:911)
    [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:768)
    [junit]
    [junit] Found 1 deadlock.

JBossWS 2010 closing balance… an year of integration

Before joining Red Hat / JBoss, I used to have closing balance face to face meetings at work before Christmas. Of course I met with my direct boss… so now I find quite funny to think about writing something similar to a JBossWS 2010 closing balance here, given my boss at that time now happens to be the guy I share this blog with and since some months he’s finally working for Red Hat / JBoss too – Stefano ;-)

So, what’s up with JBossWS in 2010 ? The project has gone through two major sets of releases. The 3.3.x series kind of finalized the JBossWS move to having the Apache CXF based stack as its preferred one, installed by default on JBoss Application server. Integrating a third-party piece of software is always something non-trivial. And even if the overall quality of what we consume (and contribute to, of course) from Apache is definitely very high, that’s simply not enough when it comes to integrating: many issues were discovered, dealt with and solved… any many are probably still to come.

The type of development you end up doing when providing a solution like JBossWS-CXF is pretty much different from what you are on when developing stuff from scratch. I kind of expected that to be honest. It’s not that unusual to spend days on looking for the best way of re-using / integrating already existing (or partially available) functionalities, trying to figure out an elegant solution for achieving the goal on JBoss side, while enriching the third-party side of the software in a way that makes sense regardless of JBoss needs. Sometime I think it’s like “plumbing”. For sure you need to go on constantly swapping your hats, the JBoss employee one and the Apache contributor one, in my case. And given we operate in an open source world here :-) … you might even find yourself producing fully vendor agnostic solutions just for the sake of solving your own (JBoss here) problem.

Some might dislike this kind of work, thinking satisfaction can come only from creating your own solutions from scratch, feeling they’re your own babies. Others might appreciate the integration work, enjoying the  new challenges in this. To be honest, I think this is a really subjective feeling and you can find yourself excited by the achievements you reach in both cases. You should probably try both in any case.

Anyway, back to bringing Apache CXF in JBoss through JBossWS… implementing the JSR 109 requirements is a good example of integration. Apache CXF provides WS functionalities and successfully verifies those are compliant with the core JCP WS specifications (JSR 224 – JAXWS, for instance). However CXF of course does not care about all the details on how that’s supposed to work with a given application server according to the rest of the JavaEE specification, which JSR 109 is a good example of. In an ideal world the missing bits need to live in the integration project (JBossWS here)… In reality you end up coordinating different needs, reviewing and rationalizing stuff on both sides, to basically make the integration happen and be a success.

The second set of JBossWS 2010 releases has been the 3.4.x series. While the announcement is recent story, that was a multiple months effort from me and the rest of the team. We went through active collaboration on CXF (Apache contributor hat on ;-) ) to have it implement JAXWS 2.2 and make it pass the TCK certifaction testsuite for that. While on that, we implemented the proper integration for passing the corresponding ws modules of JavaEE 6 TCK on JBoss side (with *the* red hat on ;-) ). This all was done while directly targeting development snapshots of Apache CXF, hence with multiple moving targets (JBoss AS, Apache CXF, our own JBossWS integration layer and even the TCK which was not final yet) to track for potential regressions.

At the end of the year I’m quite satisfied by what we got. From a job point of view, I’m just waiting for Santa to come with a nice present… a final release of JBoss AS 6 (I sent him the jbossws maven artifacts to include in the box ;-) , he should have got them in time… despite the snow over north Italy these days).

OK, now it’s time to start relaxing a bit, to enjoy the Christmas spirit…  then I’ll come back with new intentions for the next year, both directly related to JBossWS and not

Merry X-mas and happy new year!