I am using the spring-batch-admin-sample application as the starting point for a project. I have a working spring-batch job that is built with annotations that I am integrating with the console.
When I jar it up and add it to my console project, the annotations are not honored. In order to test this, I have gone as far as to add the tag to the job, so an attempt to build the job bean means that the annotation-config tag has been seen and processed.
Can anyone see what I am missing?
Thanks in advance.
Environment
OS: Windows 7
Java: jdk 1.8.0_25
Spring Batch Admin Sample version: 1.3.1
Spring version: 3.2.13 * stock 3.2.9 has a bug that causes this symptom
Spring-batch version: 3.0.2
Pivotal tc version: 3.0 Developer Edition
IDE: STS 3.6.3
Log Snip:
14:27:13.667 [localhost-startStop-1] WARN ... Error creating bean with name 'step0002-fetch':
**Cannot resolve reference to bean 'sourceSelectionReader'**
while setting bean property 'itemReader'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'sourceSelectionReader' is defined
Job Bean Definition
<context:annotation-config/>
<bean class="org.springframework.batch.core.scope.StepScope" />
<batch:job id="my-job">
<batch:step id="step0002-fetch" >
<batch:tasklet transaction-manager="transactionManager" start-limit="100" >
<batch:chunk reader="sourceSelectionReader" writer="selectedDataWriter" commit-interval="1" />
</batch:tasklet>
<batch:next on="*" to="step0003-archive-purge"/>
</batch:step>
</batch:job
Class definition:
#Component("sourceSelectionReader")
#Scope(value="step", proxyMode = ScopedProxyMode.INTERFACES)
public class SourceSelectionReaderImpl
implements ItemReader<Object>,SourceSelectionReader, ApplicationContextAware {
...
}
The tag
<context:annotation-config/>
should have been
<context:component-scan/>
... looking for a rock to crawl under ...
See Difference between <context:annotation-config> vs <context:component-scan> for an explanation.
Related
I am porting Spring( v.4.3.2) application from Tomcat7 to Tomcat9. I am running Tomcat as a service on Windows box. in my ApplicationContext.xml I have several Beans profiles defined and I also have bean definitions outside of profiles :
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="utilsDS" />
</bean>
.............
....
<bean id="utilsDS" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver" />
</bean>
....
</beans>
When I am starting Tomcat I am passing a JVM option :
-Dspring.profiles.active='UAT'
Tomcat 7 starts my application perfectly fine and I am able to run it. However with Tomcat 9 I am getting an error
org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager' defined in ServletContext resource [/WEB-INF/config/applicationContext.xml]:
Cannot resolve reference to bean 'utilsDS' while setting bean property 'dataSource';
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'utilsDS' is defined
"applicationContext.xml" are identical on Tomcat 7 and 9 since I used the same WAR to deploy an application. I am not sure what I'm missing.
It seems to me it's something in configuration of Tomcat9 that would resolve the reference. I am not sure what it is.
I added context-param to an application "web.xml" and it works :
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
still not sure why passing JVM option :
-Dspring.profiles.active=dev
didn't work
I am using spring boot 1.5.4 with mybatis-spring 3.1. I am able to successfully run my application via eclipse. But when I used commandline (java -jar jarname), I get below exception. my standalone application is stopping. I want to move my app to deploy to different machine with the jar. Please help.
Caused by: org.apache.ibatis.type.TypeException: Could not resolve type alias 'MyClass'. Cause: java.lang.ClassNotFoundException: Cannot find class: MyCLass
at org.apache.ibatis.type.TypeAliasRegistry.resolveAlias(TypeAliasRegistry.java:120)
at org.apache.ibatis.builder.BaseBuilder.resolveAlias(BaseBuilder.java:149)
at org.apache.ibatis.builder.BaseBuilder.resolveClass(BaseBuilder.java:116)
... 36 more
I resolved the same issue by moving to autoconfigure(using spring properties) I originally had my db configuration(datasource, session factory) configured in a javaconfig class. I'm removed the config and moved my config to my application properties(yml format) ..
Below is what I have
mybatis:
typeAliasesPackage: com.wiredinformatics.preauth.domain
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/preauth?
useSSL=false&serverTimezone=UTC
username: myuser
password: mypass
dbcp2:
driver: com.mysql.cj.jdbc.Driver
initial-size: 2
max-total: 10
max-idle: 10
min-idle: 5
max-wait-millis: 30000
validation-query: SELECT 1
I haven't had time yet to figure out why having my own java config broke the scanning. It worked ok in eclipse, but failed when running from the command line
I solved this problem!
https://github.com/mybatis/mybatipse/issues/77
#deoxyseia
remove
sessionFactoryBean.setTypeAliasesPackage("com.your.packae.pojo")
change resultType="MyClass" to
resultType="com.your.packae.pojo.MyClass"
repackage
I had a similar problem while working in a Maven project, resulting in the same errors.
My situation is that I have a executable jar with Spring Boot which has a nested jar (which uses regular Spring) as dependency. While running in IntelliJ, there was absolutely no problem, due to the way that IntelliJ finds its classes.
While trying to start the jar locally with java -jar jarname.jar so that I could deploy it on a remote server, MyBatis had trouble scanning the typeAliases and typeHandlers packages.
Since I'm working on a legacy-project which mixes Spring Beans initialized in Java and xml, I had one hell of a time determining the root cause. A lot of answers said to change your resultType to the full classpath like this answer. This works. But in my case that would mean hundreds of changes to our DAO's.
Finally, I got on track following this external link from titanwolf.
Here's what you need to do:
add the following dependency to your POM (the jar which contains your MyBatis setup)
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
set the VFS property on your SqlSessionFactoryBean
xml:
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="vfs" value="org.mybatis.spring.boot.autoconfigure.SpringBootVFS"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
or if you use regular Java for your bean initalizing:
#Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
return factory;
}
And that's it. Works locally and on remote server. Hope I saved anyone else some headaches.
note: mybatis-config.xml contains my configuration including, but not limited to:
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.my.path.model"/> <!--wasn't being picked up before fix-->
</typeAliases>
<typeHandlers>
<package name="com.my.path.mybatis"/> <!--wasn't being picked up before fix-->
</typeHandlers>
<mappers>
<mapper resource="sql/my-dao.xml"/>
<mappers>
</configuration>
You can trace your own errors better by enabling logging for MyBatis. Just add the following line to your application.properties file:
logging.level.org.mybatis=DEBUG
I am using Spring 3.2.9, Tomcat 6.0.44
I am trying to configure my application's Spring instrumentation provider (e.g. spring-instrumentation.jar) for load-time weaving, when it is deployed on Tomcat.
I have a requirement to NOT use:
"-javaagent:/path/path/spring-instrument.jar" on the command line to do the configuration.
I've read that I can configure the Spring instrumentation by modifying the <Context> element of my application's Tomcat configuration (in either Tomcat's server.xml or my web app's context.xml). Adding the appropriate <Context> element to the server.xml results in my application being correctly configured to run with Spring's instrumentation provider. Adding it to the context.xml (see below) does NOT result in a working setup.
I have a META-INF/aop.xml file, looks like this:
<aspectj>
<weaver options="-verbose -showWeaveInfo -debug">
<include within="com.mv.xx.services..*"/>
<exclude within="com.mv.xx.aop..*"/>
</weaver>
<aspects>
<aspect name="com.mv.xx.aop.MyAspect"/>
</aspects>
</aspectj>
I also specify that I want to use load-time weaving by adding this to my Spring context config:
<context:load-time-weaver />
And I add this jar to my application's classpath:
spring-instrument-tomcat.jar
WHAT I HAVE TRIED:
When starting Tomcat, If I identify the location of the spring-instrument.jar on the command line using the -javaagent parameter like this:
-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar
Everything works fine.
Next I removed "-javaagent:/path/path2/spring-instrument-3.2.9.RELEASE.jar" from the command line.
In Tomcat's server.xml file (located in $CATALINE_HOME/conf), I added a a <Context> element to the <Host> element, like this:
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
With this configuration everything behaves properly. However I have a requirement to not modify Tomcat's server.xml, since I don't have control over the server.xml (DevOps does, and is reluctant to modify it).
Next I removed the <Context> element from Tomcat's server.xml.
According to the Spring docs, I can add a /META-INF/context.xml to my webapp, and put the <Context> element that used to be in Tomcat's server.xml into the context.xml, like so:
<Context>
<Context path="/myApp" docBase="myApp">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
</Context>
</Context>
However when I restart Tomcat, I get an error message in the logs saying:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.weaving.AspectJWeavingEnabler#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loadTimeWeaver': Initialization of bean failed; nested exception is java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar
After digging around, I read something that suggested that I modify the <context:load-time-weaver/> element in my Spring config, like this:
<context:load-time-weaver weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
And add the jar containing InstrumentationLoadTimeWeaver.class to my classpath.
However when I do that, I get this error message in the logs:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: Must start with Java agent to use InstrumentationLoadTimeWeaver. See Spring documentation.
etc....
Can anyone explain how to setup load-time weaving with Spring and Tomcat WITHOUT using the -javaagent on the command line, and WITHOUT modifying the server.xml?
This is the code that I managed to use in order to removed the exception that you mentioned.
Basically you have to implement the LoadTimeWeavingConfigurer and override the method getLoadTimeWeaver().
#Configuration
#ComponentScan(basePackages = "org.myproject")
#EnableAspectJAutoProxy
#EnableSpringConfigured
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.AUTODETECT)
public class Config implements LoadTimeWeavingConfigurer {
#Override
public LoadTimeWeaver getLoadTimeWeaver() {
return new ReflectiveLoadTimeWeaver();
}
#Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() throws Throwable {
InstrumentationLoadTimeWeaver loadTimeWeaver = new InstrumentationLoadTimeWeaver();
return loadTimeWeaver;
}
}
I used invesdwin-instrument to perform that. It allows you to use Load time weaving instrumentation dynamically so that you don't have to use any javaagent.
It took me a bit of effort to make it work with Tomcat 8.5 though. But it finally work using this configuration with Spring Boot :
#SpringBootApplication
#EnableLoadTimeWeaving // instead of #ImportResource(locations = "classpath:/META-INF/ctx.spring.weaving.xml")
public class MySpringBootApplication {
public static void main(final String[] args) {
DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
SpringApplication.run(MySpringBootApplication.class, args); //start application, load some classes
}
}
It should also work with previous version of Tomcat.
Regards
https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Performance/Weaving/Static_Weaving
Try maven plug-in from the above link. It's working
I'm getting the following:
2013-03-27 18:51:54,944 ERROR pringframework.web.context.ContextLoader: 227 - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exporter' defined in URL ... Cannot resolve reference to bean 'dynamicNamingStrategy' while setting bean property 'namingStrategy'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'dynamicNamingStrategy' is defined
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at
and also STS is complaining:
Multiple annotations found at this line:
- Referenced bean 'dynamicNamingStrategy'
not found
with the following Spring contexts setup:
In a project, I have a jmx management context (core-app-web-common-management-context.xml) with following (excerpt):
<context:annotation-config />
<context:component-scan
base-package="com.a.b.c.management.*" />
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<property name="autodetect" value="true"></property>
<property name="namingStrategy" ref="dynamicNamingStrategy"/>
where dynamicNamingStrategy is defined in a different project (and packaged into a different jar) and is referred to in the component-scan above, as follows
package com.a.b.c.management;
#Component("dynamicNamingStrategy")
public class DynamicNamingStrategy extends KeyNamingStrategy {
......
The above Spring context is in turn imported into the main context located in the same project:
<import resource="classpath*:/META-INF/spring/core-app-web-common-management-context.xml"/>
So, somehow the #Component scanning for DynamicNamingStrategy is not working...
If I instead use this property definition in exporter, then it works:
<property name="namingStrategy"><bean class="com.a.b.c.management.DynamicNamingStrategy" /></property>
but I'd like to understand why the component scanning mechanism falters in the first instance, apparently I'm missing something.
Also, Spring Explorer view in STS is missing that bean as well. Enabling support for elements in configuration files option doesn't seem to make a difference.
Drop the .* at the end of your package name in your <context:component-scan> elements base-package attribute. I would think that this is causing the component-scan to look for a package named *, which there probably isn't one (can't be one).
The base-package is just that, the base package. The component-scan will scan all children of all base packages, therefore there is no need to have the .* wildcard at the end of your package name.
I'm using Spring-Data-JPA 1.0.3.RELEASE to manage my ORM.
my persistence.xml looks like this:
<persistence>
<persistence-unit name="default" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/myDataSource</jta-data-source>
<properties>
<property name="openjpa.TransactionMode" value="managed" />
<property name="openjpa.ConnectionFactoryMode" value="managed" />
<property name="openjpa.jdbc.DBDictionary" value="db2" />
</properties>
</persistence-unit>
</persistence>
applicationContext looks like this
<beans>
<context:annotation-config />
<bean id="myExceptionTranslator" class="org.springframework.orm.jpa.DefaultJpaDialect" />
<bean id="myEmf" class="javax.persistence.Persistence" factory-method="createEntityManagerFactory">
<constructor-arg type="java.lang.String" value="default" />
</bean>
<jpa:repositories base-package="model.repositories" />
<tx:annotation-driven transaction-manager="txManager" />
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
my OrderRepo interface looks like this:
#Transactional(readOnly = true)
public interface OrderRepository extends JpaRepository<Order, Long> {
//my stuff
}
and i'm using it like this within my service class
#Autowired
private OrderRepository repository;
But it looks like websphere dosn't like it as much and gives me this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private model.repositories.OrderRepository model.service.OrderService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: javax/persistence/EntityManager.getMetamodel()Ljavax/persistence/metamodel/Metamodel;
the only ressource i found regarding this problem points out errors in previous Spring-Data-JPA versions which are marked as fixed by now or errors using wrong dependencies to the spring-data-commons jar - however: i'm leaving that to maven so the data-commons version should be fine. also i found that spring data JPA needs a JPA 2.0 implementation so i checked for the openJPA version on the websphere server and it's fine.
Any ideas what could be causing this?
As the error informs, there is no method getMetaModel() in javax.persistence.EntityManager.
Check sources of JPA 1.0 and JPA 2.0.
EntityManager JPA 2.0
EntityManager JPA 1.0
This method exists only in version 2.0. In my opinion you should double check your dependencies if there is no jar of JPA in version 1.0
I think you need to put the below line in the dispatcher-servlet.xml file instead of applicationContext.xml file.
<tx:annotation-driven transaction-manager="txManager" />
I have faced the similar problem before few days and this change saved my life. :)
Hope yours will be saved too... Cheers.
The examples of #Autowired I've found seem to apply it to a Bean - that is a concrete class. You are applying it to an interface - is that correct?
See: tutorial