2
votes

I am using Eclipse for Java EE, Mars 2. I wrote a servlet application first using Java 8 and Apache Tomcat 8.0.x in this IDE and that runs just fine.

Now, I am trying to port the code to Kotlin. But the Apache Tomcat server, it seems like from the information posted below, is unable to locate and load my class LoginServlet.

I've ported the helper classes and just the one servlet class just now named LoginServlet. I am removing all the rest of the code in this question just to present a bare bones skeleton.

Here is my set up:

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

I first annotated the LoginServlet class with the @WebServlet("/login") annotation but that ran the server just fine but gave me a 404 for the path /login and even for the ServletContext path http://localhost:8080/BookyardServer/.

So, I moved the servlet configuration to the WEB-INF\web.xml file and it now looks like this:

<?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>

My project Build Path includes references to all the libraries my code uses. A snapshot of it is provided here.

enter image description here

In my Project Facets and the Targeted Runtimes, I have a reference to the Apache Tomcat 8.0 runtime.

enter image description here

enter image description here

However, when I Debug As -> Debug on Server, the browser reports the following error:

HTTP Status 500 - Error instantiating servlet class bookyard.server.LoginServlet

message Error instantiating servlet class bookyard.server.LoginServlet

description The server encountered an internal error that prevented it from fulfilling this request.

exception javax.servlet.ServletException: Error instantiating servlet class 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(Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Unknown Source)

root cause 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(Unknown Source) java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.lang.Thread.run(Unknown Source)

I am pretty sure this has something to do with the %CLASSPATH% but I am not sure what. I have set the Apache Tomcat jar files in the class path. Everything else that my code uses is also in the class path.

I am not sure why it isn't able to load my servlet class. Could you please help?

1
This and your two other class path related issues seem very broad "technical support" type questions. What makes a good question: stackoverflow.com/help/how-to-ask ... If you understood how your IDE works with web apps and how they deploy class files to a web app, then you would know which part of your project is broken. You show all the wrong evidence given your error message, so maybe you haven't taken the time to learn the basics. Google, ask your coworkers, do your homework, learn the basics before asking questions. This may seem harsh, there are other sites for interactive helpJayson Minard

1 Answers

1
votes

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

EDIT at 2017/09/04:

Hi friends:

I find a workaround. Maybe it can help you.

(1)Create a Kotlin main class, for example:

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

(2)Right click this main class, and select "Run"=>"Kotlin Application" This will make the Kotlin plugin compile all the Kotlin source files, and generate class files.

(3)Deploy your web app to the App server, but use the outputed class folder instead of the source folders. for example, if the "output folder" of your app is "var/classes", you can deploy it to the App Server, like this, in the WTP setting file [.settings/org.eclipse.wst.common.component] :

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

also you can set this from the Eclipse "Web Deployment Assembly" dialog: https://eclipse.org/webtools/releases/3.2.0/NewAndNoteworthy/javaee.php

Now, Eclipse WTP plugin will deploy the "var/classes" folder to the app Server, which include all the class files compiled by the Kotlin plugin

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

EDIT at 2016/11/17:

Hi friends, I created an issue for this problem:

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

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

Looks like your kotlin class is not delpoyed to the Tomcat server.

I have the same problem, and still working on it.

Please read this post: Can not publish Kotlin class files to Tomcat server

I finally solved this problem, by adding the following setting into the WTP setting file .settings/org.eclipse.wst.common.component :

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

Now the Kotlin class files will be compiled into virtual folder /kotlin_bin, and class files in this folder will be deployed into Tomcat Server.

But I think the Kotlin Eclipse plugin should take care of this problem for developers

But new problem happened.

The class files in the [/kotlin_bin] folder contain only the class and method declaration information, but the implementation code are not generated in these class files.

So, even these class files are deployed into the Tomcat Server, When I try to start the Tomcat Server, these incomplete class files will cause a java.lang.ClassFormatError with the following error message:

Absent Code attribute in method that is not native or abstract in class file xxxx/xxxx/xxxx

If I run a console app from my project, the kotlin plugin will compile source files and generate class files, then I can copy these class files to the Tomcat Server manually. But this is very inconvenience because I have to do it over and over again in my development process.