Friday, September 21, 2007

Opening JBoss AS HTTP Traffic Up To More Than Localhost

JBoss by default binds only to 127.0.0.1  So to open it up, use:

run -b <your machine's IP address>

To really do it right: Secure JBoss wiki page

Blather: I went to show off my latest Seam, Ajax4jsf, Richfaces suggestionBox/autocomplete widget to a coworker on JBoss AS 4.2 and had problem when I tried run against anything but localhost. Even on my own machine, but using my full hostname, the browser behaved strangely, not even giving a decent status code or anything. I used the Firefox Tamper plugin (Tamper + Firebug + Web Tools = web developer nirvana [okay, I stole this tagline from somewhere else in my web travels]) to see that the request status was "pending". Perhaps that is how JBoss goes stealth against port sniffing. Anyway, I figured it was just a security setting based on the principal of requiring developers to have to conscientiously open up security. But after reading the fine manual, I still didn't find it. Turns out this is a very popular question in the forums though. And, it was actually in the readme.html (sadly I missed it there) under "Configuration Issues" for 4.2.0 GA (however, I stopped reading at 4.2.1 GA--seems it should be under 4.2.1 since it still affects it).

For those googling:
Unable to connect connection
Internet Explorer cannot display the webpage

Thursday, September 13, 2007

Turning on Hibernate Logging using Seam on JBoss 4.2

At some point, you're going to need to see the sql and the bind variables that hibernate is using. When running Seam on JBoss AS 4.2 and above, there are a couple things you need to do. First, add the following lines to <jboss home>/server/default/conf/jboss-log4j.xml

<category name="org.hibernate">  
<priority value="TRACE"/>
<appender-ref ref="HIBERNATE"/>
</category>


This tells log4j to start logging hibernate at a very high detail.
Next, make sure persistence-dev.xml has the hibernate.show_sql property set to true.

<persistence-unit name="AutoPropPass5">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/AutoPropPass5Datasource</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.show_sql" value="true"/> <============ HERE
<property name="jboss.entity.manager.factory.jndi.name" value="java:/AutoPropPass5EntityManagerFactory"/>
</properties>
</persistence-unit>


Then, add commons-logging.jar to the project's war lib directory and tweak build.xml to include this jar in the deployment:

<copy todir="${war.dir}/WEB-INF/lib">
<fileset dir="${lib.dir}">
<include name="ajax4jsf*.jar" />
<include name="richfaces*.jar" />
<include name="oscache*.jar" />
<include name="commons-digester-*.jar" />
<include name="commons-beanutils-*.jar" />
HERE ============> <include name="commons-logging*.jar" />
<include name="jsf-facelets.jar" />
<include name="jboss-seam-*.jar" />
<exclude name="jboss-seam-gen.jar" />
</fileset>
</copy>


When this is all in place, you should be able to see output like the following in <jboss home>/server/default/log/server.log:

2007-09-13 09:34:55,854 TRACE [org.hibernate.type.StringType] binding 'updi' to parameter: 1
2007-09-13 09:34:56,823 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2007-09-13 09:34:56,823 TRACE [org.hibernate.jdbc.AbstractBatcher] closing statement
2007-09-13 09:34:56,823 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
2007-09-13 09:34:56,823 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
2007-09-13 09:34:56,823 DEBUG [org.hibernate.util.JDBCExceptionReporter] could not execute query [select pass0_.PASS_ID as PASS1_35_, pass0_.ADDRESS as ADDRESS35_, pass0_.state as state35_, pass0_.VERSION as VERSION35_, pass0_.reason as reason35_, pass0_.status as status35_, pass0_.DESTINATION as DESTINAT7_35_, pass0_.INS_UPD_ID as INS8_35_, pass0_.INS_UPD_TS as INS9_35_, pass0_.PASS_HOLDER_PID as PASS17_35_, pass0_.PASS_CREATOR_PID as PASS18_35_, pass0_.HOLDER_GROUP_ID as HOLDER10_35_, pass0_.HOLDER_GROUP_SUP_PID as HOLDER11_35_, pass0_.CHECKOUT_DATE as CHECKOUT12_35_, pass0_.REMOVE_DATE as REMOVE13_35_, pass0_.DUE_DATE as DUE14_35_, pass0_.ADDRESS2 as ADDRESS15_35_, pass0_.CITY as CITY35_ from ERMPMGR.PP_PASS pass0_, ERMPMGR.PP_PERSON_MV person1_ where pass0_.PASS_HOLDER_PID=person1_.PERSON_ID and (upper(person1_.FULL_NAME) like upper(?+'%'))]
java.sql.SQLException: ORA-01722: invalid number

at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:124)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:304)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:271)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:625)
...


Notes:

  • Older versions of JBoss used a different file than jboss-log4j.xml (perhaps log4j.xml) and perhaps put a log4j.properties in the META-INF dir.

  • TRACE is used instead of DEBUG which worked in prior versions.

  • I'm not positive the {hibernate.show_sql bit is required, but seam-gen puts it in there by default.


In case your wondering why I was getting the "invalid number" error, it's because Oracle uses the || symbol for string concatenation, not +. When I fixed that, it started working.