关于Java:从IntelliJ Idea社区运行嵌入式Tomcat时遇到问题

Trouble running embedded Tomcat from IntelliJ Idea Community

我试图在此处使用答案,以便从IntelliJ Idea Community Edition中的Oracle运行此示例。我创建了一个新项目,复制了示例中的源代码,并在Idea中启用了Maven支持。我可以创建并运行该项目,但是无法在浏览器中访问该服务。 Tomcat不断抛出404。请注意,源代码和pom.xml文件未更改。

pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.employees</groupId>
    employees-app</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>employees-app Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <tomcat.version>7.0.57</tomcat.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            tomcat-embed-logging-juli</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            tomcat-embed-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            tomcat-jasper</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            tomcat-jasper-el</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            tomcat-jsp-api</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
     <build>
        <finalName>employees-app</finalName>
        <resources>
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>

            </plugin>          
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <finalName>employees-app-${project.version}</finalName>
                   
                        <manifest>
                            <mainClass>com.example.employees.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

使用Process Monitor,我已经能够确定Tomcat将网站的根目录(localhost:8080)与MyProject \\\\ target \\\\ classes关联了。如果我在其中放置了一个虚拟txt文件,则可以通过浏览器访问它(例如localhost:8080 / test.txt)。

'classes'目录不为空。它包含两个子目录:

  • com / example / employees / *。class-所有班级文件
  • META-INF / resources / [Oracle中/ main / src / webapp中的所有内容
    例子 ]
  • 我的直觉是输出的文件夹层次结构有问题。我不确定该如何解决。有什么想法吗?


    我知道了。

    如链接文章所示,最好使用Heroku的启动器和pom.xml文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <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/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.heroku.sample</groupId>
      embeddedTomcatSample</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
      <name>embeddedTomcatSample Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <properties>
        <tomcat.version>8.0.28</tomcat.version>
      </properties>
      <dependencies>
        ...tomcat & other deps...
      </dependencies>
      <build>
        <finalName>embeddedTomcatSample</finalName>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                appassembler-maven-plugin</artifactId>
                <version>1.1.1</version>
                <configuration>
                    target</assembleDirectory>
                    <programs>
                        <program>
                            <mainClass>launch.Main</mainClass>
                            <name>webapp</name>
                        </program>
                    </programs>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </build>
    </project>

    此启动器功能通过以编程方式将Tomcat配置为在项目目录中运行来完成大多数工作。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public static void main(String[] args) throws Exception {

            String webappDirLocation ="src/main/webapp/";
            Tomcat tomcat = new Tomcat();

            //The port that we should run on can be set into an environment variable
            //Look for that variable and default to 8080 if it isn't there.
            String webPort = System.getenv("PORT");
            if(webPort == null || webPort.isEmpty()) {
                webPort ="8080";
            }

            tomcat.setPort(Integer.valueOf(webPort));

            StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
            System.out.println("configuring app with basedir:" + new File("./" + webappDirLocation).getAbsolutePath());

            // Declare an alternative location for your"WEB-INF/classes" dir
            // Servlet 3.0 annotation will work
            File additionWebInfClasses = new File("target/classes");
            WebResourceRoot resources = new StandardRoot(ctx);
            resources.addPreResources(new DirResourceSet(resources,"/WEB-INF/classes",
                    additionWebInfClasses.getAbsolutePath(),"/"));
            ctx.setResources(resources);

            tomcat.start();
            tomcat.getServer().await();
        }

    我不知道如何以编程方式设置Tomcat的conf文件夹的路径,但是由于这个答案,我能够克服这一问题。在正常情况下,Tomcat会负责设置初始上下文。结果,Web应用程序的context.xml文件中的环境变量最终出现在初始上下文中。幸运的是,可以通过自定义的InitialContextFactory复制此内容。