Tuesday, September 25, 2007

Installing Roller 3.1 on WebSphere 5.1 - Part 2

Before going into the null pointer issue we saw at the end of Part 1, I came across couple of more issues, which need to be addressed first.

Roller.tld

This, needs to be defined in the web.xml, with right uri, otherwise, we get this error:
/index.jsp(36,0) File "http://www.rollerweblogger.org/tags" not found

<taglib id="tagLibRef_1">
<taglib-uri>http://www.rollerweblogger.org/tags</taglib-uri>
<taglib-location>/WEB-INF/tlds/roller.tld</taglib-location>
</taglib>

I moved the tld file from classes/META-INF/tlds/ to WEB-INF/tlds/.

LocalTransactionContainment

Whenever I access any roller page, I get the following error:
[9/20/07 15:15:45:536 MDT] 23d768b9 WebAppTransac E WTRN0043I: LocalTransaction rolled-back due to setRollbackOnly.[9/20/07 15:15:45:538 MDT] 23d768b9 WebGroup E SRVE0026E: [Servlet Error]-[LocalTransaction rolled-back due to setRollbackOnly]: com.ibm.ws.LocalTransaction.RolledbackException at com.ibm.ws.LocalTransaction.LocalTranCoordImpl.cleanup(LocalTranCoordImpl.java:1091)

According to the Servlet 2.3 specifications, all transactions should be committed or rolled back within the transaction boundries, in this case, servlet method execution. Now, these could just be select statements also.

One of the solutions to this issue, as described in WebSphere documentation is to edit the ibm-web-ext.xmi file, to include config for each servlet to have either commit or rollback the local transaction. I added this for all the servlets......but, no luck. Keep getting this error.

I then realized that even though, it is printing whole stacktrace, it may not really be the root of errors. So, looking further down, I found this NullPointerException-

RollerRuntimeConfig

So, the null pointers coming all the time is not allowing me to get to the registration page.

javax.servlet.ServletException: ServletException in '/WEB-INF/jsps/tiles/tiles-simplepage.jsp': null

The null pointer indicates that it is getting null for site.name etc. These are given default values in rollerRuntimeConfig.xml file. So, why null? Is that file not read?

There is no error in the logs that this XML file could not be found or failed to load. I had to now look at the roller source code to figure out what's happening. Infact, I put more debug statements in the code to see the values for each of these config parameters.

Well, everything is loaded fine. But, still null pointer when the jsp is looking for these parameters.

Going further deep, it is found that the code, at initialization, reads this xml file, and then stores these properties in the roller_properties table. And when JSP or any other code is getting the values for these, they come from the database.

Ok, lets check the database - roller_properties table. There is only one record, about database.version. No other properties read from XML are in there. That means the database insert is failing? How did it make just one entry though?

No idea, but that was the root cause of all these null pointer exceptions. In order to move forward, I decided to manually enter the default properties in roller_properties table. After adding all the required default properties in the table, I was able to proceed.

Like:
insert into roller_properties values ('site.name', 'roller');

Register First User

Ok, now, I can get beyond the first page. Infact, I can get to the registration page, and register the user. The first user registered will have all admin rights, so, this was really good.
Registration is simple, got it fine. Then, I try to login.....grrr.

Acegi Security

When I login with the registered userid and password, I get this:

Error occurred while invoking error reporter com.ibm.ws.webcontainer.servlet.LoadTargetServletFailure: Failed to load target servlet [FormLoginServlet]

FormLoginServlet, I guess this comes into picture only when Security is enabled in WAS. This is WebSphere specific servlet, and comes into play when login action is sent to j_security.

Looking into login.jsp, it is sending it to j_security_check. Ok, but there is no security enabled in websphere, so, may be that's why it is not finding this servlet. But, I don't want to use WebSphere security. I want to, for now, use simple jdbc authentication so that I can get into roller as admin.

This forced me to look at Acegi security documentation and code. It seemed simple that posting to non j_security_check should call the Acegi filters, rather than calling the app server's FormLoginServlet.

Let's get into security.xml, and make sure jdbcAuthenticationDao bean has right property value set for jndiName.
Next, look at authenticationProcessingFilter bean in same security.xml and update the property value from j_security_check to something else, I chose a_j_s for testing.
Now, go to login.jsp, and change the action to go to a_j_s instead of j_security_check.

Recycle the server. And wow...... I can login now!

Couple of more things:
rollerProperties.jsp - it uses JSTL 1.1 URI, so change it to use JSTL 1.0 URI, as we did in taglibs.jsp.
Also, roller.properties file has upload and search index directories defned, make sure they have trailing slash, otherwise it will give - can't access directory error.

Great.... now I am able to create the first blog.

I am still getting transaction rolledback exception, but only initially, it must be coming out of Acegi code, as it uses Spring, and since that code is executed very minimal after you are authenticated and authorized, the error doesn't show up every time you do something. But still, the error/warning is present in the logs, without causing any known harm.

No comments: