I have a Spring + JPA + Hibernate application that I'm trying to test by subclassing code>AbstractJUnit4SpringContextTests. The class allows to specify the Spring context file using the #ContextConfiguration annotation. In this file, the database is created and initialized (schema + data) using SQL scripts through the <jdbc:embedded-database> element.
Now I have two classes that load two different spring context files, but they both contain this element. If I run each test class individually, all the test methods work fine. However, if I run them from an ant script, the second test that runs will complain because the database was already initialized! This is very odd as I have fork="yes" forkmode="perTest" in my Ant JUnit target. I'm not sure why this is happening. Any ideas?
EDIT: here's a fragment of my ant script:
<junit printsummary="withOutAndErr" haltonfailure="yes" fork="yes" forkmode="perTest" maxmemory="512m">
<classpath refid="mvn.classpath"/>
<classpath location="${classes-core}"/>
<classpath location="${classes-pentaho}"/>
<classpath location="${classes-plugins}"/>
<classpath location="${junit.classes}"/>
<classpath location="${junit.resources}"/>
<sysproperty key="ant.home" value="${ant.home}"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="${junit.out.dir.xml}">
<fileset dir="${junit.classes}" includes="**/*TestSuite.class"/>
</batchtest>
</junit>
Thanks
Giovanni
I found a quick and elegant solution. Apparently Spring was not reinitializing the context for each test, so my H2 database was surviving somehow. I'm still a little puzzled, but adding the following to my test classes solved it:
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
Related
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 trying to use Jenkins to execute a SQL script that is in my source control. To do this, I created a build task to invoke ANT. My ANT version is 1.9.4.
Here is the build file that I am calling
<project name="VResources-Reset">
<sql
driver="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://SERVER_NAME:1433;databaseName=Automation"
userid="USERID"
password="PWD"
src="C:\\SvyDeploy\\DEV\\Sprint\\Automation\\Database\\Viewpoint\\View Resources\\VResources - Reset Users.sql"/>
<classpath>
<pathelement location="C:\\SvyDeploy\\DEV\\Sprint\\Automation\\libs\\sqljdbc4.jar"/>
</classpath>
</project>
I have also tried using org.database.jdbcDriver as the driver.
When I try to build my project in Jenkins, I am always getting the below error and can't figure out why. ANT and Jenkins are very new to me, so I'm sure I'm missing something simple. Can someone please point out what that is?
Class Not Found: JDBC driver com.microsoft.sqlserver.jdbc.SQLServerDriver could not be loaded
Hope classPath should be passed inside sql element.
Please try this..
<project name="VResources-Reset">
<sql driver="com.microsoft.sqlserver.jdbc.SQLServerDriver" url="jdbc:sqlserver://SERVER_NAME:1433;databaseName=Automation"
userid="USERID"
password="PWD"
src="C:\\SvyDeploy\\DEV\\Sprint\\Automation\\Database\\Viewpoint\\View Resources\\VResources - Reset Users.sql">
<classpath>
<pathelement location="C:\\SvyDeploy\\DEV\\Sprint\\Automation\\libs\\sqljdbc4.jar"/>
</classpath>
</sql>
</project>
I am trying to get Load Time Weaving working with my Tomcat 7 webapp, in order to weave a class from an external jar file (located in WEB-INF/lib).
I have done the following:
Started Tomcat with the following parameters: -javaagent:/path/aspectjweaver-1.7.0.jar -classpath /path/aspectjrt-1.7.0.jar:etc
Placed aop.xml into WAR_ROOT/META-INF/, WEB-INF/lib/META_INF, WEB-INF/lib and WEB-INF/
aop.xml:
<aspectj>
<aspects>
<aspect name="ca.gc.agr.agrishare.web.jsf.chartlet.AgriShareGanttRendererAspect"/>
</aspects>
<weaver options="-verbose -debug -XnoInline">
<include within="org.jfree..*"/>
<dump within="org.jfree..*" />
</weaver>
</aspectj>
No matter where I place the file, my target class is not woven, and I keep seeing errors like this:
[WebappClassLoader#495b317b] error can't determine implemented interfaces of missing type javax.validation.ValidatorFactory
when weaving type org.hibernate.cfg.beanvalidation.TypeSafeActivator
when weaving classes
when weaving
[Xlint:cantFindType]
The fact that it is trying to weave a class outside of the package I specified, and considering that server startup time quadrupled, I think that it is trying to weave all classes.
What am I missing?
Figured it out.
WAR_ROOT/META-INF/ is the webapp metadata, looked up by servletContext.getResource("/META-INF/bla").
WAR_ROOT/WEB-INF/classes/META-INF is java classes metadata, looked up by getContextClassLoader().getResource("/META-INF/bla").
I created META-INF/aop.xml in my Config project (which is on the classpath), and everything is working properly now.
<junit printsummary="on" fork="yes" forkmode="once"
haltonerror="false" haltonfailure="false"
failureproperty="junit.failure" showoutput="false" maxmemory="1024m">
<classpath>
<path refid="CLASSPATH_JUNIT"/>
<dirset dir="${TEST_BUILD_DIR}"/>
</classpath>
<batchtest fork="no" todir="${TEST_BUILD_DIR}">
<fileset dir="${COMP_TEST_SRC}">
<include name="**/*Test.java" />
<include name="**/Test*.java" />
<exclude name="**/EswTestCase.java" />
</fileset>
</batchtest>
<formatter type="xml" />
</junit>
this takes lot of time to generate xml report, and it thorws following error:
Caught an exception while logging the end of the build. Exception was:
java.lang.OutOfMemoryError: PermGen space
why it takes long time to genearte xml? how to resolve this error and make application to run fast. I have only max of 10 test files. I use command promt to execute ant script.
Analysis:
1)If i run batch test only for test calss which extends Junit test it execute very fast. eg:
public class ImpactsParserTest extends
TestCase{..
2)Now if i have test class which extends spring junit test as:
public class AddressLookupServiceTest
extends EswTestCase{..
public class EswTestCase extends
AbstractDependencyInjectionSpringContextTests{..
this causes junit target to run very slowly and causes outof memory error. why itis happening like this?
3) when I make batchtest fork="yes" instead of no, then build is quick and doesnt throw outof memory. But, it throws error like:
java.lang.NoClassDefFoundError
at org.apache.log4j.Logger.getLogger(Logger.java:118)
..
java.lang.NoClassDefFoundError: com.bgc.ordering.wizard.back.services.EswTestCase
even though, i have specified these jar file and class file in classpath element as:
and logger jar in
<path id="CLASSPATH_JUNIT">
<fileset dir="${BUILD_LIBS_HOME}">
<include name="*.jar" />
</fileset>
<pathelement location="${TEST_CLASSES_DIR}" />
<pathelement location="${TEST_BUILD_DIR}" />
<pathelement location="${COMP_BUILD}" />
<pathelement location="${COMP_CLASSES}" />
<path location="${APP_DIR}\bgc-esw-services\target\classes"/>
<pathelement location="${APP_DIR}\bgc-esw-web\target\classes" />
...
log4j.properties present at ${TEST_BUILD_DIR}
using: apache-ant-1.8.1 and junit-3.8.1.jar
This error occurs when the JVM runs out of space in the permanent generation heap. The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. The size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize. The default is 64 Mb on the Sun VMs. To fix this issue you can give it a higher value like 256mb.
My guess is that you not only run unit tests you also run integration tests e.g. you have a class wired with Spring and you require their dependencies. That's why you have EswTestCase. If you just want to write unit tests I'd recommend you instantiate your class and mock the dependencies to other classes that you are not testing directly. This will minimize your memory footprint because you don't have to create your Spring application context.
This is what the JavaDoc says about AbstractDependencyInjectionSpringContextTests:
Really for integration testing, not
unit testing. You should not normally
use the Spring container for unit
tests: simply populate your POJOs in
plain JUnit tests!
As of Spring 3.0, the legacy JUnit 3.8 base class hierarchy (i.e., AbstractDependencyInjectionSpringContextTests, AbstractTransactionalDataSourceSpringContextTests, etc.) is officially deprecated and will be removed in a later release. It is recommended that you use the Spring TestContext Framework for writing integration tests. Instead of extending EswTestCase with AbstractDependencyInjectionSpringContextTests you should use the annotations.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class EswTestCase
{
...
}
I am trying to get Spring MVC and Junit working with eachother and I am having trouble configuring the build.xml file. I am fairly new at using ANT and do not really understand all the tutorials. I put the junit.jar file in the lib direcotory, but still am getting the following message from my console.
test:
BUILD FAILED
C:\Java\mmz\WEB-INF\build.xml:63: The <classpath> for <junit> must include junit.jar if not in Ant's own classpath
Total time: 223 milliseconds
Edit
Here is an example of wanting to run just one test
and I am not sure what I need to do, i tried doing something like the following, but I dont quite understand what its doing, so I dont know how to make changes
<path id="classpath.test">
<pathelement location="" />
<pathelement location="${test.dir}" />
</path>
<target name="test">
<junit>
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false" />
<test name="TesterTest" />
</junit>
</target>
I am pretty lost on what to do next. Thanks
If you copy-pasted your build.xml file then there is probably a classpath element somewhere. Probably near the top of the file. In that element they have probably listed some paths and/or files. You need to add the junit jar to this section.