Workaround for WAS NoClassDefFoundError with JAX-WS

If you have to use IBM’s JDK with WebSphere Application Server and like to unit test web services outside of the container, you may encounter:


java.lang.NoClassDefFoundError: com.ibm.ffdc.Manager
  at com.ibm.ws.ffdc.FFDCFilter.processException(FFDCFilter.java:82)
  at com.ibm.ws.webservices.engine.components.logger.LogFactory$2.run(LogFactory.java:159)
  at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:63)
  at com.ibm.ws.webservices.engine.components.logger.LogFactory.createLogFactory(LogFactory.java:141)
  at com.ibm.ws.webservices.engine.components.logger.LogFactory.(LogFactory.java:98)
  at java.lang.J9VMInternals.initializeImpl(Native Method)
  at java.lang.J9VMInternals.initialize(J9VMInternals.java:205)
  at com.ibm.ws.webservices.engine.soap.MessageFactoryImpl.(MessageFactoryImpl.java:103)

What is that? A quick search indicates that the server administration client jar is missing from the classpath, but why would I need that? I just want to publish a simple JAX-WS web service.

Fortunately there is a workaround. Set a system property:


  System.setProperty("javax.xml.soap.MetaFactory",
    "com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl");

This forces the use of Sun’s web service stack and the problem is gone. When the code runs in the container the classes are available and in this way we can get the unit tests to work.

Categories: Java

Basic authentication with JAX-WS in Java SE

With JAX-WS web services it is common to use preemptive basic authentication. It is also common to test the services stand-alone using the built-in support in Java SE. Unfortunately that makes it hard to test the authentication and no principal will be available on the server side. What to do?

It turns out that it is fairly easy to enable authentication after all. I found this example from 2007. In short the endpoint is published using Sun’s built-in web server.

This publishes the web service ExampleWebService on a random port with a hard-coded user and password:


HttpServer webServer = HttpServer.create(new InetSocketAddress(0), 1);
webServer.start();
HttpContext context = webServer.createContext("/");
context.setAuthenticator(new BasicAuthenticator("ExampleRealm") {
  public boolean checkCredentials(String username, String password) {
    return "testuser".equals(username) && "testpassword".equals(password);
  }
});
Endpoint endpoint = Endpoint.create(new ExampleWebService());
endpoint.publish(context);

Don’t forget to stop the web server after the test. Sun’s web server may not always be available in production, but it is most likely there in the unit test environment.

Categories: Java

Java EE two-factor authentication with Yubikey

Tonight I’m giving a presentation at JavaForum in Gothenburg on two-factor authentication in Java with Yubikey. The talk will introduce multi-factor authentication in general and Yubikey in particular; then it shows how to add Yubikey support to several types of Java web applications. It starts out with a simple servlet filter and proceeds with JAAS modules, a JASPIC (JSR-196) module and Apache Shiro.

More details can be found here. The code is available on Github.

Categories: Java

Zoom in and out in Eclipse

Do you use Eclipse for presentations? In that case I bet you want to zoom in and out in order to handle different resolutions. That feature is not built in. I found a good answer at StackExchange.

In short, select "Help/Install New Software" and add http://eclipse-fonts.googlecode.com/svn/trunk/FontsUpdate/ as a site to "Work with". Pick the FontsFeature and install it. There should be two toolbar buttons for zooming in and out and the keyboard shortcuts Ctrl+- and Ctrl+= can be used as well, unless Eclipse has reserved them for something else.

Categories: Java

JMeter with Graphite

JMeter, probably the most popular open-source tool for load testing, can now report test results to Graphite! The Graphite listener is not part of the latest release (2.12), but it is included in the nightly build and it works quite well. It can report summary statistics for the entire test run or statistics for specific samplers with successes and failure counts, percentiles and so on. Highly recommended, in particular if the system under test also reports statistics to Graphite!

Categories: Performance

Improve logging performance with Log4j

Log4j 1.2 is old, but still in very wide use. It works and for most applications performance is good enough. For log-intensive applications there are some tricks. The AsyncAppender can act as a buffer between the application and slower loggers (including FileAppender in some cases – be sure to use a large buffer though!), but that only helps for short bursts.

The FileAppender itself and its subclasses can work in buffered or immediate mode. Buffered mode is enabled with the BufferedIO parameter. When true the appender uses an 8k buffer and flushes the entire buffer to disk when it is full. This is much faster than the default operation, which flushes immediately for every log event. The disadvantage is that log entries are delayed and unless the appender is closed cleanly (a problem with most applications I’ve seen) many log events may be lost.

I have written a flush appender that can help. It can flush the file appenders when an event with high severity is logged (ensuring that errors are written to disk immediately). It can also flush and convert the file appenders to immediate mode when a specific message is logged, for example “Shutting down…”. That way no messages are lost during the shutdown process. The appender is available from Github and Maven Central (name.wramner.log4j:FlushAppender).

Categories: Java

Materialize hint required for complex SELECT in 12c

During migration from Oracle 11gR2 to 12c we encountered a weird error. We had a very complex select, that used WITH clauses, some with GROUP BY. It works in 11g, but with 12c it fails with:


ORA-00979: not a GROUP BY expression

Apparently something has changed. We have not yet found the root cause of the issue, but if we add /*+ materialize */ to the selects in the WITH clauses it works!

If the query is simplified a bit the hint is not required, even though it still has the same GROUP BY clauses. Smells like a bug.

EDIT: reported to Oracle as Bug 20887136 – ORA-00979 AFTER UPGRADE TO 12.1.0.2.

Categories: Oracle
Follow

Get every new post delivered to your Inbox.