Thursday, April 30, 2009

s:text not working on GAE

Whoa, ran into a tiiiny weeeny limitation on GAE concerning struts. The main i18n tool, the s:text tag does work because of security issues. I couldn't find anything on this on google unfortunately.
What you get is just a:
java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private static final java.util.concurrent.ConcurrentMap

I'll get back to this as soon as I find something, this is pretty important.

Update: This seems like an issue hitting alot of features of struts 2. The sandbox jvm does not allow the application to access the system class loader, which seems to be used to access resources (on classpath), such as property files and scanning for classes.

Struts/OGNL on GAE

Trying to run struts 2 on GAE I've ran into a number of issues. This is one of them. Apparently the object traversing language OGNL have a security manager which does not agree with the jvm in GAE. To disable it, just call OgnlRuntime.setSecurityManager(null) (kudos). Otherwise you'll get this error message:
Method [public void org.apache.struts2.dispatcher.StrutsResultSupport.setLocation(java.lang.String)] cannot be accessed

Put the snippet in a ServletContextListener and it'll be executed on startup.

Adjusting maven to the eclipse GAE project

As I mentioned in my previous post. The war directory location in the eclipse project cannot be changed, the GAE plugin wont understand this. Instead we have to adapt maven to this.

First off, enable maven for the project. Just create the pom.xml with some basic content.

<project xmlns="http://maven.apache.org/POM/4.0.0" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelversion>4.0.0</modelversion>
<groupid>com.appspot</groupid>
<artifactid>maven</artifactid>
<packaging>war</packaging>
<name>maven</name>
<version>0.0.1-SNAPSHOT</version>
</project>

Now, change the war directory in maven by adding a plugin configuration for maven war plugin and set the war source directory.

<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-war-plugin</artifactid>
<version>2.0</version>
<configuration>
<warSourceDirectory>${basedir}/war</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>

After this you can update your project configuration from maven and it'll work out pretty well. However, eclipse will display an error about the target directory is not corret. Just click quickfix and then accept the change and it is corrected.

To be able to run the bundled jetty server via the eclipse plugin, you must run mvn war:inplace to add the maven managed libraries to the WEB-INF/lib directory.

Adjusting GAE eclipse plugin for maven

The last months, I've been working in a application maintenance team. Yes I know, it sucks. But since I met with the CEO of the company I work for (which happens to be in the top 10 worldwide) he inspired me that working with maintenance is vital to understanding how to write maintainable applications in the future. He admitted that most people dislike it, but it is also what most developers do in the industry.

Even worse, I'm maintaining Microßoft-based applications. C#, VB, MSSQL. That shit. Throw in a little oracle as well to top it of.

So now, I'm looking at trying out something modern on my spare time. GAE (Google App Engine) released java support some time ago and I managed to get an account. I strongly like eclipse and the ease of deploying applications from it. However, the applications are not structured to my liking, which is the maven convention, and I want them all to look the same, and build the same way. In the name of maintainability. What I want to do basically, is to create a project for app engine, with the maven structure and add some of the eclipse stuff to it.

First, create a new GAE project using the eclipse plugin. You now have a project with some basic directories and files. Just hit deploy to send it the GAE and get the Hello World servlet up.

Next, we have to move and separate source and resource directories. This is no problem whatsoever. Just separate the resource and java files to src/main/resources and src/main/java respectively.

The war directory cannot be moved, as of now. So we'll have to leave it where it is (sucks).

Next. I want a faceted project with the dynamic web module (just because other java projects are like this). To enable the facet, just go into project properties and enable the java facet with version 1.6 and then the dynamic web module facet. Watch out! A notification with be displayed to configure the facet, you have the click it and change the web content directory, or you'll have a nice WebContent directory to deal with.

Most facet setting cannot be changed from Eclipse. You can however do this yourself.

If you missed out changing the war directory, edit .settings/org.eclipse.wst.common.component and set wb-resource::source-path to /war.
The web module version is default set to 2.4, if you need to change this, edit the file .settings/org.eclipse.wst.common.project.facet.core.xml

Those two files can be added to source control as well to get people started faster (maintenance thinking again).
fp