<< May 2005 | Home | July 2005 >>

Performance tuning Java with secret vm flags

I've just spent about an hour and half with Jared Jenson and Adam Leventhal performance tuning DWR with dtrace. Here's what I learnt:

There are a stack of options to java.exe that Sun don't document, but can help with tuning Java in a Tomcat environment. Particularly -XX:NewSize=200m which increases the size of the heap allocated to short lived objects. With tomcat you typically have a very large number of short lived objects so this can make a difference. I found docs written by BEA and IBM on the subject.

It is sometimes worth running tomcat with the client vm. (java -client) this is because tomcat ends up causing a large number of JIT compiles. This surprised me a bit because it wasn't as though we were testing code that was just being run for the first time where you'd expect JIT compiles, but the results were fairly clear - we got the number of calls that DWR could make per second up from 42 to 46. (This is a fairly worthless number because the client was on the same machine as the server). The point is the increase.

We might be able to wring some more performance out of DWR by doing less logging, but the % increase would not be great.

But here is the really good news - the performance overhead that DWR causes is close to zero compared to that caused by tomcat, and I expect the tomcat overhead is small compared to the network overhead. So there no point in tuning DWR.

Getting a deadlock without using any locks

Josh Block and Neil Gafter gave what was in my opinion the most interesting talk of JavaOne, day 1 on coding puzzles.

Some of the puzzles were the kind where the warning signs go off just as soon as you see them, and the sensible thing is to quit trying to work out what is going on, and just change it to be obvious. For example:

count += count++;

Stop thinking about what it does - ask what it should do and re-write it.

count++;
count = count * 2;

Is way clearer, and isn't buggy.

The real gem in the list of puzzles was on avoiding the "lock-free dead-lock" scenario. The following code uses a Thread to do some complex initialization for a class in the background:

public class LazySetup {
    private static boolean init = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                // hard work goes here
                init = true;
            }
        }

        t.start();

        try {
            t.join();
        }
        catch (InterruptedException ex) {
        }
    }

    public static void main() {
        System.out.print(init);
    }
}

Apparently there is Swing code that does something similar. You could use an idiom like this to set off an number of setup tasks in parallel; but don't!

The very subtle bug is that the line that says init = true;. Since this line is executing in a different (inner) class and thread from the main LazySetup class and thread, the JVM needs to check to see the status of the Class to see if it is properly initialized.

Clearly it isn't - The main thread is waiting for the the child thread in the t.join(); line, which is inside the static init block. So before the init = true; line is executed the JVM stops execution of this thread to wait for the initialization to finish, which of course will never happen.

Outch! The moral is never use lazy threads to initialize your resources, or if you really need to you should create some separate classes so the init order is clearer.

Security Warning: Watch out using CVS at JavaOne

Very nearly got bit by this one today. I wanted to show someone the DWR code at JavaOne, so I flipped up the the lid on my laptop and was just about to double click on a java class when it occurred to me that doing so would probably be telling someone my password.

Whenever you open a file in a CVS project using Eclipse it checks CVS to see what you have changed compared to the CVS version (the same goes for Intellij as well I think). Since java.net advises you to use pserver for CVS access, this means you password will be being broadcast in clear-text using wifi to 15,000 developers at JavaOne?

How many of those 15,000 developers will be snooping on the network do you think? Anyone want to bet their password on 0?

The good news is that there is a solution, the shame is that java.net don't publicize it more.

I pointed it out to the java.net people, who said, roughly speaking "there is a special 'tunnel' ssh user that can fix the issue". (The lady I was speaking to even spoke in HTML - very impressive!)

It's a bit of a shame that java.net don't publicize this one more, but appatently it has something to do with the 'tunnel' user being a Sun enhancement, and the website descriptions are provided by Colab.net.

DWR version 1.0RC1 Released!

We've reached DWR version 1.0RC1. The list of changes for this release is slightly shorter than for previous releases:

  • DWRUtil.js: has had lots of tweaks, several functions have been deprecated, generally because there are better versions, sometimes because they don't belong in DWR. We'll probably remove them for 1.0 final so if you think any functions should stay. Join the mailing lists and tell us.
  • Better handling of collections: There is a new element in dwr.xml: <signatures> that allows you to specify method signatures in a JDK5 generics style even on JDK 1.3/1.4
  • More Remoting Options: DWR now supports iframe remoting as well as XMLHttpRequest and you can set a timeout on a call.
  • Big Website Update: Lots more documentation. Check it out.
  • Lots of changes for the release have been to make DWR more maintainable and bug free.

Sun's comments of the future of AJAX

Greg Murray wrote an interesting article a few days ago about AJAX and some of the issues with writing AJAX websites. The article makes the following points about AJAX websites:

Complexity: Server-side developers will need to understand that presentation logic will be required in the HTML client pages as well as in the server-side logic to generate the XML content needed by the client HTML pages. HTML page developers must have JavaScript technology skills. Creating AJAX-enabled applications will become easier as new frameworks are created and existing frameworks evolve to support the interaction model.

And those frameworks are arriving. DWR has just reached version 1.0RC1 and clearly having written most of DWR, I think it's the best Java and Ajax solution out there. It looks like Google agrees with me, but if you want options there is always Echo2 or JSON-RPC-Java.

Standardization of the XMLHttpRequest Object: The XMLHttpRequestobject is not yet part of the JavaScript technology specification, which means that the behavior may vary depending on the client.

This is one of the best reasons for using a tool like DWR. You don't need to get bogged down in discovering that Safari doesn't support XHR/POST or that various versions of IE have all sorts of quirks that you need to tak into account.

JavaScript Technology Implementations: AJAX interactions depend heavily on JavaScript technology, which has subtle differences depending on the client. See http://www.quirksmode.org for more details on browser-specific differences.

This is why DWR comes with its DWRUtil.js function that help you take data returned from the server and put it on your web page. DWRUtil.js is not a full-blown widget framework like Dojo - It is a set of easy to understand functions that create tables, lists and manipulate text and form fields.

Debugging: AJAX applications are also difficult to debug because the processing logic is embedded both in the client and on the server.

Tell me about it! There are now a number of tools like greasemonkey scripts that help with this issue. But if you use DWR you should not need them at all. DWR has been debugged so you don't need to.

Viewable Source: The client-side JavaScript technology may be viewed simply by selecting View Source from an AJAX-enabled HTML page. A poorly designed AJAX-based application could open itself up to hackers or plagiarism.

DWR takes security very seriously; using J2EE authentication and role based authorization, along with other security measures. I believe this makes the process of auditing what is allowed and what is dis-allowed easier than it was before the days of AJAX.

Javaworld article on DWR

JavaWorld have published a good tutorial on using DWR. The article misses a few recent changes to DWR so you'll need to know about the following:

In place of, DWRUtil.showById("id"); you should use $("id").style.display = '';.

And in place of DWRUtil.drawTable(...) you should use DWRUtil.addRows(...).

The reason for the changes is that we are trying to concentrate on being a AJAX library and not a set of generic Javascript functions. So DWR will help you get data from a server using AJAX, but it won't help you mucking with CSS and so on. Other libraries can do that better.

Obscure code hell and a security hole for a bus

It would be nice to be able to say "only joking" about this code; however this code was live, on the internet. Spot the bus sized security hole.

The code sample is color coded because I needed to demonstrate to some non-techies what a mess things were, and showing them the language mish-mash like this worked well. Sorry if you only have a narrow screen; I didn't fancy trying to word-wrap it ...

Answer to the security hole below:

Key:
JSP Server-side scripting language
HTML Client display layout
Java Server-side programming language
JavaScript Client scripting language
SQL Database programming language
CSS Client display style

Code:

...
<script>
function saveSnippet(controlname) {
var myvalue = document.all[controlname].value;
mysql = "update mgruat.conf_component set <%=locale%>='"+cleanvalue(myvalue)+"' where id="+(controlname.substring(5));
processQueue(mysql);
document.all[controlname].style.backgroundColor="#ffffff";
}
</script>
...
<%for (int i = 0; i < queryResult.length; i++) { %>
...
<TD width="10"><INPUT style="width:300px;" onfocus="spansave<%=queryResult[i][0]%>.style.visibility='visible';this.style.background='#ffffcc'" value="<%=codedResult%>" type="Text" name="value<%=queryResult[i][0]%>"></TD>
<TD><span id="spansave<%=queryResult[i][0]%>" style="visibility:hidden;"><NOBR><a href='javascript:;' onclick='spansave<%=queryResult[i][0]%>.style.visibility="hidden";saveSnippet("value<%=queryResult[i][0]%>")'><img src="/contenteditor/icons/save.gif" width="18" height="18" alt="" border="0" align="absmiddle"/> save</a></NOBR></span></TD>
...
<%} %>
...
...

It's not there any more ;-P.

Digging the project out of this hole is what inspired me to write DWR.

Curious to the security hole? Answer in white on a white background below, select the text to view:

The SQL is embedded in Javascript and not Java, so the functions that it is passed to send the Javascript back to the server for execution. So altering the SQL to 'DROP DATABASE' is rather easy.

Tags :

Being tempted to switch to Intellij from Eclipse

It looks to me like Intellij has a killer feature that I can't get anywhere else, and I'm fighting my way to making use of it.

Generally speaking there is a huge hurdle in swapping your IDE, and that is your "finger memory". When I'm in Eclipse and I want to see the implementation of some method I just hit F3 and I don't need to think about it. Whenever I try out Intellij or NetBeans, I'm sure they can do it too, but I don't know the key sequence off by heart. So other IDEs slow me down.

Aside: I'm sure that IDE wars often come down to people rationalizing their in-ability to learn new key sequences, by inventing stupid reasons why their IDE is better than someone elses. But that's another story.

BUT it appears that Intellij v5 has a killer feature, and one that might make me go through the pain of learning new key sequences. In ye-olden-days of 2004 before Ajax was invented, most of a Java/Web developers time was spent like this:

  • 30%: Editing/Debugging Java code
  • 40%: Editing/Debugging Struts/Spring config files
  • 20%: Editing HTML and CSS in web pages
  • 10%: Filling in timesheets

Now if you are lucky enough to be involved with Ajax development, things have changed a bit:

  • 50%: Getting your head around some gnarly Javascript
  • 20%: Editing/Debugging Java code
  • 20%: Editing HTML and CSS in web pages
  • 10%: Filling in timesheets

It appears that IntelliJ 5 has a Javascript editor with the brains that we've come to expect from Java editors.

So I'm currently being very unproductive and tying my fingers in knots getting the key-sequences wrong, and getting cross with a javascript editor which is very nearly a must have feature.

I say 'very nearly' because it is clearly still under development.

Back to keymaps

I notice that IntelliJ (like Eclipse) has a keymap feature that helps users from Emacs and Visual Studio. Eh! I'm sure there will be more people trying out IntelliJ 5 from Eclipse than from Emacs in the next few months. Eclipse is similarly unhelpful.

Maybe they don't want the "other guy's" keyboard shortcuts to become the "standard". I say - help users out, it's far more important than some keyboard standards battle.

Does anyone have a neat way to make Eclipse do IntelliJ keyboard shortcuts, or the other way around?

Rumors of ActiveX off by default in IE7

There have been a few rumors as a result of a blog article on Microsoft watch (see reduced security mode) that IE7 might default to ActiveX being crippled like it is in Windows Server 2003.

This is good because it would fix a lot of security problems, but could also be bad because it could break a lot of websites, maybe including Ajax ones which use an ActiveX control on IE.

The IE blog however reported that what many regard as a huge security issue stays. In some ways it's a shame because Firefox has shown that ActiveX is not required, but I suppose it is to be expected.

Comparing DWR as a web framework

Matt Raible recently blogged about his updated presentation on Comparing Java Web Frameworks, and already in the comments there are people asking about how Ajax fits in. So here's my take from a DWR point of view:

First a comment on architecture. In my experience it is easy to create a service layer that works with POJOs and have DWR integrate with that directly, so your service methods are remoted to Javascript. This cuts down on a huge amount of boiler-plate code, and really gets you off to a fast start.

DWR will work with any of the major web frameworks - it ties into Spring well and Bram Smeets and I are working on making this integration better. The next version of WebWork even comes with DWR. BUT the more you get into the Ajax model the more you realize that you are using your standard web framework less and less. Ajax won't do away with the need for a web framework, but it does mean that less server-side code is needed.

Pros and Cons for AJAX / DWR

Pros:

  • Better user interfaces
  • Fast response times
  • Ajax is the "new thing", so it is easy to get enthusiastic about
  • It will integrate with your existing framework

Cons:

  • The need to learn Javascript
  • Extra time needed for an accessible site
  • All quite new, so maybe it is all hype after all?

Comparing DWR with other frameworks

Recognising that DWR does not exclude more traditional frameworks, it is worth comparing using Matt's criteria:

List Screens: How easy is it to code pageable, sortable lists?
For server side generated tables you can still use DisplayTag. For client side tables, use DWRUtil.drawTable which is not as feature-full yet.

Bookmarkability: Can users bookmark pages and return to them easily?
It depends how you organize your site, AJAX sites that exist in only 1 page (like Google maps) may have to take extra steps for bookmarkability.

Validation: How easy is it to use and does it support client-side (JavaScript) validation?
Very easy. DWR integrates with commons-validation and any other validation framework.

Testability: How easy is it to test Controllers out of container?
Very easy. Server side code with DWR is just a collection of Java beans

Post and Redirect: How does the framework handle the duplicate post problem?
AJAX has 2 solutions, firstly AJAX can be so fast that the problem just goes away, secondly since the pages are controlled by Javascript, disabling a button is fairly easy.

Spring Integration: Does the framework support using Spring in the middle tier; how easily?
Yes. DWR can remote spring beans - it doesn't get much easier than that!

Internationalization: How is i18n supported and how easy is it to get messages in Controllers?
AJAX in general and DWR in particular do not attempt to solve the i18n issue, use one of the other frameworks in tandem with DWR to get i18n.

Page Decoration: What sort of page decoration/ composition mechanisms does the framework support?
DWR works with both Tiles and SiteMesh.

Tools: Is there good tool (particularly IDE) support for the framework?
IDEA v5 has updated Javascript editing functions that can really help web development.

Marketability of Skills: If you learn the framework, will it help you get a job?
Maybe not today, but certainly tomorrow.

Job Count: What is the demand for framework skills on dice.com?
9 for AJAX (wow!)

[Update: Fixed the spelling of Raible! - Sorry Matt.]
[Update: Fixed a typo.]

A New Type of Dependency Injection.

Matt Raible was playing with DWR and Valang, and wondering if they could work together, and it set me off on a train of thought from which I conclude that maybe there is a type of Inversion of Control that we'd not thought of before.

There is a good summary of the types of IoC at the Pico website. Martin Fowler has written on the subject and Cedric isn't sure if type 1 and 2 are worth splitting. But at the end of the day there are currently 2 useful forms of Dependency Injection. Pico prefers the former, Spring the latter:

  • Constructor Injection: (i.e. the config file specifies how to call a constructor)
  • Setter Injection: (i.e. the config file specifies what setters to call on a JavaBean)

Matt wanted to know if DWR could use Valang to do Ajax based validation. I've not looked at Valang in detail, but I can say that the answer is: probably. You configure DWR to remote certain classes. There are various ways to create a class for remoting, but the most powerful is the ScriptedCreator, which is used in the current Ajax validation example.

The configuration for the Ajax validation example looks a bit like this:

<create creator="script" javascript="EmailValidator">
  <param name="language" value="beanshell"/>
  <param name="script">
    import org.apache.commons.validator.EmailValidator;
    return EmailValidator.getInstance();
  </param>
</create>

In short, I'm using BSF and BeanShell to configure the commons-validator component. It struck me that ScriptedCreator is a bit like an IoC container that implements "Scripted Injection". You still get the ability to put all your configuration in a single file, and keep the dependencies out of the code, but in addition you get to call whatever constructors and setters you like. You can also specify the exact order or call a custom init() method, which Setter and Constructor based injection find harder.

I can also imagine that Scripted Injection could be considerably more compact than setter or constructor based injection.

I'm sure some people will say that Scripted Injection is evil because it blurs the boundary between data and code. But I would argue that the Spring config file was already expressive enough that it could be called a programming language of sorts (may it is even Turing-complete?) and everyone knows that it is evil to write programming languages in XML. The point is not to knock Spring - but to argue that Scripted Injection could be the answer to some of the criticism of the verbosity of Spring (particularly from those RubyOnRails types).

Revised Law of Software Envelopment.

<tongue position="cheek">Some time ago the ego that is JWZ, noted that Netscape contributed to the proof of the "Law of Software Envelopment" which was that "Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can".

E-Mail is old hat. These says - we have Thunderbird and GMail. IoC is the new E-Mail. The Revised Law of Software Envelopment is that "Every program attempts to expand until it is an IoC container or it contains one. Those programs which cannot so expand are replaced by ones which can". So now at last I know that DWR is good enough to cut it for the next decade or so.

Anyway - take it or leave it, I think that scripted injection is an interesting option for any real IoC containers.

(Updated: with correction to Pico and Spring)