I am using Logback to do most of my logging. I am using a third party library for some computation. Luckily the library uses slf4j, meaning it’s agnostic of the logging implementation.

The library caches two collections of items and depending on the circumstances the item I am looking for may be in any of the two collections. This is not important. What is important, is that the library for some reason logs an error if an item cannot be found in the first collection.

I wanted to get rid of this message because it was cluttering my logs. But I didn’t want to disable all logging from this specific class, because it may print some useful logs. I just wanted to get rid of this specific log. There is a way to do it Continue reading

Since Spring 3.2 it should be possible to use a qualifier in the “Async” annotation of a method, to indicate which specific executor to use. For example, I have the following class, that is supposed to collect the HTML from a website asynchronously:

HTMLFetcher Interface

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.concurrent.Future;

import org.springframework.scheduling.annotation.Async;

public interface HTMLFetcher {

Future<HTMLFetcher.HTMLFetcherResult> getHTML(String baseUrl,Date date);

interface HTMLFetcherResult {

String getHTMLResult();

Date getDate();
}
}

TestHTMLFetcher Class

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.concurrent.Future;

import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import agonesgr.html.HTMLFetcher;

@Component
public class TestHTMLFetcher implements HTMLFetcher{

@Async(value="htmlFetcherExecutor")
public Future<HTMLFetcher.HTMLFetcherResult> getHTML(String baseUrl, Date date) {
try {
System.out.println("Before execute!!");
Thread.sleep(100000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HTMLFetcher.HTMLFetcherResult r = new TestHTMLFetcher.HTMLFetcherResultImpl("",new Date());

return new AsyncResult<HTMLFetcherResult>(r);
}

private static class HTMLFetcherResultImpl implements HTMLFetcherResult{

private String htmlResult;
private Date date;

public HTMLFetcherResultImpl(String htmlResult, Date date) {
super();
this.htmlResult = htmlResult;
this.date = date;
}

public String getHTMLResult() {
return htmlResult;
}

public Date getDate() {
return date;
}
}
}

And the following excerpt from the context.xml file:


This didn’t work! I submitted 10 tasks to the executor and 10 thread, instead of 1 as I had instructed it had been created. I digged into the Spring code a bit and found the AnnotationAsyncExecutionInterceptor class that was doing tbe job of assigning tasks from methods annotated as async to executors. Putting  a breakpoint on its getExecutorQualifier method it became evident why it doesn’t work.

You need to annotate the interface method rather than the class with the:

@Async(value="htmlFetcherExecutor")

annotation. In my example that is the getHTML method of the HTMLFetcher interface. It now works. I am not sure if it was done on purpose (i.e. if it’s part of the specification). I don’t have time to read the related documentation or search the Spring Jira. However, I would assume that the right place to put the annotation is the implementation. I may want to have two implementations of the same method, one decorated with “Async” that will be asynchronously executed and another without any annotation that will be synchronously executed.

I tried using the Apache XMLConfiguration to save the settings of an application I am developing to XML format. When I used it with Java 1.5 it all worked perfectly; however if I tried using it with Java 1.6 I was getting the following exception.

Exception in thread "main" java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.setDocumentInfo(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
at org.apache.commons.configuration.XMLConfiguration.save(XMLConfiguration.java:880)
at org.apache.commons.configuration.AbstractHierarchicalFileConfiguration$FileConfigurationDelegate.save(AbstractHierarchicalFileConfiguration.java:454)
at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:546)
at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:513)
at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:491)
at org.apache.commons.configuration.AbstractFileConfiguration.save(AbstractFileConfiguration.java:403)
at org.apache.commons.configuration.AbstractHierarchicalFileConfiguration.save(AbstractHierarchicalFileConfiguration.java:199)

After doing some search on google I found that this can be a problem with the xerces XML library (xercesImpl.jar). Checking the 3rd party libraries I am using in my project, I found a library that was using and distributing an earlier version of xercesImpl.jar.

I downloaded the latest version (2.91) of xercesImpl.jar from the Apache xerces project (http://xerces.apache.org/mirrors.cgi#binary) and replaced in the 3rd party library I was using the xercesImpl.jar file with the one I downloaded. Now everything seems to work fine, even in Java 1.6.  🙂