The Source for Java Technology Collaboration
User: Password:



Simon Brown's Blog

November 2003 Archives


Inconsistency between Servlet specification implementations

Posted by simongbrown on November 27, 2003 at 03:49 AM | Permalink | Comments (3)

I’ve been playing around with the various implementations of the security features in Servlet 2.3 compatible web containers. If you’ve ever built secure web applications, you’ll know that there are a handful of fairly useful methods on the HttpServletRequest interface. For example, the getUserPrincipal() method allows you to get access to the authenticated principal, as described by the following Javadoc.

Returns a java.security.Principal object containing the name of the current authenticated user. If the user has not been authenticated, the method returns null.

The reason that I've been looking into all this in detail is that I'm trying to get my open source blogging software (Pebble) to work consistently between vendor implementations. In the webapp, I have a collection of unsecured pages and a collection of secured pages that are defined to fall within a security constraint that is declared in the web.xml file. As stated the by Servlet specification, trying access a secured resource will force the user to be authenticate themselves. The problem that I've come across is that those security methods that I mentioned before work inconsistently between implementations.

For example, on Tomcat and Resin, a call to the getUserPrincipal() method returns a non-null Principal instance at any time after authentication, regardless of whether a request has been made for a secured or unsecured resource. However, with other implementations such as JBoss and Jetty, the getUserPrincipal() method only returns a non-null instance if the request is for a secured resource. What this means is that after authentication, you cannot consistently tell from that method whether the current user has been authenticated or not. Tomcat/Resin will report yes, while JBoss/Jetty will report no.

This issue first came up because a few people have deployed my blogging webapp onto JBoss and were reporting that they could not see some of the "admin" links that appear on the top of every page after logging in. Having delved through the Servlet specification and accompanying Javadoc, I'm still not sure who has correctly implemented this particular feature. A workaround to this is fairly straightforward, and just requires that the user's credentials are saved away in the session, using something like the following:

    // some J2EE web containers don't allow programmatic access to the
    // principal information from resources that don't fall under a
    // security constraint - for this reason this information is placed into
    // the user's session
    AuthenticatedUser user = new AuthenticatedUser();
    user.setName(request.getUserPrincipal().getName());
    user.setBlogOwner(request.isUserInRole(Constants.BLOG_OWNER_ROLE));
    user.setBlogContributor(request.isUserInRole(Constants.BLOG_CONTRIBUTOR_ROLE));
    request.getSession().setAttribute(Constants.AUTHENTICATED_USER, user);

Regardless of the workaround, this does present some interesting questions. Which implementation is correct? What happens when the specification is unclear? Are the Javadocs considered as a part of the specification? After all, they are a programming contract and included in the specification itself. In this case, my opinion is that Tomcat and Resin are correct because the important point is that the user has been authenticated. What do you think, and what do you think would happen if all the implementations were put through the J2EE compatibility tests? Deploying to a certified implementation is my next step and should guarantee consistency. Perhaps making the compatibilty test kits free to open source implementations would help in situations like this, removing doubt as to what is correct.



Using mock naming contexts for testing

Posted by simongbrown on November 21, 2003 at 06:48 AM | Permalink | Comments (7)

Say for example that you want to unit test a Service Locator - a class that looks up data sources, topics, queues, etc from JNDI. How would you go about doing this?

One option would be to simply setup a JNDI environment inside a J2EE application server and write some JUnit tests to run inside the container. While this works, ideally you may want your unit tests to run independently and quickly.

The option we've just taken is to use a Mock Objects approach, therefore enabling us to run the tests during our normal unit test cycle. The one tiny problem that we ran into was that the service locator itself is responsible for creating a naming context by creating a new InitialContext instance, meaning that it's harder to get a mock context in there. The solution? Just write a mock InitialContextFactory as follows.

import javax.naming.Context;
import javax.naming.spi.InitialContextFactory;

/**
 * Provides a JNDI initial context factory for the MockContext.
 */
public class MockInitialContextFactory implements InitialContextFactory {

    public Context getInitialContext(Hashtable env) {
        return new MockContext();
    }

}

Then, when you want to run your tests, just stick a jndi.properties file on your classpath like this.

java.naming.factory.initial=some.package.mock.MockInitialContextFactory

At runtime, the call to new InitialContext() uses the mock factory and results in the creation of a mock context. Just remember not to deploy the properties file in production!



Reasons to use Eclipse and SWT?

Posted by simongbrown on November 14, 2003 at 09:19 AM | Permalink | Comments (18)

I popped down to the JSIG today, the topic of which was Eclipse. Unfortunately I had a 2pm meeting so could only stay for the first presentation by Berthold Daum (author of Eclipse for Java Developers) which was an overview of Eclipse, SWT and plugin development.

The first part of the session took a look at Eclipse itself, and Berthold gave a good overview of the tool, the workbench, the various views, perspectives and so on. Following on from this was a look at some of the features that Eclipse provides including things like code completion, code assist, refactoring, etc. Overall this was technically a good presentation although it didn't leave me wanting to download the tool and give it another try. If you've been following my blog, you'll know I'm a big fan of IntelliJ IDEA and I have a personal license to prove it. In terms of the content covered in the presentation, feature for feature there's nothing new that I can't do with IDEA. Apart from the obvious advantage (i.e. price), why should I switch to Eclipse?

The next part of the presentation looked at SWT - the Swing alternative that Eclipse uses and that we (as developers) can use to build our own desktop applications. Again, this was a good presentation that covered topics ranging from the SWT architecture to the various widgets it provides. For me, the interesting part of the presentation was the summary of the pros/cons for using SWT. Advantages quoted include richer (native) widgets and integration, more stable and more responsive than Swing. Disadvantages quoted include SWT only runs on a limited number of platforms, widgets (can) have different behaviour on different platforms and deployment is an issue because of the native code. So, to summarise my understanding, SWT takes all the things that Java tries to achieve (platform independence, compatibility, etc) and throws them out of the window for something that is perceived to be faster, richer and more stable than Swing? I think I need some more convincing, particularly with the advances that J2SE 1.4.2 has provided in this area.

Just as a last point, there was a quick poll done about how many people have used Eclipse and, unsurprisingly, about half of the audience (about 40 people) raised their hands. Whether you like it or not, Eclipse is gaining a large "market" share. There's been a lot of discussion about Eclipse/SWT, but why should developers make the switch to either of these two tools?



First impressions of Clover

Posted by simongbrown on November 06, 2003 at 03:52 PM | Permalink | Comments (6)

Code coverage by CloverI've recently started using Clover on my open source projects and it's an amazing product. I've not used the Ant tasks yet, but I am using the integration with IntelliJ. Wow, this is probably one of the most impressive products since IntelliJ itself!

If you've not seen Clover before, it's basically a code coverage tool that will help you identify what sort of coverage you are achieving during execution of the code. This means that you can see how much of your code is called when your program is being run, and also how much of your code is run during the execution of your unit tests. In addition to this, it can tell you how many times each particular line/block has been called and also how many times conditionals have been evaluated to true/false.

I'll write a full review when I've had some more time with the tool, but the IntelliJ integration makes using Clover a breeze. Once you've installed the plugin by dropping a JAR file into the IntelliJ plugins directory you get some additional toolbar buttons. Essentially, running Clover is then a simple matter of rebuilding your code with Clover, running your code and then returning to IntelliJ to see the graphical representation of the coverage. I think from the initial download to my first coverage results took about 15 minutes. This really is a great tool and, as I said, I'll write a full review sometime soon.





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds