Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Tuesday, May 19, 2009

Fix: Spring-based JNDI lookup can't see .properties file

After refactoring one of our internal applications at work to use Spring XML configuration file based JNDI lookup today, several of the application's unit tests which involve testing of JNDI lookups started failing. The following error appeared for each failed test in the jUnit XML log file:

<error message="Error creating bean with name '[dsName]':
Invocation of init method failed; nested exception is
  javax.naming.NoInitialContextException: Need to specify class name in
  environment or system property, or as an applet parameter, or in an
  application resource file:  java.naming.factory.initial"
type="org.springframework.beans.factory.BeanCreationException">
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
  .initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
  .doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
... (snipped for brevity) ...
at org.springframework.context.support.ClassPathXmlApplicationContext
  .<init>(ClassPathXmlApplicationContext.java:83)
at [internal namespace].util.TestUtil.getSpringContext(TestUtil.java:167)

Cause

We discovered that the cause of the problem in our case was that, as the error message indicated, Spring wasn't seeing a .properties file present in the project which set a value for the java.naming.factory.initial property.

The line in our Spring context .xml file looked like:

<jee:jndi-lookup id="[dsName]" jndi-name="jdbc/[dsPath]/[dsName]"
  expected-type="javax.sql.DataSource" />

The line in our .properties file (which Spring wasn't finding properly), which set the naming factory class to a class provided by our J2EE application server (WebLogic), was:

java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory

The .properties file was located in the same folder as the Spring context .xml file.

Solution

In the Spring context .xml file, just prior to the jee:jndi-lookup tag, we added a bean of type PropertiesFactoryBean to act as a pointer to the .properties file:

<bean id="jdbcConfiguration"
  class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="classpath:productInquiry.properties"/>
</bean>

Then, we added a reference to that new bean to the existing jee:jndi-lookup tag (the added part is bolded):

<jee:jndi-lookup id="ot1ds" jndi-name="jdbc/[dspath]/[dsname]"
  expected-type="javax.sql.DataSource" environment-ref="jdbcConfiguration"/>

This change fixed the problem, and got our tests to run successfully.

I hope this is helpful to someone!

Wednesday, February 25, 2009

Getting JAX-WS to work with WebLogic 9.2

I spent several hours at work today troubleshooting problems related to getting JAX-WS (as included with Apache CXF) working in a Java web application running under BEA (Oracle) WebLogic 9.2.  This post contains a summary of the errors I encountered, and their resolutions -- hopefully this will save someone some of the troubleshooting time that I spent today.

Background

Some brief background: I was building some new SOAP web service integrations into one of our internal Java applications, which runs on WebLogic server.  This application was the client side of the integration.  I used Spring, Apache CXF, and JAX-WS to build the integrations.

I first coded the SOAP integrations into a simple stand-alone Java application, and that worked fine.  However, when I plugged my code and the CXF .jar files into the "real" application running on my local WebLogic server, I ran into a couple of errors.

Error #1: "java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude"

Upon running my application under WebLogic 9.2, I got this error in the WebLogic server log file:

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'internalBeanName': Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public java.lang.Object org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create()]
threw exception; nested exception is java.lang.NoSuchMethodError: javax.jws.WebMethod.exclude()Z

This error turned out to be caused by the fact that in addition to the javax.jws.WebMethod class included in the geronimo-ws-metadata_2.0_spec-1.1.2.jar file included in the distribution of CXF that I downloaded, another (apparently older) implementation of that class is also included in the weblogic.jar file included with WebLogic 9.2.  WebLogic by default assigned priority to classes from its own weblogic.jar file over classes included with my application; as a result, WebLogic tried to use the older implementation of the javax.jws.WebMethod class, which does not include the exclude() method, and the NoSuchMethodError occurred when the other JAX-WS code tried to access that method.

To fix this, I modified my weblogic.xml and weblogic-application.xml files, to instruct WebLogic to give priority to the JAX-WS implementation in my own supplied .jar files rather than its own JAX-WS implementation. 

In my weblogic.xml, I added:

<container-descriptor>
  <prefer-web-inf-classes>true</prefer-web-inf-classes>
</container-descriptor>

For more on this weblogic.xml change, see documentation on a similar issue affecting Apache Axis.

In my weblogic-application.xml, I added:

<prefer-application-packages>
    <package-name>org.apache.xerces.*</package-name>
    <package-name>javax.jws.*</package-name>
</prefer-application-packages>

For more on this weblogic-application.xml change, see the WebLogic configuration documentation in the CXF documentation.

Error #2: "Your JAXP provider [...] does not support XML Schema"

Having resolved the NoSuchMethodError, I re-deployed my application, and got this error upon running the app:

org.springframework.beans.factory.BeanDefinitionStoreException: Parser configuration exception parsing XML from class path resource [mySpringContext.xml]; nested exception is javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@nnnnnnn] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? Upgrade to Apache Xerces (or Java 1.5) for full XSD support.

The problem here was that there was an an old (2003) xerces.jar file present in my Java project, which contained an old JAXP provider class which did not support XSD. 

To fix this, I deleted the old xerces.jar file, and redeployed the project.  (I also needed to delete WebLogic's cache, located on my machine at \bea\user_projects\domains\mydomain\servers\myserver\tmp, to completely get rid of the old cached xerces.jar file.)