junit test and non junit test with ant target - spring

<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
{
...
}

Related

Address already in use error if 2+ arquillian integration tests

I have several 'standard' junit integration test with arquillian, tomcat7 embedded (arquillian-tomcat-embedded-7:1.0.0.Final-SNAPSHOT, tomcat-embed-core:7.0.50) and Shrinkwrap.
#RunWith(Arquillian.class)
public class TestMe {
#Deployment
public static WebArchive deploy() {
return
ShrinkWrap.create(WebArchive.class, "test.war")
.addPackages(true, "org.foo")
.addAsManifestResource("META-INF/context.xml", "context.xml")
.addAsWebInfResource("WEB-INF/beans.xml", "beans.xml")
.addAsWebInfResource("WEB-INF/web.xml", "web.xml").as(WebArchive.class);
}
#Test ...
}
Separately executed via maven, every test is green. But if I do a mvn verify and start the whole testsuite I get: java.net.BindException: Address already in use: JVM_Bind :9095. What is the problem?
arquillian.xml:
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<defaultProtocol type="Servlet 3.0" />
<engine>
<property name="deploymentExportPath">target</property>
</engine>
<container qualifier="tomcat" default="true">
<configuration>
<property name="unpackArchive">true</property>
<property name="bindAddress">localhost</property>
<property name="bindHttpPort">9095</property>
<property name="serverName">amgui-arquillian-tomcat7-embedded</property>
</configuration>
</container>
It looks like mvn verify is trying to run tests in parallel. Or at least not waiting for the previous test to clean up before it starts the next one. You can't have more than one process binding to the same address/port combination.
Tomcat connectors support the concept of using a new free port every time they start to avoid these sorts of issues (set the port to zero) but I don't think that on its own will help you. Your test environment would need to know to query Tomcat to find out which port to use for every test.
I'd try and modify your tests so they don't run in parallel.

AspectJ not seeing META-INF/aop.xml

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.

Spring + JPA + Hibernate Testing with H2 and #ContextConfiguration

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)

Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered

Getting follwing error when I run junit test case report through ant srcipt:
Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.
java.lang.IllegalStateException: Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.
at org.springframework.mock.jndi.SimpleNamingContextBuilder.activate(SimpleNamingContextBuilder.java:135)
at org.springframework.mock.jndi.SimpleNamingContextBuilder.emptyActivatedContextBuilder(SimpleNamingContextBuilder.java:113)
at com.bgc.ecm.core.test.ElNinoAbstractTestCase.prepareTestInstance(ElNinoAbstractTestCase.java:216)
at org.springframework.test.AbstractSingleSpringContextTests.setUp(AbstractSingleSpringContextTests.java:100)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
code:
this.callerContext = (CallerContext) getApplicationContext().getBean("CallerContext");
assertNotNull(this.callerContext);
SimpleNamingContextBuilder builder =
SimpleNamingContextBuilder.emptyActivatedContextBuilder();
Junit target:
<junit printsummary="on" fork="yes" forkmode="perBatch" haltonfailure="false" failureproperty="junit.failure" showoutput="false">
<classpath>
<path refid="CLASSPATH_JUNIT"/>
</classpath>
<batchtest fork="no" todir="${TEST_BUILD_DIR}">
<fileset dir="${APP_DIR_CORE}\src\test">
<include name="**/*Test.java" />
<include name="**/Test*.java" />
</fileset>
</batchtest>
</junit>
I had enabled JNDI datasource in Hibernate config file which causes 2 jndi reference and thows JNDI/JVM binding exception.

Cant get Junit to work with Spring in an ANT build

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.

Resources