Archive

Archive for the ‘Technical’ Category

On resources scarcity, application servers and micro-services

October 26th, 2014 2 comments

While attending JavaZone recently, I went to a talk by Neal Ford. To be honest, the talk was not something mind-blowing, many tools he showed were either outdated or not best of breed, but he stated a very important fact: application servers are meant to address resources scarcity by sharing resources, while those resources are no more scarce in this day and age.

In fact, this completely matches my experience. Remember 10 years ago when we had to order hardware 6 months in advance? At that time, all webapps were deployed on the same application server – which weren’t always clustered. After some years, I noticed that application servers grew in number. Some were even required to be clustered because we couldn’t afford the service offered to be off. It was the time when people started to think about which application to deploy on which application server, because of their specific load profile. In the latest years, a new behavior appeared: deploying a single webapp to a single application server because it was deemed too critical to be potentially affected by other apps on the same application server. And that led sometimes to the practice of doing that for every application, whether the latter was seen as critical or not.

Nowadays, hardware is available instantly, in any required quantity and for nothing: they call it the Cloud. Then why are we still using application servers? I think that the people behind the Spring framework asked themselves the same question and came up with a radical answer: we don’t need them. Spring has always been about pragmatic development when JavaEE (called J2EE then) was still a big bloated standard, full of barbaric acronyms and a real pain in the ass to develop with (remember EJB 2.0?) – no wonder so many developers bitch about Java. Spring valued simple JSP/Servlet containers over fully-compliant JavaEE servers and now they finally crossed the Rubicon as no external application server is necessary anymore.

When I first heard about this, I was flabbergasted, but in the age of micro-services, I guess this makes pretty much sense. Imagine you just finished developing your application. Instead of creating a WAR, an EAR or whatever package you normally do, you just push to a Git repo. Then, a hook pushes the code to the server, stops the existing application and starts it again. Wouldn’t that be not only fun but really Agile/Devops/whatever-cool-concept-you-want? I think that would, and that’s exactly the kind of deployment Spring Boot allows. This is not the only feature of Spring Boot, it also provides a real convention over configuration, useful Maven POM, out-of-the-box metrics and health checks and much much more, but embedding Tomcat is the most important one (IMHO).

On the opposite side, big shops such as IBM, Oracle, even Red Hat still invest huge sums of money into developing their full profile Java EE compliant application servers. The funny stuff is that in order to be JavaEE compliant, you have to implement “interesting” bits such as Java Connector Architecture, something I’ve seen only once early in my career to connect to a CICS. Interestingly, the Web Profile defines a lightweight standard, leaving out JCA… but also JavaMail. However, it goes the way of going lightweight.

Now, only the future will tell what and how happens next, but I can see a trend forming there.

Send to Kindle

You shouldn’t follow rules… blindly

October 12th, 2014 1 comment

Some resources on the Internet are written in a very imperative style – you must do that in this way. And beware those that don’t follow the rule! They remind me of a french military joke (or more precisely a joke about the military) – but I guess other countries probably have their own version, regarding military rules. They are quite simple and can be summarized in two articles:

Art. 1: It’s mandatory to obey the orders of a superior.

Art. 2: When the superior is obviously wrong, refer to article 1.

What applies to the military domain, however, doesn’t apply to the software domain. I’ve been fighting for a long time about good practices having to be put in context, so that a specific practice may be the right in one context but plain wrong in another context. The reason is that in the latter case, disadvantages outweigh advantages. Of course, some practices have a wider scope than others. I mistakenly thought that some even have an all-encompassing scope, meaning they give so many benefits, they apply in all contexts. I have been proven wrong this week, regarding 2 of such practices I use:

  • Use JavaConfig over XML for Spring configuration
  • Use constructor injection over attribute injection for Dependency Injection

The use-case is the development of Spring CGLIB-based aspects (the codebase is legacy and interfaces may or may not exist) to collect memory metrics. I must admit this context is very specific, but that doesn’t change that it’s still a context.

First thing first, Spring aspects are not yet completely compatible with JavaConfig – and in any case, the Spring version is also legacy (3.x), so JavaConfig is out of the question. But at least annotations? In this case, two annotations may come into play: @Aspect for the class and @Around for the method that has to be used. The first is used in a very straightforward way, while the second needs to be passed the pointcut… as a String argument.

@Aspect
public class MetricsCollectorAspect

    @Around("execution(...)") // This spans many many lines
    public Object collectMetrics {
        ...
    }
}

The corresponding XML is the following:

<bean id="metricsCollectorAspect" class="ch.frankel.blog.MetricsCollectorAspect" />

<aop:config>
    <aop:aspect ref="metricsCollectorAspect">
        <aop:pointcut id="executedMethods" expression="execution(...)" />
        <aop:around method="collectMetrics" pointcut-ref="executedMethods" />
    </aop:aspect>
</aop:config>

Benefits of using annotations over XML? None. Beside, the platform’s product we use do not embed Spring configuration fragments, so that it’s quite easy to update it and check results in deployed environment – pointcut included. XML: 1, annotations 0.

Another fun stuff: I’ve been an ardent defender of using constructor injection. This has some advantages, including highlighting dependencies, fewer boiler plate code and immutability. The 3.x version of Spring uses a version of CGLIB that cannot create proxies when there’s no no-args constructor on the proxied class. The paradox is that “good” design prevents proxying, while “bad” design – attribute injection with no-args constructor allows it. Sure, there are a couple of solutions to allow this: add interfaces to allow pure Spring proxies, add a no-args constructor on or filter out those unproxyable classes, but none of them are without impact.

Morality: rules are meant to help you, not hinder you. If you cannot follow them because of a good reason (like the cost is prohibitive), just ignore the. Just write down in comments the reason why you didn’t for your future code’s maintainers.

Send to Kindle
Categories: Java Tags:

Your code coverage metric is not meaningful

October 5th, 2014 1 comment

Last week, I had a heated but interesting Twitter debate about Code Coverage with my long-time friend (and sometimes squash partner) Freddy Mallet.

The essence of my point is the following: the Code Coverage metric that most quality-conscious software engineers cherish doesn’t guarantee anything. Thus, achieving 80% (or 100%) Code Coverage and bragging about it is just as useful as blowing in the wind. For sure, it’s quite hard to have a fact-based debate over Twitter, as 140 chars put a hard limit on any argument. This article is an attempt at writing down my arguments in a limitless space.

The uselessness of raw Code Coverage can be proved quite easily. Let’s have a simple example with the following to-be-tested class:

public class PassFilter {

    private int limit;

    public PassFilter(int limit) {
        this.limit = limit;
    }

    public boolean filter(int i) {
        return i < limit;
    }
}

This class is quite straightforward, there’s no need to comment. A possible test would be the following:

public class PassFilterTest {

    private PassFilter passFilterFive;

    @BeforeMethod
    protected void setUp() {
        passFilterFive = new PassFilter(5);
    }

    @Test
    public void should_pass_when_filtering_one() {
        boolean result = passFilterFive.filter(1);
    }

    @Test
    public void should_not_pass_when_filtering_ten() {
        boolean result = passFilterFive.filter(10);
    }
}

This test class will happily return 100% code coverage as well as 100% line coverage: executing the test will go through all the code’s lines and on both sides of its single branch. Isn’t life sweet? Too bad there are no assertions; they could have been “forgotten” on purpose by a contractor who couldn’t achieve the previously agreed-on code coverage metric. Let’s give the contractor the benefit of the doubt, and assume programmers are of good faith – and put assertions:

public class PassFilterTest {

    private PassFilter passFilterFive;

    @BeforeMethod
    protected void setUp() {
        passFilterFive = new PassFilter(5);
    }

    @Test
    public void should_pass_when_filtering_one() {
        boolean result = passFilterFive.filter(1);
        Assert.assertTrue(result);
    }

    @Test
    public void should_not_pass_when_filtering_ten() {
        boolean result = passFilterFive.filter(10);
        Assert.assertFalse(result);
    }
}

Still 100% code coverage and 100% line coverage – and this time, “real” assertions! But it still is no use… It is a well-know fact that developers tend to test for passing cases. In this case, the two cases use parameters of 1 and 10, while the potential bug is at the exact threshold of 5 (should the filter let it pass or not with this value?).

In conclusion, the raw Code Coverage only guarantees the maximum possible Code Coverage. If it’s 0%, of course, it will be 0%; however, with 80%, it gives you nothing… just the insurance that at most, your code is covered at 80%. But it can also be anything in between, 60%, 40%… or even 0%. What good is a metric that only hints at the maximum? In fact, in this light, Code Coverage is a Bloom Filter. IMHO, the only way to guarantee that test cases and the associated test coverage are really meaningful is to use Mutation Testing. For a basic introduction to Mutation Testing, please check my Introduction to Mutation Testing talk at JavaZone (10 minutes).

The good thing is that Mutation Testing is not some kind of academic paper only known by nerdy scientists, there tools in Java to start using it right now. Configuring PIT with the previous test will yield the following result:

This report pinpoints the remaining mutant to be killed and its associated line (line 12), and it’s easy to add the missing test case:

@Test
public void should_not_pass_when_filtering_five() {
    boolean result = passFilterFive.filter(5);
    Assert.assertFalse(result);
}

Now that we’ve demonstrated without doubt the value of Mutation Testing, what do we do? Some might tried a couple of arguments against Mutation Testing. Let’s have a review of each of them:

  • Mutation Testing takes a long time to be executed. For sure, the combination of all possible mutations takes much more longer than standard Unit Testing – which has to be be under 10 minutes. However, this is not a problem as Code Coverage is not a metric that has to be checked at each build: a nightly build is more than enough.
  • Mutation Testing takes a long time to analyze results. Also right… but what of the time to analyze Code Coverage results that, as seen before, only hint at the maximum possible Code Coverage?

On one hand, the raw Code Coverage metric is only relevant when too low – and requires further analysis when high. On the other hand, Mutation Testing lets you have confidence in the Code Coverage metric at no additional cost. The rest is up to you…

Send to Kindle
Categories: Development Tags: ,

Throwing a NullPointerException… or not

September 28th, 2014 7 comments

This week, I’ve lived again an experience from a few years ago, but in the opposite seat.

As a software architect/team leader/technical lead (select the term you’re more comfortable with), I was doing code reviews on an project we were working on and  I stumbled upon a code that looked like that:

public void someMethod(Type parameter) {
    if (parameter == null) {
        throw new NullPointerException("Parameter Type cannot be null");
    }
    // Rest of the method
}

I was horribly shocked! An applicative code throwing a NullPointerException, that was a big coding mistake. So I gently pointed to the developer that it was a bad idea and that I’d like him to throw an IllegalArgumentException instead, which exactly the exception type matching the use-case. This was very clear in my head, until the dev pointed me the NullPointerException‘s Javadoc. For simplicity’s sake, here’s the juicy part:

Thrown when an application attempts to use null in a case where an object is required. These include:

  • Calling the instance method of a null object.
  • Accessing or modifying the field of a null object.
  • Taking the length of null as if it were an array.
  • Accessing or modifying the slots of null as if it were an array.
  • Throwing null as if it were a Throwable value.

Applications should throw instances of this class to indicate other illegal uses of the null object.

Read the last sentence again: “Applications should throw instances of this class to indicate other illegal uses of the null object“. It seems to be legal for an application to throw an NPE, even recommended by the Javadocs.

In my previous case, I read it again and again… And ruled that yeah, it was OK for an application to throw an NPE. Back to today: a dev reviewed the pull request from another one, found out it threw an NPE and ruled it was bad practice. I took the side of the former dev and said it was OK.

What would be your ruling and more importantly, why?

Note: whatever the decision, this is not a big deal and probably not worth the time you spend bickering about it ;-)

Send to Kindle

Thank you Mr Beck

September 21st, 2014 No comments

Two weeks ago, I was at the JavaZone conference (in Norway) for the first time. There, I facilitated a Vaadin 7 workshop and presented an Introduction to Mutation Testing. Moreover, I attended many great talks by brilliant speakers, but one was really head and shoulders above the lot: “Software Design, Why, When and How” by Kent Beck.

For those of you that don’t know about Mr Beck: he’s the co-author of the JUnit testing framework, he created Extreme Programming, he is at the origin of Test-Driven Development methodologies and much much more… This is just to say that I was expecting much from the talk, especially since Software Design is at the root of most of my work though I’ve been disappointed by so-called “star” speakers in he past.

The first thing to note is that the talk took place in an unusual room, as the stage was set between two opposite sets where half the audience was located. In essence, you could speak only in front of  half the people at any one time. Not an easy feat! Also, I was very surprised by Mr Beck not using any slides in his talk. Of course, he probably had some piece of paper somewhere but the magic is that his talk was very fluid. Given the amount of time it takes me to prepare my talks with slides, I can only wonder at the time it took him to prepare without. In the end, the result was impressive!

The content of the talk, however, was all about a single and very simple message: Software Design is all about context. Sometimes, you need to design upfront, sometimes, it will cost more. Sometimes, it’s better to refactor, sometimes, not. Sometimes, one should refactor now, sometimes later. And so on. In essence, the meme about code duplication being bad is just that, a meme. This is despite the fact that Software Designers need to care about efficiency first and about how to best use scarce resources, i.e. time.

The last part of the talk was devoted to three main qualities of a Software Designer:

  • Tolerance to ambiguity
  • Ability to postpone decisions
  • Social skills [sic]

This talk really stroke a chord in me as my studies were not in Computer Sciences but in Architecture (as in buildings). At this time, I was very pissed off that Architecture was not a real science, that there was no right or wrong answer and that you were never completely sure to have an adequate solution until the thing is finally built. This uncertainty was really a burden at that time, and I went to software development because either my code compiled – or not, and my application produced the expected output – or not. But with Software Design, that’s exactly as in Architecture (as in buildings, remember?), it’s all about context and gut feeling and experience.

All in all, this was really a great show. Even better, I went to him after the talk to tell him about the Architecture stuff and his conclusion is the following:

Good decisions come from experience
Experience come from bad decisions
- Kent Beck at JavaZone

This just exactly match my experience, as I’ve made plenty of bad decisions in my career, so I guess I’ve plenty of material to take good decisions from in the future ;-)

And as for those who want to enjoy the integrality of the talk, here it is in all its glory. Thank you Mr Beck.

Send to Kindle
Categories: Technical Tags:

Another valid Open/Closed principle

September 15th, 2014 1 comment

I guess many of you readers are familiar with the Open/Closed principle. It states that:

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification
- Meyer, Bertrand (1988). Object-Oriented Software Construction

This other Open/Closed principle is completely unrelated, but just as important. It states that:

When “something” is opened by one’s code, one MUST close it as well!
-Me (2014). My bathroom

Simple enough? Then why do I regularly stumble upon database connections not closed (i.e. released to the pool), sockets as well, input streams not closed, output streams not closed, etc.? (But to be honest, I also am guilty of sometimes forgetting the later). When resources are not released just after their use, it might generate memory leaks. Other possible consequences are related to the resource’s nature: for example, when not releasing database connections, sooner or later the pool will be exhausted so that no new connections to the database can be acquired – and basically your application will be unusable, requiring a reboot of the application server.

Still, nothing prevents us from taking care of closing the resource, there are just some little things to address:

  1. As seen above, closing a resource is not an option, it must be ensured. Java makes it possible through the finally block (so that a related try block is necessary as well).
  2. Most close() (or release() or destroy() or what have you) method signatures throw a checked exception. If you really want my opinion, this is a design mistake but we developers have to deal with it (and to be honest, this is not the first time someone made a decision where I had to handle the consequences of, that’s know as Management 1.0).

Here’s a very simple example:

File file = new File("/path/to/file");
FileInputStream fis = new FileInputStream(file);
try {
    // Do something with file
} finally {
    fis.close();
}

Note line 6 uses a method whose signature throws a checked exception and must be dealt accordingly. As in most cases, exception thrown while closing hard hardly recoverable (read not at all), not throwing it further is more than a valid option. Instead of further cluttering the code, just use Apache Commons IO‘s IOUtils.closeQuietly() (or its database counterpart Apache Commons DB‘s DBUtils.closeQuitely()).

The finally block above can be replaced as follows:

finally {
    LOGGER.log("Couldn't close input stream on file " + file.getAbsolutePath());
    IOUtils.closeQuietly(fis);
}

(Yes, logging that a resource cannot be released is a good practice in all cases)

Finally (no pun intended), one might remember that Java 7 brings the AutoCloseable interface along with the try-with-resources syntax. This makes it even simpler to handle the close() if the method signature doesn’t throw an exception:

try (StringReader reader = new StringReader(string)){
    // Do something with reader
}

(Note StringWriter.close() signature throws an exception, even though it does nothing)

In conclusion, remember that Continuous Integration platforms are your friend and tools such as Sonar (or Checkstyle, PMD and FinddBugs) are a good way to check unreleased resources.

Send to Kindle
Categories: Java Tags:

The best there is at what it does

September 7th, 2014 No comments

Before anything else, please check the reference to the title if you didn’t get it.

This week, Vaadin released its version 7.3 with the new easily configurable Valo theme. I just had to blog about this on my other blog, morevaadin.com, which uses Jekyll as static-site generation engine.  The problem I had to tackle is that not only did I not use Jekyll since 5 months, my laptop had been remastered and I had to re-install the software.

Now, with the help of my friend Google, I managed to install homebrew, rbenv, ruby-build and jekyll (yes, Jekyll is a Ruby gem) in the course of an evening. The same evening, I wrote my blog post, fixed the configuration as well as bad link reference and generated the site. Easy as pie, even though I didn’t touch the thing is so much time!

Today, my thoughts hovered around that fact: it is easy! Just like some other tools – like WordPress, are easy: easy to install, easy to configure and easy to use. In parallel, I thought about the original version of morevaadin.com I developed with Drupal. Let me tell you what: Drupal is extremely powerful but is a nightmare to configure. Making the switch from Drupal to Jekyll made my life easier a thousandfold.

The my mind wandered further and drew a parallel between simple programming languages and more powerful ones. This has been my experience when I tried to do some Scala workshop at the beginning of the year: after 6 months, I’ve been able to use only the simplest features, not the most powerful constructs. That had been sorely disappointing to me, as I realized I was worse in Scala than I thought.

I’m aware this parallel might be a little overstretched, however I cannot stop theorizing languages features power can be an asset but also a curse if one has to constantly keep using them to remember them. For example, I think that Java’s syntax is easy enough not only to use but also to remember, though I must conced I might be biased because I have more than 10 years experience developing in that language.

Whatever you design, tool, technique or language, it might be the best at what it does, but please consider that simplicity is a virtue.

Send to Kindle
Categories: Technical Tags:

Using exceptions when designing an API

August 31st, 2014 2 comments

Many knows the tradeoff of using exceptions while designing an application:

  • On one hand, using try-catch block nicely segregates between regular code and exception handling code
  • On the other hand, using exceptions has a definite performance cost for the JVM

Every time I’ve been facing this quandary, I’ve ruled in favor of the former, because “premature optimization is evil”. However, this week has proved me that exception handling in designing an API is a very serious decision.

I’ve been working to improve the performances of our application and I’ve noticed many silent catches coming from the Spring framework (with the help of the excellent dynaTrace tool). The guilty lines comes from the RequestContext.initContext() method:

if (this.webApplicationContext.containsBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) {
    this.requestDataValueProcessor = this.webApplicationContext.getBean(
    REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME, RequestDataValueProcessor.class);
}

Looking at the JavaDocs, it is clear that this method (and the lines above) are called each time the Spring framework handles a request. For web applications under heavy load, this means quite a lot! I provided a pass-through implementation of the RequestDataValueProcessor and patched one node of the cluster. After running more tests, we noticed response times were on average 5% faster on the patched node compared to the un-patched node. This is not my point however.

Should an exception be thrown when the bean is not present in the context? I think not… as the above snippet confirms. Other situations e.g. injecting dependencies, might call for an exception to be thrown, but in this case, it has to be the responsibility of the caller code to throw it or not, depending on the exact situation.

There are plenty of viable alternatives to exceptions throwing:

Returning null
This means the intent of the code is not explicit without looking at the JavaDocs, and so the worst option on our list
Returning an Optional<T>
This makes the intent explicit compared to returning null. Of course, this requires Java 8
Return a Guava’s Optional<T>
For those of us who are not fortunate enough to have Java 8
Returning one’s own Optional<T>
If you don’t use Guava and prefer to embed your own copy of the class instead of relying on an external library
Returning a Try
Cook up something like Scala’s Try, which wraps either (hence its old name – Either) the returned bean or an exception. In this case, however, the exception is not thrown but used like any other object – hence there will be no performance problem.

Conclusion: when designing an API, one should really keep using exceptions for exceptional situations only.

As for the current situation, Spring’s BeanFactory class lies at center of a web of dependencies and its multiple getBean() method implementation cannot be easily replaced with one of the above options without forfeiting backward compatibility. One solution, however, would be to provide additional getBeanSafe() methods (or a better relevant name) using one of the above options, and then replace usage of their original counterpart step by step inside the Spring framework.

 

Send to Kindle
Categories: Java Tags: , ,

Past, present and future

August 17th, 2014 3 comments

Dear readers,

This week won’t be a detailed technical article: last week’s was the 250th post on this blog, time for a little introspection, and thinking about the past and future. Speaking about the past, my first post was written on this blog on April 7th 2008 – more than 6 years ago, to announce I had successfully passed the Sun Certified Java Developer 5 :-) At that time, I didn’t really know what a blog was for, I just wanted to have one and I used it sometimes like Twitter today.

The first real technical article was written about the Display taglib on May 23rd of the same year. I guess it was the first that really counted, and I haven’t stopped writing from this point. I love my job – though I’ve changed employers since that time, and all my positions have given me material to blog about. I also try to dabble into unknown territory when I want to understand how software I do not use is working. If you’re a regular visitor, you might have noticed I try to write once per week, though I sometimes cannot hold the rhythm. However, some of you might know I’m currently also writing Integration Testing from the Trenches, which sometimes puts me in a quandary: should I write a new article or write another chapter of the book? So if you want to help me there, don’t forget to get your own copy ;-)

And for the future, well, it looks extremely interesting.

  • At JavaZone (Oslo – Norway), on September 11th, I’ll be holding a workshop on Vaadin. I’ll also use the occasion to give a lightning talk on Mutation Testing
  • I’ll be at JavaDay Kiev (Ukrain), on October 17th-18th for a workshop on Vaadin and a talk about Integration Testing
  • Going to Joker conference (St Petersburg – Russia) on October 20th-21st? Let’s meet there, my exact contributions are to be announced in the near future
  • Finally, I’ll finish October at Agile Tour London on the 24th for a talk about Integration Testing

If you happen to attend any of these events, don’t hesitate to say hello!

 

Send to Kindle
Categories: Technical Tags:

Sanitizing webapp outputs as an an afterthought

August 10th, 2014 No comments

For sure, software security should be part of every developer’s requirements: they should be explained and detailed before development. Unfortunately, it happens in real life that this is not always the case. Alternatively, even when it is, developers make mistakes and/or have to make with tight (read impossible) plannings. In the absence of security checks automated tools, sooner or later, an issue will appear.

I’ve been thinking about a way to sanitize the output of a large-scale legacy Spring MVC application in a reliable way (i.e. not go on each page to fix issues). Basically, there are 4 ways output is displayed in the HTML page.

# Name Sample snippet Description
1 Form taglib <form:input path=”firstName”> Outputs a bean attribute
2 Spring taglib <spring:message code=”label.name.first”> Outputs a message from a properties file
3 Java Standard Taglib Library <c:out value=”${pageContext.request.requestURI}” /> Outputs a value
4 Expression Language <span>${pageContext.request.requestURI}</span> Outputs a value

Spring taglibs

Spring taglibs are a breeze to work with. Basically, Spring offers multiple ways to sanitize the output, each scope parameter having a possibility to be overridden by a narrower one:

  1. Application scoped, with the boolean defaultHtmlEscape context parameter
    <context-param>
      <param-name>defaultHtmlEscape</param-name>
      <param-value>true</param-value>
    </context-param>
  2. Page scoped (i.e. all forms on page), with the <spring:defaultHtmlEscape> tag
  3. Tag scoped, with the htmlEscape attribute of the tag

There’s only one catch; the <spring:message> tag can take not only a code (the key in the property file) but also arguments – however, those are not escaped :

Hello, ${0} ${1}

A possible sanitization technique consists of the following steps:

  1. Create a new SanitizeMessageTag:
    • Inherit from Spring’s MessageTag
    • Override the relevant revolveArguments(Object) method
    • Use the desired sanitization technique (Spring uses its own HtmlUtils.htmlEscape(String))
  2. Copy the existing Spring TagLib Descriptor and create a new one out of it
  3. Update it to bind the message tag to the newly created SanitizeMessageTag class
  4. Last but not least, override the configuration of the taglib in the web deployment descriptor:
    <jsp-config>
      <taglib>
        <taglib-uri>http://www.springframework.org/tags</taglib-uri>
        <taglib-location>/WEB-INF/tld/sanitized-spring-form.tld</taglib-location>
      </taglib>
    </jsp-config>

    By default, the JavaEE specifications mandates for the container to look for TLDs insides JARs located under the WEB-INF/lib directory. It is also possible to configure them in the web deployment descriptor. However, the configuration takes precedence over automatic scanning.

This way, existing JSP using the Spring taglib will automatically benefit from the new tag with no page-to-page update necessary.

JSTL

The <c:out> tag works the same way as the <spring:message> one, the only difference being there’s no global configuration parameter, only a escapeXml tag attribute which defaults to false.

The same technique as above can be used to default to true instead.

EL

The EL syntax enables output outside any taglib so that the previous TLD override technique cannot be used to solve this.

Not known to many developers, EL snippets are governed by so-called EL resolvers. Standard application servers (including servlet containers like Tomcat) provide standard EL resolvers, but it is also possible to add others at runtime.

Note: though only a single EL resolver can be set in the JSP context, the resolver hierarchy implements the Composite pattern, so it’s not an issue.

Steps required to sanitize EL syntax by default are:

  1. Subclasses relevant necessary EL resolvers – those are ScopedAttributeELResolver, ImplicitObjectELResolver and BeanELResolver, since they may return strings
  2. For each, override the getValue() method:
    • Call super.getValue()
    • Check the return value
    • If it is a string, sanitize the value before returning it, otherwise, leave it as it is
  3. Create a ServletContextListener to register these new EL resolvers
    public class SanitizeELResolverListener implements ServletContextListener {
        public void contextInitialized(ServletContextEvent event) {
            ServletContext context = event.getServletContext();
            JspFactory jspFactory = JspFactory.getDefaultFactory();
            JspApplicationContext jspApplicationContext = jspFactory.getJspApplicationContext(context);
            ELResolver sber = new SanitizeBeanELResolver();
            jspApplicationContext.addELResolver(sber);
            // Register other EL resolvers
        }
    }

Summary

Trying to sanitize the output of an application after it has been developed is not the good way to raise developers concerns about security. However, dire situations require dire solutions. When the application has already been developed, the above approaches – one for taglibs, one for EL, show how to achieve this in a way that does not impact existing code and get the job done.

Send to Kindle
Categories: JavaEE Tags: , ,