【问题标题】:Apache Tomcat 8.0 unable to load servlet class written in Kotlin using Eclipse for Java EE, Mars 2Apache Tomcat 8.0 无法加载使用 Eclipse for Java EE、Mars 2 用 Kotlin 编写的 servlet 类
【发布时间】:2017-01-14 01:56:10
【问题描述】:

我正在使用 Eclipse for Java EE,Mars 2。我首先在这个 IDE 中使用 Java 8 和 Apache Tomcat 8.0.x 编写了一个 servlet 应用程序,并且运行良好。

现在,我正在尝试将代码移植到 Kotlin。但是,从下面发布的信息来看,Apache Tomcat 服务器似乎无法定位和加载我的课程LoginServlet

我已经移植了助手类和刚刚命名为LoginServlet 的一个servlet 类。我删除了这个问题中的所有其余代码,只是为了呈现一个简单的骨架。

这是我的设置:

package bookyard.server;

// import statements ommitted for brevity

open class LoginServlet : HttpServlet() {

    override fun doGet(request : HttpServletRequest, response : HttpServletResponse) {
        val msg: String = "HTTP GET method not supported.";

        try {
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } catch (e: IOException) {
            e.printStackTrace();
        }
    }

    override fun doPost(request : HttpServletRequest, response : HttpServletResponse) {
        this.doPostInternal(request, response);
    }

    private fun doPostInternal(request: HttpServletRequest, response: HttpServletResponse) {
        ...
    }
}

我首先用@WebServlet("/login") 注释对LoginServlet 类进行了注释,但是服务器运行得很好,但给了我一个404 路径/login 甚至ServletContext 路径http://localhost:8080/BookyardServer/

所以,我将 servlet 配置移至 WEB-INF\web.xml 文件,现在看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>BookyardServer</display-name>

  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>bookyard.server.LoginServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

</web-app>

我的项目构建路径包含对我的代码使用的所有库的引用。此处提供了它的快照。

在我的 Project FacetsTargeted Runtimes 中,我引用了 Apache Tomcat 8.0 运行时。

但是,当我Debug As -> Debug on Server时,浏览器报如下错误:

HTTP 状态 500 - 实例化 servlet 类 bookyard.server.LoginServlet 时出错

消息实例化 servlet 类 bookyard.server.LoginServlet 时出错

说明服务器遇到内部错误,导致它无法完成此请求。

例外 javax.servlet.ServletException:实例化 servlet 类时出错 bookyard.server.LoginServlet org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(未知来源)

根本原因 java.lang.ClassNotFoundException: bookyard.server.LoginServlet org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332) org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源) java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(未知来源)

我很确定这与 %CLASSPATH% 有关,但我不确定是什么。我在类路径中设置了 Apache Tomcat jar 文件。我的代码使用的所有其他内容也在类路径中。

我不确定为什么它不能加载我的 servlet 类。你能帮忙吗?

【问题讨论】:

  • 这和您的其他两个与课程路径相关的问题似乎非常广泛的“技术支持”类型的问题。什么是一个好问题:stackoverflow.com/help/how-to-ask ... 如果您了解您的 IDE 如何与 Web 应用程序一起工作以及它们如何将类文件部署到 Web 应用程序,那么您就会知道项目的哪一部分被破坏了。根据错误信息,您显示了所有错误的证据,因此您可能没有花时间学习基础知识。谷歌,问你的同事,做你的功课,在提问之前学习基础知识。这可能看起来很苛刻,还有其他网站可以提供交互式帮助

标签: eclipse apache tomcat servlets kotlin


【解决方案1】:

================================================ ====================

2017 年 9 月 4 日编辑:

朋友们好:

我找到了解决方法。也许它可以帮助你。

(1)创建一个Kotlin主类,例如:

fun main(args: Array<String>) {
    println("Hello, world!")
}

(2)右键单击这个主类,然后选择“运行”=>“Kotlin 应用程序” 这将使 Kotlin 插件编译所有 Kotlin 源文件,并生成类文件。

(3) 将您的 Web 应用部署到应用服务器,但使用输出的类文件夹而不是源文件夹。 例如,如果您的应用程序的“输出文件夹”是“var/classes”,您可以将其部署到 App Server, 像这样,在 WTP 设置文件 [.settings/org.eclipse.wst.common.component] 中:

<wb-resource deploy-path="/WEB-INF/classes" source-path="/var/classes"/>

您也可以从 Eclipse“Web 部署程序集”对话框中进行设置: https://eclipse.org/webtools/releases/3.2.0/NewAndNoteworthy/javaee.php

现在,Eclipse WTP 插件会将“var/classes”文件夹部署到应用服务器,其中包含了 Kotlin 插件编译的所有类文件

================================================ ====================

2016/11/17 编辑:

各位朋友,我为这个问题创建了一个问题:

https://youtrack.jetbrains.com/issue/KT-14838

================================================ ====================

看起来您的 kotlin 类未部署到 Tomcat 服务器。

我遇到了同样的问题,还在努力解决。

请阅读这篇文章: Can not publish Kotlin class files to Tomcat server

我终于解决了这个问题, 通过将以下设置添加到 WTP 设置文件 .settings/org.eclipse.wst.common.component 中:

<wb-resource deploy-path="/WEB-INF/classes" 
             source-path="/kotlin_bin"/>

现在 Kotlin 类文件将被编译到虚拟文件夹 /kotlin_bin 中,该文件夹中的类文件将被部署到 Tomcat Server 中。

但我认为 Kotlin Eclipse 插件应该为开发人员解决这个问题

但是出现了新问题

[/kotlin_bin]文件夹下的类文件只包含类和方法的声明信息,但这些类文件中没有生成实现代码。

所以,即使这些类文件被部署到 Tomcat 服务器中,当我尝试启动 Tomcat 服务器时,这些不完整的类文件也会导致 java.lang.ClassFormatError 错误信息如下:

方法中的缺失代码属性不是本机或抽象的 类文件xxxx/xxxx/xxxx

如果我从我的项目中运行控制台应用程序,kotlin 插件将编译源文件并生成类文件,然后我可以手动将这些类文件复制到 Tomcat 服务器。 但这很不方便,因为我必须在开发过程中一遍又一遍地这样做。

【讨论】:

  • 谢谢。我编辑了您的答案以包含您链接到的网址中的解决方案,以防万一该链接在几年后失效并且其他人陷入了这个问题。
  • 其实我没有解决这个问题。我以为我做到了,但发生了另一个错误。请阅读:discuss.kotlinlang.org/t/… [/kotlin_bin] 文件夹中的类文件只包含类和方法的声明信息,但这些类文件中没有生成实现代码。因此,这些不完整的类文件将导致 java.lang.ClassFormatError 并带有以下错误消息:Absent Code attribute in method that is not native or abstract in class file xxxx/xxxx/xxxx
  • 感谢您的更新。我现在从你的答案中去掉绿色检查,这样其他面临这个问题的人认为这不会解决他们的问题。就个人而言,我切换到 IntelliJ Ultimate 并获得了流畅的体验。但我同意,Kotlin 的 Eclipse 插件应该有更好的支持。 github.com/Sathyaish/Bookyard/…
  • 各位朋友,我为这个问题创建了一个问题:youtrack.jetbrains.com/issue/KT-14838
猜你喜欢
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 2015-09-14
  • 2015-08-26
  • 2015-12-09
  • 1970-01-01
相关资源
最近更新 更多