【问题标题】:Spring Boot Integration Test - Maven Tests missing JSTLSpring Boot 集成测试 - Maven 测试缺少 JSTL
【发布时间】:2016-01-21 18:32:39
【问题描述】:

我正在尝试使用 Selenium 为我们的应用程序实施集成测试。我们的想法是加载我们 SpringMVC 项目的 applicationcontext,启动一个嵌入式 Tomcat 容器,然后在其上运行集成测试,然后关闭并完成应用程序编译。

现在从 Eclipse 中运行 JUnit 测试可以完美地使用 Spring Boot 启动服务器,但是在运行 Maven 测试和访问网站时(通过或不通过 Selenium),我得到以下异常:

org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

但是,JSTL 位于 Maven 中范围 test 的类路径中。有谁知道,为什么会这样?

我的配置分为一个父项目、一个用于我们项目的内部库和另一个用于实际项目的库。我省略了 pom.xml 中不感兴趣的部分:

<properties>
    <apache.tiles.version>3.0.4</apache.tiles.version>
    <tomcat.version>7.0.59</tomcat.version>
</properties>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-jsp</artifactId>
    <version>${apache.tiles.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-core</artifactId>
    <version>${apache.tiles.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-api</artifactId>
    <version>${apache.tiles.version}</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>${powermock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.3.1</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.2.8</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>${spring.boot.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.47.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>${tomcat.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-el</artifactId>
    <version>${tomcat.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-logging-juli</artifactId>
    <version>${tomcat.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-websocket</artifactId>
    <version>${tomcat.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>${tomcat.version}</version>
    <scope>test</scope>
</dependency>

TestConfig.java:

@EnableAutoConfiguration
@SpringBootApplication
@Import({ GVAppConfiguration.class, SecSecurityConfig.class, TestMvcConfig.class })
@ImportResource({ "classpath:applicationContext.xml", "classpath:/META-INF/applicationContext-commons.xml",
    "classpath:/applicationContext-solr.xml" })
public class TestConfig extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
    return application.sources(TestConfig.class);
    }

    public static void main(final String[] args) {
    SpringApplication.run(TestConfig.class);
    }
}

IndexControllerTest.java:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfig.class)
@WebIntegrationTest(value = "server.port=9000")
@SeleniumTest(driver = FirefoxDriver.class, baseUrl = "http://localhost:9000")
public class IndexControllerTest {

    @Autowired
    private WebDriver webDriver;

    @Test
    public void testController() {
    webDriver.getTitle();
    }

}

【问题讨论】:

    标签: spring maven spring-mvc spring-boot spring-test


    【解决方案1】:

    事实证明,默认情况下,Maven 的 Surefire 插件采用了一种技巧,即创建一个 Manifest-Only JAR 文件,以避免将完整的类路径传递给分叉的 JRE(请参阅本文)。 Jetty JSP 处理器只是向每个类加载器询问其 URL 列表,因此只看到一个仅清单 JAR 文件,而不是实际使用的所有 JAR 文件,因此找不到 TLD 文件。

    该页面上也记录了简单的解决方案,即关闭 useManifestOnlyJar 选项,如下所示:

    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
          <useManifestOnlyJar>false</useManifestOnlyJar>
        </configuration>
      </plugin>
      ....
    <plugin>
    

    这指示 Surefire 将完整的类路径直接传递给分叉的 JRE 进程,从而使其能够定位 TLD。 已回复from here

    【讨论】:

      【解决方案2】:

      尝试这样的部门:

      <groupId>javax</groupId>
              <artifactId>javaee-api</artifactId>
              <version>6.0</version>
              <scope>provided</scope>
          </dependency>
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>servlet-api</artifactId>
              <version>2.5</version>
              <scope>provided</scope>
          </dependency>
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>jstl</artifactId>
              <version>1.2</version>
          </dependency>
      

      【讨论】:

      • 恐怕不会改变任何东西。 JSTL 已经在类路径中,只是在运行时被忽略,当 spring-boot 在 maven 测试期间启动时。并且仅在运行时。
      猜你喜欢
      • 2019-12-27
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      • 2020-04-24
      • 2017-10-27
      • 1970-01-01
      相关资源
      最近更新 更多