NoClassDefinitionError with simple bean configuration - spring-xd

<bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
<property name="fragmentRootElementName" value="SomeElement" />
<property name="unmarshaller" ref="jaxb2unmarshaller" />
</bean>
<bean id="jaxb2unmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.MappedClass</value>
</list>
</property>
</bean>
I started with multi step job and have issue when packaged as the job module in the spring-xd, I stripped all the other beans from the configuration and finally figured the issue was coming due to the above two beans.
The spring-oxm jar is present in the custom modules lib. I am using spring-xd 1.0.0.RC1.
I don't want to put the jars in to the server lib, all the required libraries should be part of the custom module lib directory.
How to get it working?
If I place the spring-oxm jar in the spring-xd/lib directory the error goes but then I get the other errors too.
I guess the real reason for the NoClassDefError could be the missing dependencies and the error does not indicate the information about the missing dependent class.
Any inputs would be appreciated?

The information provided is not sufficient to conclude anything. However, you could check the second last line of the code block provided above. The closing <property> tag is missing or it's a TYPO while writing the code here.

The module's dependent jars should go in the module's lib/ directory if they are not on the server class path already. Spring XD 1.1 has improved support for module packaging but in 1.0 you need to install the jars manually. Also, I would suggest upgrading to 1.1.0.M2 or 1.0.3.RELEASE at least.

Related

Using PropertyPlaceholderConfigurer to access test resources

In my IntelliJ project, under the project root, there is a config folder.
This is where various .properties files are located.
Within the application, these are made available to Spring in the standard way, using a propertiesConfigurer.xml file:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:config/${name}.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true"/>
</bean>
The reason they are accessed using 'file', is that eventually they may be external to the deployed jar.
This works, both when running the application, and when running unit tests.
I also wish to access files which are only for use when running tests.
I have placed these under:
test
--- resources
-------META-INF
----------spring
-------------config
I have added this line to the list of locations within the same propertiesConfigurer.xml:
<value>classpath*:META-INF/spring/config/${name}.properties</value>
This is not working. No file or resource exception is being thrown, but none of the properties defined in the test file are being resolved within the application.
Within the IntelliJ Project Settings->Modules, src\test\resources is listed as a context root.
Also, on the file system, under:
...\target\test-classes\META-INF\spring\config
the test property files exist.
What is the correct way to access them?
Thanks

PropertyPlaceholderConfigurer does not find property file on disk

I am trying to move a working spring WAR to OSGI environment (in glassfish 3.1 and blueprint, spring 3.0.5).
The application loads properties file from disk, like this:
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="${my_conf}/my.properties"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
</bean>
I see in debugger that ${my_conf}/my.properties is translated to the existing path (c:\conf\my.properties)
I use the property jms.url defined in my.properties in the next bean declaration
<amq:broker useJmx="false" persistent="false" brokerName="embeddedbroker">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://${jms.url}"/>
<amq:transportConnector uri="vm://embeddedbroker" />
</amq:transportConnectors>
</amq:broker>
And in deployment I get an exception "Could not resolve placeholder ${jms.url}"
Why it fails? Is there another way to load properties from file on disk?
thank you
Since its an OSGI environment, you will need spring-osgi-core jar added to your application. Take a look at this link to configure property-placeholder for OSGI framework.
It isn't a solution, but an explanation of my problem.
The problem is related to this bug in spring 3 and osgi.
I had to open spring logs to debug level to understand it.

Spring application context external properties?

i have a Spring application and its working well so far. Now i want the properties file in an external config folder and not in the packed jar to change things without the need to repack. This is what i got:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- <property name="locations" value="classpath:/springcontext.properties"/> -->
<property name="locations" value ="config/springcontext.properties" />
The outcommented one is working and the other one i dont get to work :/ Can someone help?
Edit:
Thx 4 comments so far.
Maybe my question wasnt clear enough :). I perform a Maven build and everything will be packaged and i want this folder to be NOT in the package nut next to the outcomming jar and in this folder i want the properties file. possible?
You can try something like this:
<context:property-placeholder
location="${ext.properties.dir:classpath:}/servlet.properties" />
And define ext.properties.dir property in your application server / jvm, otherwise the default properties location "classpath:/" (i.e., classes dir of .jar or .war) would be used:
-Dext.properties.dir=file:/usr/local/etc/
BTW, very useful blog post.
You can use file prefix to load the external application context file some thing like this
<context:property-placeholder location="file:///C:/Applications/external/external.properties"/>
<context:property-placeholder location="classpath*:spring/*.properties" />
If you place it somewhere in the classpath in a directory named spring (change names/dirs accordingly), you can access with above
<property name="locations" value ="config/springcontext.properties" />
this will be pointing to web-inf/classes/config/springcontext.properties
This blog can help you. The trick is to use SpEL (spring expression language) to read the system properties like user.home, to read user home directory using SpEL you could use #{ systemProperties['user.home']} expression inside your bean elements. For example to access your properties file stored in your home directory you could use the following in your PropertyPlaceholderConfigurer, it worked for me.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:#{ systemProperties['user.home']}/ur_folder/settings.properties</value>
</property>
</bean>
This question is kind of old, but wanted to share something which worked for me. Hope it will be useful for people who are searching for some information accessing properties in an external location.
This is what has worked for me.
Property file contents:
PROVIDER_URL=t3://localhost:8003,localhost:8004
applicationContext.xml file contents: (Spring 3.2.3)
Note: ${user.home} is a system property from OS.
<context:property-placeholder system-properties-mode="OVERRIDE" location="file:${user.home}/myapp/latest/bin/my-env.properties"/>
<bean id="appsclusterJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">${PROVIDER_URL}</prop>
</props>
</property>
</bean>
${PROVIDER_URL} got replaced with the value in the properties the file
One way to do it is to add your external config folder to the classpath of the java process. That's how I've often done it in the past.
<context:property-placeholder location="file:/apps/tomcat/ath/ath_conf/pcr.application.properties" />
This works for me.
Local development machine path is C:\apps\tomcat\ath\ath_conf and in server /apps/tomcat/ath/ath_conf
Both works for me

Spring PropertyPlaceholderConfigurer not replacing placeholder

I want to pass the WSDL url for an internal web service into my Spring beans.xml dynamically, using a PropertyPlaceHolderConfigurer.
Here's the scenario:
My web application is deployed in WebLogic 10.3.
The WSDL url is contained in a properties file that is located outside my application (directly under the corresponding domain folder, while my application is inside the autodeploy folder). I set the location of this properties file in my domain's setDomainEnv.cmd file like below:
set JAVA_PROPERTIES=%JAVA_PROPERTIES% %CLUSTER_PROPERTIES% -Dproperty.file.path.config=%DOMAIN_HOME%\Service.properties
This is what my Service.properties file contains:
Service.WSDL.PATH=http://localhost:8088/mockServiceSoap?WSDL
My Spring beans.xml configuration:----
<bean id="file.path" class="java.lang.System" factory-method="getProperty">
<constructor-arg index="0"><value>property.file.path.config</value></constructor-arg>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" ref="file.path"/>
</bean>
<bean id="myServiceId" class="com.test.service.ServiceImpl">
<property name="myServiceSoap">
<ref bean="myService"/>
</property>
</bean>
<bean id="myService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="com.test.service.ServiceSoap"/>
<property name="wsdlDocumentUrl" value="${Service.WSDL.PATH}"/>
</bean>
I enabled DEBUG log specifically for PPC and this is what I saw in my application log:
INFO org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 178 - Loading properties file from URL [file:D:/bea10.3/user_projects/domains/my_domain/Service.properties]
So, it seems that although the Service.properties file is getting loaded by PPC, the ${Service.WSDL.PATH} is NOT getting replaced.
What am I doing wrong here?
Also, how can I find out if PPC tried replacing the value of the placeholder and with what value? I was hoping the log file would contain that info but there was nothing there.
Any help is appreciated.
I've figured out, that PropertyPlaceholderConfigurer needs to be declared first in the application Context file, otherwise there's no guarantee of the load order. It took me a few hours to realize this.
Try moving the "file.path" bean into the PropertyPlaceHolderConfigurer's location property.

Spring alias not available when running in Grails

I have a problem with Spring aliases in Grails. I have a library .jar file containing classes and Spring configuration that is not working as expected. It does work as expected when I import them from a standard (no Grails) Java app.
The current configuration contains this.
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="uk.co.company.package"/>
</bean>
<alias name="marshaller" alias="unmarshaller"/>
And fails with an error.
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'unmarshaller' is defined
Changing the configuration to the following then leads it to work as expected.
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="uk.co.company.package"/>
</bean>
<bean id="unmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="uk.co.company.package"/>
</bean>
The configuration is being imported and is being read. For some reason the alias is unavailable when I try to use it. What is that reason?
This is with Grails 1.3.7 and Spring 3.0.5.
I am seeing this issue as well. You can get around it by defining the alias in the Grails resources.xml or in my case in my plugin doWithSpring closure:
springConfig.addAlias "aliasName", "beanName"
I'd expect the importBeans to import alias as well
This link might be helpful for you:
http://burtbeckwith.com/blog/?p=85
It is mentioned there that aliases don't work at least when declared in the resources.xml. The post also mentions a way of declaring aliases programatically. But it seems like this post was written a while back and not sure how relevant it is with grails 1.3.7.

Resources