JSON endpoint in Playframework with one annotation

Playframework 1.2 is really nice in getting things done quickly. Today I’ve had to add JSON endpoints
in my application that would render exactly same models as html pages on same URLs.
I could have done it manually, but there are some AOP mechanisms you can use in Play that may be useful here.

So I’ve implemented some simple aspect that would cut trough requests and return JSON instead
of rendering html templates:

public class JsonPointcut extends Controller {
    static void renderModelsJson() {
        if (isJsonRequest()) {
            Scope.RenderArgs renderArgs = Scope.RenderArgs.current();
            Map<String, Object> outputObjects = new HashMap<>();
            for (Map.Entry<String, Object> entry : renderArgs.data.entrySet()) {
                if(entry.getValue() instanceof JPABase) {
                    outputObjects.put(entry.getKey(), entry.getValue());
    static boolean isJsonRequest() {
        Http.Header accepts = request.headers.get("accept");
        return accepts != null && "application/json".contains(accepts.value());

It will simply override render statements in controllers annotated with @With(JsonPointcut.class)
and render all parameters that would usually go into html template and extend JPABase (base class of Play entities) in form of JSON map.
Just remember to use Accept:application/json in request HTTP header.

Simple and beautiful.


Just uploaded a bit more fail safe and powerful version as Playframework module. Check my company GitHub account:

No documentation yet, but javadocs on controller.JsonRenderer class describe pretty much everything. Will add some later on.

Log4j logger.error(Object) trap

Today I’ve fell into ugly Log4j logger trap. Everybody knows there is error, debug, info… method on Logger object. But what you might not know is that there is no error(Throwable) method there, only error(Object). What’s the difference you ask? It’s quite big. There’s error(String, Throwable) that will log out your message (the String param), build Throwable stack trace and log it along, but error(Object) will treat exception just like every other object. There will be NO stack trace in your logs, only exception message, Throwable.toString() will be called to generate it.

Continue reading…

Generating Web Services server using Axis2

Everybody knows that you can easily generate Web Services client classes just from WSDL file in Java.
You even have such tool (wsimport) in every JDK distribution (check JDK_HOME/bin). It handles
all XML data types to Java mapping and generates all complex types needed. You even have such tools
for many other programming languages. Scripting languages don’t need them at all, they generate them
on the fly.

But what to do if you have to implement WS client and only thing you can get from your customer
is a WSDL file? Of course you can generate client classes from it. But how to test it? (You wouldn’t give
untested code to your customer, won’t you?)

Continue reading…

Web Services in Ruby, Python and Java

Today I’ve had to prepare some examples to show that web services are interoperable. So I’ve created a simple web service in Java using Metro and launched it on Tomcat. Then tried to consume them using Python and Ruby. Here’s how it all finished…
Continue reading…

J2EE JDBC based authentication with JPA Entities in Glassfish

One of the authentication options you get in Glassfish is to store your users/roles just in database tables. This way you can implement your custom UIs and logic for managing users. Usual solution you’ll find over the web for that is to create them by hand with SQL and fill using JDBC. What I needed was to get some entities for the users so I just could start my app and everything is created by JPA. This is not that easy, as Glassfish has some assuptions about tables you use (as it’s also using plain JDBC to retrieve users from database). Here’s how I’ve managed to do it using JPA 2.0 entities:
Continue reading…

Java 7 listen for file/directory change

Today I’ve started to experiment with some new features we’ll get in Java 7. First is filesystem WatchService which allows us to listen to changes in some directory without any pooling. Looks really great. You just register to be notified about change and wait to get your notifications. Best of it you can assign as much listeners as you like and even from different threads with no code changes, it all is thread save. Here’s what I’ve done to get notified about files being modified/removed/added to my very important TEMP directory:
Continue reading…

File last access time in Java on Linux

Some time ago a friend of mine needed to retrieve last access time of file in his Java code on Linux. Then he used this info to check if some cache files can be removed. I’ve wrote simple JNI based library to do this. It’s very simple but maybe someone can reuse it. So here it is (You need Java 1.4 or newer to use):

Jar with classes: jAccessTimeJ.jar
Native library (32bit): libjAccessTimeC.so

(Sorry no 64bit binary yet. I don’t have 64 bit Linux host right now. Please send it to me if you compile it from sources)

To run:
java -Djava.library.path=./ -cp jAccessTimeJ.jar com.wordpress.jdevel.utils.JAccessTimeUnix /path/to/file

Remember to put .so file in current directory.
Or you could put .so file somewhere on LD_LIBRARY_PATH and then omit -Djava.library.path=./ switch.

To use it from you Java code:

private void testLastAccess() {
    File f = new File("/boot/vmlinuz");
    Date date = JAccessTimeUnix.getLastAccessTime(f);

You can get source from here:

Java 1.5 annotation processors and Netbeans

Netbeans has great support for annotation processors in editor, but it’s only available if you’re developing Java 1.6 application. But because Netbeans is using standard Ant scripts as it’s build system you can easily integrate 1.5 annotation processors with it. What you have to do is edit project build.xml file and add new apt target:
Continue reading…

Java DocumentBuilder: xml parsing is very slow?

I’ve been messing up with some code to find certain links in a xhtml page in Java. I’ve started with XPath and page source parsed by ootb javax.xml.parsers.DocumentBuilder, but it was so painfully slow. What’s most interesting it was not the XPath evaluation but xhtml parsing.

It was only 12kB large and took around 2 minutes to parse! It was simply unusable (that’s why this regex from previous post was born). Then XPath was evaluated in no time. What was causing the issue is that xml parser is by default doing all validation it can while parsing documents (this also means trying to download DTDs or xslt documents to validate document structure). All was fixed by disabling validation. So here it is if you need it:

DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
fac.setFeature("http://xml.org/sax/features/namespaces", false);
fac.setFeature("http://xml.org/sax/features/validation", false);
fac.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
fac.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder builder = fac.newDocumentBuilder();

Now use this builder to parse xml documents with no validation (and no time).

ArrayList vs LinkedList

I’ve always wanted to really check when we should use which list implementation in Java. You know theory: ArrayList should be faster to get element by position while LinkedList should be much faster to remove and add elements somewhere in the middle. But how does it look in the real world? I’ve done some quick benchmark and here are results (it’s time so smaller is better):

Add Iterate Remove last Remove first Random get Random insert
ArrayList 0001.00 0000.00 0004.00 0001.00 0006.00 2937.00
LinkedList 0015.00 0000.00 0003.00 0000.00 7013.00 36215.00
Random remove Contains Middle get Middle insert Middle remove Middle contains
ArrayList 0558.00 7722.00 0007.00 1962.00 0535.00 7042.00
LinkedList 5101.00 18342.00 11774.00 20428.00 5246.00 17053.00
Insert before
ArrayList 3516.00
LinkedList 0023.00

Continue reading…

%d bloggers like this: