enkor
enkor

Reputation: 177

Maven failed JUnit Spring controller test but in eclipse works fine

When I run Junit test in eclipse it works without any problem. But when I want build application with Maven. It will fail. If I remove testclass, everything is ok.

TestClass:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "test-context.xml")
public class RoomControllerTest {

    private final Logger log = LoggerFactory.getLogger(RoomServiceTest.class);

    @Autowired
    private RoomService roomService;
    @Autowired
    private CalendarHelper cal;

    @Autowired
    private RoomController room;

    private MockHttpServletRequest mockRequest;
    private AnnotationMethodHandlerAdapter handlerAdapter;
    private MockHttpServletResponse mockResponse;

    @Before
    @Transactional
    public void setUP() {
        mockRequest = new MockHttpServletRequest();
        handlerAdapter = new AnnotationMethodHandlerAdapter();
        mockResponse = new MockHttpServletResponse();

        roomService.save(new Room("test", DigestUtils.sha256Hex("test"), cal
                .getExpiresDate()));
    }

@Test
    @Transactional
    public void login() throws Exception {
        mockRequest.setMethod("POST");
        mockRequest.setParameter("name", "test");
        mockRequest.setParameter("pwd", "test");
        mockRequest.setRequestURI("/login");

        @SuppressWarnings("rawtypes")
        HttpMessageConverter[] messageConverters = {new MappingJacksonHttpMessageConverter()};

        handlerAdapter.setMessageConverters(messageConverters);

        handlerAdapter.handle(mockRequest, mockResponse, room);

        log.debug(mockResponse.getContentAsString());

    }
}

ControllerClass:

@Controller
public class RoomController {

    @Autowired
    private RoomService roomService;

@RequestMapping(value = "login", method = { RequestMethod.POST,
            RequestMethod.GET })
    public @ResponseBody Room login(
            @RequestParam(value = "name", required = true) String name,
            @RequestParam(value = "pwd", required = true) String pwd) {

        return roomService.login(name.toLowerCase(), pwd);
    }
}

test-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:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">



    <import resource="classpath:persistence/Hibernate.xml" />


    <context:annotation-config />
    <context:component-scan base-package="webaccess" />

    <mvc:annotation-driven />

</beans>

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>WebAccess</groupId>
    <artifactId>WebAccess</artifactId>
    <version>b1</version>
    <packaging>war</packaging>
    <name>WebAccess</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.1.1.RELEASE</spring.version>
        <hibernate.version>4.1.4.Final</hibernate.version>
        <slf4j.version>1.6.6</slf4j.version>
    </properties>

    <dependencies>

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <!-- Hibernate dependecies -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>


        <!-- MySQL connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>

        <!-- logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- testing -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>

        <!-- json -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.8</version>
        </dependency>

        <!-- other -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- Java version -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.1.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <downloadJavadocs>true</downloadJavadocs>
                    <wtpversion>2.0</wtpversion>
                    <additionalBuildcommands>
                        <buildCommand>
                            <name>org.springframework.ide.eclipse.core.springbuilder</name>
                        </buildCommand>
                    </additionalBuildcommands>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

error:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletResponse
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
    at java.lang.Class.getMethod0(Unknown Source)
    at java.lang.Class.getMethod(Unknown Source)
    at org.apache.maven.surefire.battery.JUnitBattery.processTestClass(JUnitBattery.java:126)
    at org.apache.maven.surefire.battery.JUnitBattery.<init>(JUnitBattery.java:81)
    at org.apache.maven.surefire.SurefireUtils.instantiateBattery(SurefireUtils.java:63)
    at org.apache.maven.surefire.Surefire.instantiateBatteries(Surefire.java:262)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:140)
    at org.apache.maven.surefire.Surefire.run(Surefire.java:87)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.maven.surefire.SurefireBooter.runTestsInProcess(SurefireBooter.java:285)
    at org.apache.maven.surefire.SurefireBooter.run(SurefireBooter.java:201)
    at org.apache.maven.test.SurefirePlugin.execute(SurefirePlugin.java:366)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServletResponse
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 38 more
RUN ABORTED
java.lang.NoClassDefFoundError
org.apache.maven.surefire.Runner
An exception or error caused a run to abort.
javax/servlet/http/HttpServletResponse

Results :
[surefire] Tests run: 0, Failures: 0, Errors: 1

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.242s
[INFO] Finished at: Wed Aug 15 12:44:40 CEST 2012
[INFO] Final Memory: 12M/164M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.1.2:test (default-test) on project WebAccess: There are some test failure. -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Upvotes: 1

Views: 2061

Answers (1)

axtavt
axtavt

Reputation: 242706

I think you need to add Servlet API as a dependency of scope provided to your pom.xml:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

I guess it works fine in Eclipse because Servlet API is included in the classpath in project properties (especially if you use Dynamic Web Project), but for Maven build you need to declare it in pom.xml.

Note that <scope>provided</scope> is important - without it you'll get classloading problems if you try to deploy .war file assembled by Maven.

Upvotes: 3

Related Questions