Friday, September 28, 2007

Spring 2.0 schemas not found? And the solution is...

We've experienced a mysterious problem that the Spring 2.0 schemas could not be found when the application context is being created inside an EJB 2.1, using Spring's AbstractStatelessSessionBean.

The problem manifests itself with the following exception:
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 18 in XML document from class path resource [springContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
Caused by:
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)


Normally this is caused by the incorrect XML namespace or schema location declaration at the head of the application context. However, in our case, the declaration was correct:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
...
</bean>


After some research, we found that other people have also experienced this problem.

The cause is that somehow the "META-INF/spring.schemas" and "META-INF/spring.handlers" files packaged in spring.jar could not be found.

What are these two files?
  • "spring.schemas" specifies the classpaths of all Spring schemas within the spring.jar. The content of this file is listed below:

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/tx/spring-tx-2.0.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd

http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/tx/spring-tx.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd

  • "spring.handlers" specifies the handler class that implements the NamespaceHandler interface for each namespace. The content of this file is listed below:

http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler

One raised the topic in Spring's support forum that it was because of no internet access for the application server to access the schemas over the internet. Another post even provided a solution to reference the schemas using classpath prefix directly in the application context configuration files.

However, that's not the root cause and a good solution, because even if the application server can access the schemas over the internet or via classpath prefix, the bootstrap code still cannot access the "spring.handlers" file and would not know how to handle various namespaces other than the default "beans".

In fact, the root cause is that the META-INF directory of a can be blocked when referenced inside an EJB jar.

I tried a few ways to get around this problem, and the final solution I adopted is to extract these two files and put them in the META-INF directory of a JAR file that contains only this directory, and place this JAR file in the lib/ext directory of the application server domain where the application is deployed.

I hope this would help others who may face this problem.

Tuesday, September 25, 2007

Nice improvements in NetBeans 6.0

NetBeans 6.0 Beta 1 has been released since last week.

There are a few nice improvements that I have been waiting for:

1) Different font style for different scoped variables.
In NetBeans 5.5.1 and earlier versions, all variables have the default black colour, unlike Eclipse, which displays instance variables in blue and static variables in italic.
NetBeans 6.0 has finally caught up. Now the instance variables are in green and static variables/methods are also italic.

2) Visual JSF page editing now supports message resource bundles.
Previously, when using visual editing of a JSF page, if you need to display a label with text from a resource bundle, you have to manually edit the JSP pages. The resulting components are not displayed on the canvas.
This has been improved. Now these components are displayed on the canvas with the text from the default base.

Nice, isn't it? I may consider switching from MyEclipse to NetBeans 6.0 when it's finally out.

Wednesday, September 19, 2007

Won an IntelliJ IDEA 6.0 licence!

Tonight I went to the Sydney Java User Group's Lightning Talks Night hosted by Atlassian, and won the random audience draw. Among three rewards: a Sun umbrella, a "Java Concurrency in Practice" book and an IntelliJ IDEA licence, I chose IntelliJ IDEA, since: 1) who needs an umbrella in Sydney? 2) I have already got that book, though I haven't started reading...

I used IntelliJ at work previously. But we switched to MyEclipse, mainly because it's easier to find developers with Eclipse experience on the market, and also because the licence is much cheaper.

IntelliJ IDEA is actually a pretty cool IDE. One of the plugins I'd like to try out is the Grails plugin...

I'm also playing with NetBeans 6.0. The beta 1 has just been released.

If I have time, I will try to blog about my experience with these IDEs: Eclipse (and MyEclipse), IDEA and NetBeans...