Rough Book

random musings of just another computer nerd

Tag: java

Don’t use class literals as type-tokens

Generics were added to the Java language within J2SE 5.0, and there was much rejoicing. It was finally possible to deal with containers in a type-safe manner. Prior to the availability of generics, Java developers had to do things like this:

List people = new ArrayList();
people.add(new Person("Donkey Kong"));
people.add(new Person("Guybrush Threepwood"));

Person pirate = (Person) people.get(1);

This kind of code is very fragile since it is not easy to keep track what is inside a container. If at runtime, the object you retrieve is not of the type that you’re expecting, you can get a ClassCastException. It is also remarkably easy to pollute a container by shoving objects of different types inside there, which makes it even more difficult to keep track of the types of the objects inside. Workarounds included littering code with instanceof checks, or creating a wrapper class (for example a class called PeopleList that would delegate to an internal List instance) around the container so that you could have control over the types of objects being inserted.

When generics finally arrived, people were ecstatic because now you could do things like this:

List<Person> people = new ArrayList<Person>();
people.add(new Person("Donkey Kong"));
people.add(new Person("Guybrush Threepwood"));

Person pirate = people.get(1); //It just works!

This meant no-more ugly workarounds, which means that things are awesome! Right?

Read the rest of this entry »

Heroku template for Spring 4 app with Oracle Java 8 and Tomcat 7.0.54

I’ve been playing around with Heroku at work for the past week or two. Heroku is pretty awesome if you want to get an app up and running quickly. Heroku does support Java and they have a few Java templates. Their current offering for Java uses Spring 3 and Tomcat 7.0.54 with Java 7. However, the version of Spring is somewhat older and they also use OpenJDK’s Java instead of Oracle’s Java. I wanted to try out Java 8 and also use a newer version of Spring so I upgraded the existing template to support both of those (I used a forked version of a custom buildpack for Java 8). I also had to update Heroku’s Web Runner to use Tomcat 7.0.54 (I have a pull-request waiting but I’m not sure if/when it will get approved so I have an artifact on GitHub that Maven can pull).

You can check out the template here.

The image that lied about itself

A few weeks ago, I ran into a puzzling issue at work. Someone was uploading an image which made it past our file-size checks, but caused an OutOfMemoryError and a heap dump when the code attempted to resize it. The information we had from the heap-dump was that it was trying to allocate memory for an image whose resolution was 18,375×11,175. What didn’t make sense is how this image was even getting through our file-size checks, because there is no way we would ever let in an image of that size.

In the code, we have a global limit for the largest file we will accept. We also have a separate limit for image uploads. If the image is over this size, but under the global limit, we will resize the image to a smaller size. The strange part was that the large image was making it past the global check, which meant that the size of the incoming data was below the global limit, but above the image-size limit. How could this be?

On a hunch, I hypothesized that perhaps the entire image wasn’t making it through. Perhaps only a part of the image was making it through with its header left intact. In an image file, there is usually a header that conveys information about the file format, the color space, and the resolution of the image! I figured that even though the data are incomplete, enough information was present in the header to enable the resizing code to make sense of it. When it tries to allocate memory for this image, based on the resolution it gets from the header, it runs out of memory!

To verify this, I manually hex-edited a file that was of proper size to have a ridiculously-large resolution. I then uploaded this file and was able to witness the behavior happening even though the file was of the proper size! So what’s the lesson here? Don’t only rely on file-size limits for images; you have to look at the resolution as well!

JavaOne

I am at JavaOne! The last time I was here was in ’08, when it was run by Sun. Of course, it’s run by Oracle now. The first day has been pretty good. I attended sessions on Garbage Collection, the Nashorn JavaScript engine, writing DSLs, and about parallelization options offered by JDK 7 and 8 to leverage multicore processors. Pretty good first day!

Nashorn looks pretty interesting and I will be giving it a closer look when I come back home. They are also looking for people to help out so I am going to see if I can contribute anything useful.

Today I will be checking out a talk on Lambdas by Brian Goetz and will also be going to a talk on Big Data. Finally I also have some BOF (birds of a feather) sessions on evolutionary algorithms and writing parsers in Scala. Pretty interesting day and I’m looking forward to it!

A simple trie-implementation

I’ve known about tries for sometime. They’re a pretty neat data-structure for storing and looking-up strings.I decided to try and implement one in Java so that I can learn more about them. I’ll post another article later that goes into some more detail about this implementation, but for now you can check out the source here. It’s not production-ready by any means; it’s just me playing around.

Implementing pinch-zoom and pan/drag in an Android view on the canvas

I was trying to get pinch-zoom and panning working on an Android view today. Basically I was trying to implement the same behavior you see when you use Google Maps (for example). You can zoom in and pan around until the edge of the image, but no further. Also, if the image is fully zoomed out, you can’t pan the image. Implementing the pinch-zoom functionality was pretty easy. I found an example on StackOverflow. I then wanted to implement panning (or dragging) as well. However, I wasn’t able to easily find examples and tutorials for this functionality. I started with this example that comes from the third edition of the Hello, Android! book but I didn’t get too far. So I started playing around a little bit with the events and started writing some code from scratch (using the example from Hello, Android!) so that I could have a better idea of what was happening.

As I mentioned before, getting zoom to work was pretty easy. Implementing panning/dragging was the hard part. The major issues I encountered and subsequently fixed were the following:

  1. Panning continues indefinitely in all directions.
  2. When you zoom and then pan, stop, and then start again, the view jerks to a new position instead of panning from the existing position.
  3. Excessive panning towards the left and top can be constrained, but panning towards the right and bottom is not so easily constrained.

Once I fixed all the problems, I figured that it would be nice to document it for future reference, and I also think it would be a useful resource for others who have the same problem. Now a little disclaimer before I go any further: I’m not an Android expert and I’m really not that great with graphics; I just started it learning to program for Android this semester for one of my Masters electives. So there might be a better way of doing all this, and if there is, please let me know! Also, if you want to skip all the explanations and just see the code, you can skip to the last page.

Read the rest of this entry »

Setting the content type to text/plain for a JSON response from a Spring controller

I was using a jQuery plugin called a ajaxfileupload to upload a file through AJAX. Technically what the plugin does isn’t AJAX. It creates a hidden form and an iframe, and then submits the form using the iframe as the target. The iframe will then end up with the response from the server. This response is then read-in by the plugin and handled appropriately. In my case I was using a controller action that would return JSON (using the .action extension). The action uses Spring’s MappingJacksonJSONView that returns JSON with a content type of application/json (as it should). This works perfectly in Chrome, however in both Firefox and IE, the user is presented with a dialog box that asks them to download the JSON response. This is obviously not what I wanted. The reason this is happening is because the response is being directly submitted to the iframe (and therefore, the page). That is, it’s not coming through via the XMLHttpRequest object. So IE and FF don’t know what to do with it and assume that it is something the user would want to download. The solution to this problem is to set the content-type to text/plain. This wasn’t as straightforward as I thought it would be.

Initially I was going to call the render(…) method of MappingJacksonJsonView but that didn’t work because the content-type had already been set to application/json. The solution I came up with was to duplicate some of the code (ugh) inside MappingJacksonJsonView to get the JSON as a string and to then write that to the response:

@RequestMapping
public void processFileUpload(HttpServletResponse response, Model model, ...) {

    ...

    //Set the content-type and charset of the response
    response.setContentType("text/plain");
    response.setCharacterEncoding("UTF-8");

    //I need to use another OutputStream here; I cannot use the response's OutputStream because that will cause errors
    //later on when the JSP needs to render its content (recall that getOutputStream() can only be called exactly once
    //on a response). Therefore I'm writing the data to a ByteArrayOutputStream and then writing the byte array from
    //the ByteArrayOutputStream to the response manually.

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ObjectMapper objectMapper = new ObjectMapper();
    JsonGenerator generator = objectMapper.getJsonFactory().createJsonGenerator(byteArrayOutputStream, JsonEncoding.UTF8);

    //Before I can convert the data into JSON, I will need to filter some attributes out of the model (namely BindingResult)
    Map<String, Object> result = new HashMap<String, Object>();

    for(Map.Entry<String, Object> entry : model.asMap().entrySet()) {
        if(!(entry.getValue() instanceof BindingResult)) {
            result.put(entry.getKey(), entry.getValue());
        }
    }

    objectMapper.writeValue(generator, result);
    response.getWriter().write(new String(byteArrayOutputStream.toByteArray(), "UTF8"));
}

This still seems a little hacky to me. A possible improvement is to annotate the action with @ResponseBody and return the JSON as a string without involving the response at all. If anyone has a better solution, I’m all ears!

Fixing Maven 3.0.3’s dependency-resolution performance-regression

TL; DR; version: Maven 3.0.3 has a performance-regression while resolving dependencies. This is because it uses version 1.11 of aether. The problem has been fixed in version 1.12 of aether, but a version of maven with this library is not available. I built maven from source with the 1.12 version of aether, so use maven-3.0.3-with-aether-1.12.zip if you have the same problem.

The whole story: At work we use Maven to build our project. Over the last few months, we started noticing a disparity in build times between different developers even though the hardware they were using was similar to each other (Core i7’s with 6 Gb RAM). Initially we suspected that it might have to do with SSD performance-degradation. Some of us were using SSD’s that didn’t support TRIM and others didn’t have TRIM enabled. I was one of the few with the former problem. I secure-erased my drive but still saw no performance benefits. I even got a new drive and even with that I didn’t see much of an improvement either.

We finally realized that the build-time disparity was related to the version of maven some developers were using. On maven 3.0b1, build times are much faster compared to 3.0.3. In 3.0.3 there is a performance regression when maven tries to build the dependency graph. For example, using 3.0b1 our project built in 3 minutes and 30 seconds, whereas using 3.0.3, the build times were upwards of 9 minutes. Long build-times take away from the amount of productive coding-time a developer has.

I was determined to find the reason for this performance regression and did some investigation by looking at the source for 3.0b1 and 3.0.3. In 3.0b1, maven uses its own code to resolve dependencies and build the dependency graph, whereas in 3.0.3 it uses the aether library. For more background information on the matter, take a look at this post on the maven developer’s mailing list and this JIRA issue.

Long story short, to get better build times, maven needs to use version 1.12 of aether. I downloaded the maven source and edited the pom.xml file to use version 1.12 of aether. I then built maven from source and got a deployable version that uses the newer aether library. When I tested it out, the build times were comparable to 3.0b1.

I initially thought that version 3.0.4 of maven would include version 1.12 of aether. But it turns out that there were licensing changes and so the maven developers are discussing whether to include it. In the meantime, you can use this version of maven that I built from source, which includes version 1.12 of aether. It’s a zip file and you can install it like you would normally install maven.

Implementing JSONP in Spring MVC 3.0.x

In Spring 3, it’s very easy to get a view to return JSON. However, there is no built-in mechanism to return JSONP. I was able to find a pretty good tutorial That uses Spring’s DelegatingFilterProxy. I implemented this solution and I got it to work, but I didn’t like the fact that I had to create a separate filter and a bunch of other classes just for that. I also wanted to use a specific extension (.jsonp) for JSONP just to make it more explicit. Spring uses MappingJacksonJsonView to return JSON. I figured that I could extend this view and have it return JSONP instead of JSON.
Read the rest of this entry »

All original content on these pages is fingerprinted and certified by Digiprove
%d bloggers like this: