Monday, January 28, 2013

Getting logback and slf4j to work in JBoss AS 7

As usual, it has to do with classloading and that JBoss internally also uses slf4j and logback. As everyone seems to state just about everywhere, JBoss classloading has completely changed in AS 7. Here's the recipe for this particular problem.

Create a file called "jboss-deployment-structure.xml" in the META-INF directory for an EAR or WEB-INF directory for a WAR. This file can contain a lot of different stuff to tweak the classloader, but for the logback case this is enough:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
   <deployment>
      <exclusions>
         <module name="org.apache.commons.logging" />
         <module name="org.apache.log4j" />
         <module name="org.jboss.logging" />
         <module name="org.jboss.logging.jul-to-slf4j-stub" />
         <module name="org.jboss.logmanager" />
         <module name="org.jboss.logmanager.log4j" />
         <module name="org.slf4j" />
         <module name="org.slf4j.impl" />
      </exclusions>
   </deployment>
</jboss-deployment-structure>

For the EAR case, you'll probably need to add a subdeployment for each application (both wars and ejbs) with the same exclusions. For more details, consult the JBoss documentation on the subject.

UPDATE

I ran into the same issue with log4j2 on EAP 6.3 and the recipe still works. It is important to add a separate exclusion for each sub-deployment or JBoss will eat your log messages and they'll go into the JBoss internal logger.

Monday, November 26, 2012

Thursday, September 13, 2012

Is SetCharacterEncodingFilter a thing of the past?

I thought so. But I was wrong. I thought after all those years of hacking the encoding parameters in our java application they had sorted it out. In our latest migration to JBoss EAP 5 i made sure that we didn't need those hacks. But we also had to change the jsp and response encoding to UTF-8 for other reasons.

This turned out bad. JBOSS is hard set to ISO-8859-1 internally which means that a form submission in UTF-8 will decode incorrectly. Now, we did set the accept-charset tag on all forms, but Internet Explorer ignores the property. We tried to hack the poor explorer with ugly javascripts which made it work. But finally we let in an added the good old encoding filter anyway.

Our options was to either change the page encoding to ISO. This would have broken an old external system (yepp, it's old, it must get UTF-8, it "can't" be changed). Or we could have changed the encoding settings in the JBoss configuration files. This would have broken other applications on the same server.

But still, why did the JBoss community decide to take this path? How does users in non-western countries do? Is JBoss designed for Europe only?

Thursday, August 30, 2012

Struts 2 convention plugin in a WAR in a EAR in Jboss

This issue has been bugging my for a while and I have not found any solution to it so far. It seems from google results that I am not alone with this problem.

The problem occurs when you have a Struts 2 convention based web application (WAR) inside an EAR package. And deploy it on jboss. Because of Jboss using the vfszip packaging the open symphony ClassFinder fails with a message like

c.o.x.u.f.ClassFinder - Unable to read URL 
    [vfszip:/.../server/default/deploy/MyEar.ear/MyWebApp.war/WEB-INF/classes/]
    java.io.FileNotFoundException: 
    /.../server/default/deploy/MyEar.ear/MyWebApp.war/WEB-INF/classes/ 

So. Nobody solved it in a good way yet. I'm gonna go with this solution, it'll have to do for now.

Update: I tried to implement the linked solution using reflections, but failed. Basically it has the same issue and I'm still left with hard coding the list of classes.

Friday, August 10, 2012

Surefire plugin wont run my JUnit tests!

I spent way to much time on this trivial issue to not write it down. I ran into an issue where my unit tests (JUnit 4) were running fine in Eclipse but not by the maven surefire plugin.

Google served up numerous solutions to my problem but it didn't help me. My problem was much simpler. Eclipse will run any test in any class where the method is annotated with @Test. This does not apply to surefire. If the class is not named Test, surefire will not even look for tests in it. Hence, in maven projects, we should always name test classes that way.

Friday, April 27, 2012

Code coverage on JDK7 with Emma

The latest upgrade to JDK7 did go without any issues what so ever in terms of application functionality.

The only issue so far is with Emma which stopped recording code coverage and turned to breaking tests instead giving an "Illegal local variable table length 5 in method" error instead.

What you need is this:
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.12</version>
  <configuration>
    <argLine>-XX:-UseSplitVerifier</argLine>
  </configuration>
</plugin>

Thursday, April 5, 2012

Relative file paths on JBoss EAP 5.1.2

Apparently there was a change in which kind of file URLs are correct in JBoss EAP 5.1.2. This tiny little change caused a great deal of pain in my case throwing
"IllegalArgumentException: URI is not hierarchical" in one environment but not the other.

Very well. We use the PropertyPlaceholderConfigurer with relative paths for file locations to greatly simplify the configuration differences between deployement and development environments. This is all done by simply stating
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>config/application.properties</value>
    </property>
</bean> 

In the applicationContext.xml to load properties from a path relative to the execution path. Running the application with maven jetty makes development rapid and simply and almost no setup is required for new developers.

With the latest change in JBoss, this could have become a very big issue. However, after a long days fiddling, here's the solution with maintained behavior.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>file:${user.dir}/config/application.properties</value>
    </property>
</bean>