Posts tagged struts 2

plans

Maybe you know, maybe no – it’s about five years as I’m involved in the Apache Struts project. About two years ago I became a Struts 2 Lead – whatever it means in non-profit organisation working on an opensource project where everyone is equal 🙂 Nevertheless I like what I’m doing – code and refactor 🙂 And as there is a plenty of code in the project and most of them need to be improved – I have what to do for the next few years 😀

Recently I’ve started working on a new plugin – the MVEL plugin – which will allow to use MVEL instead of OGNL to handle expressions. In theory the task wasn’t too difficult, Struts 2 already provides many extension points where you can hook in with your code. Replacing expression engine require to implement two interfaces – very simple and straightforward.  After I did that, I have started testing many possible expression syntaxes which are already present in unit tests.

And then problems show off :/ The main problem is conversion, to give you a hint check the below expression which simple means array in both – MVEL and OGNL

{1,2,3}

but the problem is how both engines handle such statement (pseudo code):

  • MVEL:
    new Object[]{Integer, Integer, Integer}
  • OGNL:
    new ArrayList(){Integer, Integer, Integer}

As you can see the difference is slight but important – the wrapping object is totally different. And then goes conversion logic, as I wanted to get string on output, built-in conversion mechanism do this:

  • MVEL: [1]
  • OGNL: [1,2,3]

Not so good 😉 The problem is that the conversion logic is too narrowed to OGNL. After some internal brainstorming I’ve came up with a plan – to allow other expression engines to work with Struts 2, first I must decouple conversion logic and OGNL 🙂 So the plan is:

  • extract conversion mechanism to allow replacement of it (another extension point)
  • simplify current logic related to converters created by users
  • implement more common logic to allow handle wide list of results
  • implement MVEL specific conversion
  • implement MVEL plugin 🙂

As you see the plan is simple, but as it is with plans – it is good to prepare them, but to follow them is a different story 😉

Finally, I found something interesting in the latest newsletter from TED – something about attention 🙂

do it as want to

Why do I like working with the Apache Struts 2? Because I can simple change the framework behaviour and customise it to what I needed. And not just because you have plenty of options to modify, but especially because you can simple develop your own class which can replace version provided by the framework. Yeah, you can replace almost every framework class – Struts 2 was designed with that on mind 🙂

Recently I got involved in working on some old issue – WW-1967 Dynamic Method Invocation, validator with ActionName-aliasName-validation.xml files. The problem is related to Dynamic Method Invocation functionality and how the name of validation definition XML file is created. By default the file name will base on an action class and defined alias name and suffixed with -validation.xml, eg:

<action name="Login" class="org.demo.example.LoginAction">
    <result>/example/Login.jsp</result>
</action>

for action defined as above, the validation definition file name will be constructed as follow:

LoginAction-Login-validation.xml

There be a problem when you want to use DMI to call any public action’s method – which isn’t the best practise, though 😉 Anyway for each method the same validation file will be used, which ins’t a good idea. So, if you try to call an action like this – Login!check.action, the above file will be used to validate input as method name isn’t included in logic used to resolve file name.

How it can be solved? Quite simply, validation is provided by ValidationInterceptor which delegates execution to ActionValidatorManager to perform the validation process. But the context name is constructed by the mentioned interceptor in method:

public String getValidationContext(ActionProxy proxy)

So, to solve the problem you can extend ValidationInterceptor and override the method to provide your own context name like below:

@Override
protected String getValidationContext(ActionProxy proxy) {
    if (dmiEnabled && StringUtils.isNotEmpty(proxy.getMethod())) {
         return proxy.getActionName() + "_" + proxy.getMethod();
    }
    return super.getValidationContext(proxy);
}

After that, the file name will be created as follow:

LoginAction-Login_check-validation.xml

I’ve prepared a small demo how to do it – just check it out from GitHub.

And at the end see this talk from TED and give 10 minutes to solve all your problems 🙂

struts2 improved validators

Recently I’ve worked on how to improve built-in validators in the Apache Struts 2. The basic idea was to allow specify configuration params of the validators as OGNL expressions. Till now you could only statically define these params which was a bit suboptimal. See the example below:

<validator type="stringlength">
    <param name="fieldName">myPurchaseCode</param>
    <param name="minLength">1</param>
    <param name="maxLength">10</param>
    <message>Your purchase code needs to be between 1 to 10 characters long</message>
</validator>

As you see you can only define minLength / maxLength as a static value which sometimes isn’t enough. Quite often you would like depend on a user input or assigned privileges to the user and so on. Having option to dynamically adjust the minLength and maxLength is a nice future, though 🙂

Someone else noticed the same and registered an issue WW-2923, I’ve extended it a bit and added all the sub-tasks to handle each available validator step-by-step. I had to change not only the code, but also documentation. Maybe it’s obvious but very frequently we (developers) forget about that – and then myth like JavaDocs are useless come to light 😉

Anyway, my first thought was to implement the enhancement based on the current param names and just add logic to parse param’s value as an OGNL expression, see below:

<validator type="stringlength">
    <param name="fieldName">myPurchaseCode</param>
    <param name="minLength">${minLenghtValue}</param>
    <param name="maxLength">${maxLengthValue}</param>
    <message>Your purchase code needs to be between ${minLength} to ${maxLength} characters long</message>
</validator>

The problem with this approach is that it breaks backward compatibility, also if you want to use just static values as above, there is an additional overhead – OGNL parser will try to evaluate the expression and fallback to the original value – which is costly.

Then I simple added another set of params to allow specify only these params as an OGNL expression, so you can decide when to use the static values or when to use expressions or when to mix all of them. Thus also simplify migration of existing applications as a developer can migrate each validation when he needs that.

<field-validator type="stringlength">
    <param name="minLengthExpression">${minLengthValue}</param>
    <param name="maxLengthExpression">${maxLengthValue}</param>
    <param name="trimExpression">${trimValue}</param>
    <message>Your purchase code needs to be between ${minLength} to ${maxLength} characters long</message>
</field-validator>

If you want to know more please read the docs. You can try to play with the latest build if you want to use this future. I’m going to work on another improvement in Apache Struts 2 🙂

reactivation

I’ve decided to reactivate my technical blog (in Polish) hosted on Java Developer’s Network – why? I’ve stared missing strict technical entries and discussion over them. And there are plenty of english technical blogs out there, so I didn’t want to be another one here. I’m still planning to post some small examples in English, but larges one will be posted there.

Few weeks ago I was moved to join a new project and for last two weeks I was trying hard to recall how JSF 2.0 works. It isn’t an intuitive way and for a guy as me – who was growing up on request-response paradigmate of the Web – the whole components approach is a big fake 😉 The frameworks are cheating us and the users, http protocol is stateless and over it we try to build a statefull application. Jsfize are flying in the air 😛

What else is going on? A lot, I can say. A brand new Apache Struts 2 is out – the web page should be updated soon (on my todo list), also we’ve a few new very active contributors and a new PMC Chair. It looks like we’ve a new opening 🙂

The fourth thing, another we are working to prepare upcoming annual Warsaw Java User Group conference – Confitura 2011 aka Javarsovia. It’s a hard peace of wood now, but hopefully we redo it in something nicer 😉

And the last thing – a new Agile conference in Warsaw is over the horizon – Agile By Example!

That’s it folks …. naha … what’s left is some new presentation from TED – not only software can be open sourced 😀

metrics and worm holes

It took me more time than I’ve expected to start the New Year on my blog. So here it is, the first post for the New Year! Happy New Year!

The last year I was at conference and attended to ‘s presentation about . This talk based on his post on the IBM’s web site about and the whole series.

The talk was about and – quite interesting tools to discover potential bugs and hard-to-maintain code in a project. What was the most important for me, Neal used the  project as an example, especially the class – you can find the details in the mentioned article. He presented how to prepare these metrics, how to read them and what they mean. A really interesting talk.

After all, I’ve asked Neal to give me more details about the problem and few days later I received an e-mail from him. I’ve followed his advice and inspired by his talk I’ve gave a promise to my self that I must improve that badly-looking code.

…. but wait, it’s just a badly-looking code. It had taken me another few weeks to discover it isn’t so important to improve that piece of code, it really doesn’t matter right now. There are plenty of places to improve code base of the project and so many users don’t care about that – UIBean doesn’t exist for them.

The current UIBean implementation do the job, it isn’t pretty or easy to maintain, but right now there is no one for whom it is important. No one complains about it. Some day I’ll refactor the code of UIBean class but today isn’t that day.

The conclusion is the same as for code optimization, you shouldn’t optimize too early, so you shouldn’t improve too early. Don’t throw everything and try to improve some bandwagonhost vps not-important part of your project. Don’t trust metrics by heart, they can lie to you, try to figure out what they mean in context of your knowledge of the project. They aren’t a silver bullet.

Today’s day brings to me another newsletter from web site and gave me answer to important question: the shortest connection between two points is …

are you affraid

The last two weeks I’ve been simplifying an application flow engine base on Apache Struts 1 – I know it’s a bit old technology but I don’t care, I have a job to do 😉infolio-rg.ru

Anyway I discovered lot of strange use cases where some custom mechanism was build instead to use what was already provided with the framework. It was like inventing a wheel once again! Frankly, I was truly surprised how someone could do this that way. And I start thinking what was the reason to do that…

The only thought came to the mind that someone was afraid to use what was already provided to him with Apache Struts 1 – he didn’t know the framework well, he was too lazy to check sources, and so on. I was real devastated! If someone doing application in such way, no framework will help him or do the job for him!

Recently I’ve been solving issues in Apache Struts 2 and one of them was to add wildcard support to a file upload mechanism. Provided patch had solved that problem with some home made RegExp engine. I just added a test case to proof it was working properly and committed all the changes to a source code repository. After that a more experienced Committer pointed me out that I should use existing PatterMatcher class instead, what I did and the code looks much better right now. You can see an example here Apache Struts 2 useful beans.

community day

I spent the whole day working with Apache Struts 2 Maven archetypes – it’s an open source project hosted at struts.apache.org – basically Action Base Java Web framework.

During that I discovered strange Maven behaviour – when I lunched it with -o option (work in offline mode) it wasn’t be able to find installed archetypes. To clarify – I prepared a script that will build up the archetype from source code, install it in my local Maven repository, then create basic application base on that archetype and lunch them, the source is below:download movie Collateral Beauty

#!/bin/sh
if [ -e demo ] ; then
    rm -R demo
fi
cd $1
mvn clean install
cd ..
mvn -o archetype:generate -DgroupId=org.demo
    -DartifactId=demo -Dversion=1.0-SNAPSHOT
    -DpackageName=org.demo
    -DarchetypeArtifactId=$1
    -DarchetypeGroupId=org.apache.struts -DarchetypeVersion=2.1.8
    -DinteractiveMode=false
cd demo
mvn jetty:run
cd ..

$1 – it’s a command line parameter specifying archetype folder which is also archetype name

So it shouldn’t be needed to access remote archetype repository to download archetype – it’s already in local repository! I tried that with different Maven versions – the latest 2.2.1 and with 2.0.10 – with both was the same.

After some time and many experiments I found the solution – do not use -o option used -B instead! And that I was able to test one archetype – another 3 are waiting!

Go to Top