I read a problem from the link https://stackoverflow.com/q/15784984/814074 and tried the solution given in above link.
However, I got the following error while running the code:
Error creating bean with name 'JobArgs' defined in class path resource [pipelineJob.xml]:
Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy2 implementing java.io.Serializable,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'com.test.genepanel.job.JobArguments' for property 'jobArguements'; nested exception is java.lang.IllegalStateException:
Cannot convert value of type [$Proxy2 implementing java.io.Serializable,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.test.genepanel.job.JobArguments] for property 'jobArguements': no matching editors or conversion strategy found
The xml contains
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">
<batch:job id="pipelineJob">
<batch:step id="initializationStep" next="CleanUPStep">
<batch:tasklet ref="initializationStepTasklet" />
</batch:step>
<batch:step id="CleanUPStep">
<batch:tasklet ref="cleanupTaskLet" />
</batch:step>
</batch:job>
<bean id="basicStep" class="com.test.mutation.steps.BasicStep" abstract="true">
<property name="testJobArgs" ref="JobArgs"/>
</bean>
<bean id="JobArgs" class="com.test.mutation.application.TestJobArguements">
<property name="jobArguements" ref="jobArg">
</property>
</bean>
<bean id="jobArg" class="com.test.genepanel.job.JobArguments" scope="step">
<constructor-arg value="#{jobParameters['jobOutputDir']}"/>
</bean>
<bean id="emptyTaskLet" class="com.test.mutation.steps.EmptyStep" scope="step" parent="basicStep" />
<bean id="cleanupTaskLet" class="com.test.mutation.steps.CleanUpStep" scope="step" parent="basicStep">
</bean>
<bean id="initializationStepTasklet" class="com.test.mutation.steps.InitializationStep" scope ="step" parent="basicStep">
</bean>
</beans>
Am I missing anything?
The easy way to use step scope is like this:
<bean id="myReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" value="file:#{jobParameters['input.file']}" />
<property name="linesToSkip" value="0" />
<property name="recordSeparatorPolicy" ref="simpleRecordPolicy" />
<property name="lineMapper" ref="journalSicIemtLineMapper" />
</bean>
Placing the step scope on the beans will delay his creation until the step it his referred is about to start. This is what Late-binding means, so you could access variables in the the ExecutionContext.
As the docs in the StepScope states:
beans with the StepScope will be aop:scoped-proxy. This means a proxy goes around the real object.
So when you define a regular Spring Beans (like you did with jobArg) and put the scope=step on it. You will have to find a way to retrieve the object inside this proxy when you want to set it in another bean (JobArgs)
I have looked all over the Spring references and I have not seen late binding in the constructor arguments so I am not sure it works. I assume you are setting the jobParameters in the JobArgs, in which case it should have the same scope="step"
Related
I have two datasources defined "datasource1" and "datasource2" (in xml configuration from a dependency).
Because of that I don't get JdbcTemplate configured by default so I need to do it manually, I do it like this:
1.
#Bean
public JdbcOperations jdbcOperations(DataSource datasource1) {
return new JdbcTemplate(datasource1);
}
2.
#Bean
public JdbcOperations jdbcOperations(#Qualifier("datasource1") DataSource datasource1) {
return new JdbcTemplate(datasource1);
}
In both cases it fails with:
Parameter 0 of method jdbcOperations in com.example.PersistentConfig required a single bean, but 2 were found:
- datasource1: defined in class path resource [datasources.xml]
- datasource2: defined in class path resource [datasources.xml]
Why the qualifier doesn't work?
I can't change the datasources.xml file to add a primary=true to datasource.
datasources.xml:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="datasource1"
class="com.example.database.IdentifiedLazyConnectionDataSourceProxy">
<qualifier value="datasource1"/>
<property name="targetDataSource">
<bean class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/ak1Database"/>
<property name="resourceRef" value="true"/>
</bean>
</property>
<property name="identifier" value="shared"/>
</bean>
<bean id="datasource2"
class="com.example.database.IdentifiedLazyConnectionDataSourceProxy">
<qualifier value="datasource2"/>
<property name="targetDataSource">
<bean class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/ak2Database"/>
<property name="resourceRef" value="true"/>
</bean>
</property>
<property name="identifier" value="shared"/>
</bean>
</beans>
The reason this wasn't working is because xml configuration always overrides java config (see https://jira.spring.io/browse/SPR-7028).
To solve this I needed to create a bean that has different name then the one in the xml and mark that new bean as #Primary.
So now I will have three datasource beans, two connecting to the same database schema, but only one of the marked Primary so it will be used in default places instead of the xml defined one.
I'm with a JEE project, from Maven project to Dynamic Web.
The problem is that I haven't use xml configuration, but now, with the Dynamic web project, I must.
I can't figure out how write right the applicationContext.xml; I've read a lot of topic but no one help me.
Here the code and error:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-4.2.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd">
<!-- Abilita l'uso di tutte le annotazioni -->
<context:annotation-config/>
<import resource="security-config.xml"/>
<context:component-scan base-package="it.**"/>
<!-- Abilita il supporto AOP -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<util:properties id="settings" location="classpath:../../META-INF/MANIFEST.MF"/>
<!-- i valori delle properties vengono iniettati in AuthentificationFilter e il id=myProps serve per l'iniezione -->
<util:properties id="myProps" location="classpath:muru/application.properties"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath*:muru/*.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg>
<bean class="com.mongodb.MongoClient">
<constructor-arg value="localhost"/>
<constructor-arg value="27017"/>
</bean>
</constructor-arg>
<constructor-arg value="database"/>
</bean>
<mongo:repositories base-package="it.cap.domain" mongo-template-ref="mongoTemplate"></mongo:repositories>
<!-- Abilita la configurazione delle transazioni tramite annotazioni -->
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
</beans>
Stacktrace
11:12:26.108 [localhost-startStop-1] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 68 in XML document from ServletContext resource [/WEB-INF/applicationContext.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 68; columnNumber: 93; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mongo:repositories'.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:399)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'mongo:repositories'.
Can you help me to understand?
Thanks in advice :)
The issue seems to be from the order of the bean definition in your context file.
Just try changing the position of the below bean definition
<tx:annotation-driven transaction-manager="txManager"/>
from currrent position to just after the below bean.
<context:component-scan base-package="it.**"/>
Something like
<context:component-scan base-package="it.**"/>
<tx:annotation-driven transaction-manager="txManager"/>
See if this solves your issue.
For your reference..
http://forum.spring.io/forum/spring-projects/container/9895-order-of-bean-definitions-matters
If the above solution doesn't works ,last thing I guess would be to check if right jars holding the specified mongo related xsds under your application's lib folder
I found a solution, in applicationContext.xml I just put an import tag to resource "spring.xml":
<import resource="spring.xml" />
And inside spring.xml:
<!-- MongoDB host -->
<mongo:mongo host="localhost" port="27017" />
<!-- Template for performing MongoDB operations -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate" c:mongo-ref="mongo" c:databaseName="dbname" />
<!-- Activate Spring Data MongoDB repository support -->
<mongo:repositories base-package="it.domain" mongo-template-ref="mongoTemplate" />
<!-- Use this post processor to translate any MongoExceptions thrown in #Repository annotated classes -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
Now it starts without tomcat's crash; I wil let you know if it works fine with db's connections.
I would like to get a simple integration test with Tomcat and Spring 4 running, injecting a spring component and use my existing data source configuration from Tomcat. I don't want to configure my DataSource twice.
Everything, including my data source, is configured in the file WebContent/WEB-INF/application-context.xml.
<?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:task="http://www.springframework.org/schema/task"
xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<task:annotation-driven />
<!-- annotations in bean classes -->
<!-- context:annotation-config / -->
<!-- mvc:annotation-driven / -->
<context:component-scan base-package="com.mycompany.package.**" />
<jpa:repositories base-package="com.mycompany.package.**" />
<!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="packagePU" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
</property>
<property name="jpaPropertyMap">
<props>
<prop key="eclipselink.weaving">false</prop>
</props>
</property>
</bean>
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="showSql" value="true" />
</bean>
<bean id="jpaDialect"
class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
<!-- <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/> </bean> -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="i18n/messages" />
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DefaultDB" />
</beans>
I am using this tutorial http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#testcontext-ctx-management, but I don't fully understand how I can just run my test in the context of Tomcat that provides my DataSource.
Currently, I am this far:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations = { "file:WebContent/WEB-INF/application-context.xml"})
public class SimulatorTest {
#Autowired
private ShiftSimulator simulator;
#BeforeClass
public void setup() {
// ???
}
#Test
public void testShiftStart() {
System.out.println("Hello world");
}
}
Currently, I get this error when running the test
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:WebContent/WEB-INF/application-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': 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
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': 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
...
Caused by: 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
...
I fully understand that there needs to be a InitialContext, but how can I provide my test with my context that is provided by Tomcat, including my Data Source configuration? I don't want to set my data source connection credentials twice.
Solved it. Just to recap the problem: Spring tries to create the dataSource bean and fails at looking up the JNDI name - because there is no JNDI available.
So what I did for testing, I just created another XML files that overrides the bean dataSource. I ignored the file in version control and ask every developer to copy this file in place:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="com.sap.db.jdbc.Driver"
p:url="jdbc:sap://xxx:30015"
p:username="sa"
p:password="">
</bean>
</beans>
In the test class, I am providing the additional file reference that overrides dataSource so it never tries to do the failing JNDI lookup:
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration(locations = { "file:WebContent/WEB-INF/application-context.xml", "file:WebContent/WEB-INF/test-datasource.xml" })
public class SimulatorTest {
...
TomcatJNDI offers a comfortable solution for this problem. It's based on Tomcat's JNDI system and initializes only Tomcat's JNDI environment without starting the server. So you can access all your resources as configured in Tomcat's configuration files in tests or from within any Java SE application. Usage is simple, e. g.
TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();
DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/path/to/datasource");
Find more about it here.
I am trying to use spring's unmarshaller to automatically unmarshal request body from xml to an object. But I failed getting the error util prfeix unbind. Could you tell me how can I use util:list and where can I find reference for util:list.
I did spot that the official documentation leave out a closing > in </property and I correct that in my configuration.
I find configuration far more frustrating that just write the code.
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="stringHttpMessageConverter"/>
<ref bean="marshallingHttpMessageConverter"/>
</util:list>
</property
</bean>
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean id="marshallingHttpMessageConverter"
class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="castorMarshaller" />
<property name="unmarshaller" ref="castorMarshaller" />
</bean>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
You need to declare to util namespace; e.g.:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
I have property file and I want to set uri in my route from this file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<import resource="TransactionsParserConfig.xml"/>
<bean id="transactionsValidator" class="com.class.TransactionsValidator"/>
<bean id="transactionsValidator123" name="${ftp.host}"/> <!--here I can use property-->
<routeContext id="transactionsRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="routeFTP">
<from uri="direct:start" />
<!--here I can NOT use property-->
<from uri="ftps://${ftp.host}/?securityProtocol=SSL"/>
etc...
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<array>
<value>classpath:/ftp.properties</value>
</array>
</property>
</bean>
</beans>
But looks like it's not allowed to set uri from property file. Because when I use ${ftp.host} outside the routexContext tag everething is fine. Also even Idea can't redirect me when I hit ctrl+mouseclick inside routeContext.
Why?
Camel cannot use PropertyPlaceholderConfigurer inside it's Spring DSL due to Spring restrictions. There are many ways to achieve what you want. Some of them are described by link.
You can use bean configuration mentioned below
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>file:/properties1.properties</value>
<value>file:/properties2.properties</value>
</list>
</property>
</bean>
Properties can be access in java classes like
#Value("${categories.insert.sql}")
private String insertQuery;
Properties can be accessed in camel context like
<setHeader headerName="signature">
<constant>{{api.secretkey}}</constant>
</setHeader>
Hope this works