Recent Posts

Various Bit-Array Implementation in Java

Bit-Arrays are much-useful and quite-fast data-structure that have a variety of uses. One of the most important ones in context of Big-Data is the use in Bloom filters. To store the bloom we need a very fast bit-array and the ones that can be persisted as well. Java has only an in-memory bit-array implementation. I needed a file-persisted one to be used in conjunction with the bloomfilter filter project. Thus, I added the following implementations to the jerry-core project.

  • FastBitArray - an implementation that is much faster than the standard Java implementation
  • FileBackedBitArray - backed by file persistence, and all operations are flushed back automatically
  • MMapFileBackedBitArray - one that is file-persisted, but uses memory-mapped files for nuch faster performance
  • JavaBitSetArray - one that uses internal Java implementation underneath

Usage is pretty simple as,

final int maxElements = 1000 * 1000; // 1 million
BitArray ba = new FileBackedBitArray(new File("my-bit-array.ba"), maxElements);

boolean updated = ba.setBit(13); // returns true
updated = ba.setBit(13); // returns false
ba.clearBit(13);
udpated = ba.setBit(13); // returns true

boolean isSet = ba.getBit(13); // returns true


// using the memory-mapped version is similar
ba = new MMapFileBackedBitArray(new File("my-bit-array"), maxElements);

// all other operations are the same

I have used MMapFileBackedBitArray in production for the last few years and has been quite useful and fast.

Hope this helps.

Iterating over Strings inside a String object

When reading file contents, or working with REST requests, many a times we want to read a String object line-by-line, that is, read lines within a single String object. Java does not offer a simple solution to the same - either you convert the String object to a byte[] and then use ByteArrayInputStream or use a StringReader and then push this into another line-by-line reader.

For the same, I wrote a simple utility class, StringLineIterator (available in jerry-core project) simplifying reading of lines to the following code snippet:

String contents = '...'; // some contents that contains new-lines, and form-feed characters

StringLineIterator iterator = new StringLineIterator(contents);
while(iterator.hasNext()) {
    String line = iterator.next();

    // do something with this extracted line
}

This helps us reading sub-string lines from contents and reduces boiler-plate code. Note that this implementation would use extra memory to the extent of each line, as it creates a new String object for each line that is read via the iterator.

Hope this helps.

Jetty + Spring 4 + Jersey 2 Integration

Today most of the enterprise systems are built over MicroServices. The advantages of the same are well-explained as 12factor principles. In Java, this translates to using Jetty as the embedded HTTP server, running Jersey or RestEasy or alike as the Jax-RS based REST framework.

Integration between Spring 3 and Jersey 2 is well documented and works great. With the coming of Spring 4, the integration still works if you are building a web application using Tomcat or JBoss or any other application server. However, for standalone Java applications this is broken.

Last night, I went poking my nose inside the jersey-spring3 module to dig the reason for the same. And finally found the reason, and a fix for the same.

Quick Fix

For the impatient, a very simple fix to this is to create a new WebApplicationContext, with the parent set to the ApplicationContext you created manually, and then set it in the Jettys ServletContext as:

    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
    context.setContextPath("/");

    AnnotationConfigWebApplicationContext wc = new AnnotationConfigWebApplicationContext();
    wc.setParent(rootContext);
    wc.refresh();
    wc.start();

    context.setAttribute(WebApplicationContext.class.getName() + ".ROOT", wc);

This will ensure that all your dependencies get wired in your web-services.

For why it happens, continue reading.

Why is it broken?

The class org.glassfish.jersey.server.spring.SpringComponentProvider is responsible for detecting existence of Spring context and wiring the same withint the Jersey code so that all your dependencies can be @Autowired or @Injected. Let's take a look at the initialize method of the class:

    @Override
    public void initialize(ServiceLocator locator) {
        this.locator = locator;

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine(LocalizationMessages.CTX_LOOKUP_STARTED());
        }

        ServletContext sc = locator.getService(ServletContext.class);

        if (sc != null) {
            // servlet container
            ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
        } else {
            // non-servlet container
            ctx = createSpringContext();
        }
        if (ctx == null) {
            LOGGER.severe(LocalizationMessages.CTX_LOOKUP_FAILED());
            return;
        }

        // more code omitted for brevity
    }

If you look above, if Jersey figures out that there is a ServletContext already present, which would be as you are running a Jetty server, it will then only read the ApplicationContext/ctx via the code line:

ctx = WebApplicationContextUtils.getWebApplicationContext(sc);

If it detects that no ServletContext is present, only then it creates a new ApplicationContext instance via the call to,

ctx = createSpringContext();

Now the call to WebApplicationContextUtils.getWebApplicationContext(sc) translates to the following code (some constant references have been modified to make the code more understandable):

    public static WebApplicationContext getWebApplicationContext(ServletContext sc, String attrName) {
        Assert.notNull(sc, "ServletContext must not be null");
        Object attr = sc.getAttribute(WebApplicationContext.class.getName() + ".ROOT");
        if (attr == null) {
            return null;
        }
        if (attr instanceof RuntimeException) {
            throw (RuntimeException) attr;
        }
        if (attr instanceof Error) {
            throw (Error) attr;
        }
        if (attr instanceof Exception) {
            throw new IllegalStateException((Exception) attr);
        }
        if (!(attr instanceof WebApplicationContext)) {
            throw new IllegalStateException("Context attribute is not of type WebApplicationContext: " + attr);
        }
        return (WebApplicationContext) attr;
    }

As there is not WebApplicationContext.class.getName() + ".ROOT" attribute present in the ServletContext - Jersey fails to wire the dependencies.

Now, let's take a look at the createSpringContext() method (again, some constants have been inlined):

    private ApplicationContext createSpringContext() {
        ApplicationHandler applicationHandler = locator.getService(ApplicationHandler.class);
        ApplicationContext springContext = (ApplicationContext) applicationHandler.getConfiguration().getProperty("contextConfig");
        if (springContext == null) {
            String contextConfigLocation = (String) applicationHandler.getConfiguration().getProperty("contextConfigLocation");
            springContext = createXmlSpringConfiguration(contextConfigLocation);
        }

        return springContext;
    }

One another way to fix this, would be be to add an ApplicationHandler class that sets the contextConfig property in its configuration, but with annotation support and classpath scanning, I don't see why someone would want to do that.

I would raise a pull-request for the same in Jersey code sometime soon.

Hope this helps.