Компиляция JSP на Android (встроенный Jetty)

Я запускаю Jetty на платформе Android для обслуживания статических html-страниц и сервлета. Теперь я попытался добавить поддержку страниц JSP, но у меня есть это исключение, когда я запрашиваю любой jsp:

HTTP ERROR 500

Problem accessing /time.jsp. Reason:

    Server Error

Caused by:

org.apache.jasper.JasperException: PWC6033: Error in Javac compilation for JSP

PWC6199: Generated servlet error:
The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files

PWC6199: Generated servlet error:
The type java.lang.Throwable cannot be resolved. It is indirectly referenced from required .class files

PWC6199: Generated servlet error:
The type java.lang.String cannot be resolved. It is indirectly referenced from required .class files

PWC6199: Generated servlet error:
org.apache.jasper.runtime.HttpJspBase cannot be resolved to a type

PWC6199: Generated servlet error:
org.apache.jasper.runtime.JspSourceDependent cannot be resolved to a type

PWC6199: Generated servlet error:
JspFactory cannot be resolved to a type

PWC6199: Generated servlet error:
JspFactory cannot be resolved

PWC6199: Generated servlet error:
java.util.List cannot be resolved to a type

PWC6199: Generated servlet error:
Syntax error, parameterized types are only available if source level is 1.5 or greater

PWC6199: Generated servlet error:
String cannot be resolved to a type

PWC6199: Generated servlet error:
org.glassfish.jsp.api.ResourceInjector cannot be resolved to a type

PWC6199: Generated servlet error:
java.util.List cannot be resolved to a type

PWC6199: Generated servlet error:
Syntax error, parameterized types are only available if source level is 1.5 or greater

PWC6199: Generated servlet error:
String cannot be resolved to a type

PWC6199: Generated servlet error:
_jspx_dependants cannot be resolved to a variable

PWC6199: Generated servlet error:
HttpServletRequest cannot be resolved to a type

PWC6199: Generated servlet error:
HttpServletResponse cannot be resolved to a type

PWC6199: Generated servlet error:
java.io.IOException cannot be resolved to a type

PWC6199: Generated servlet error:
ServletException cannot be resolved to a type

PWC6199: Generated servlet error:
PageContext cannot be resolved to a type

PWC6199: Generated servlet error:
HttpSession cannot be resolved to a type

PWC6199: Generated servlet error:
ServletContext cannot be resolved to a type

PWC6199: Generated servlet error:
ServletConfig cannot be resolved to a type

PWC6199: Generated servlet error:
JspWriter cannot be resolved to a type

PWC6199: Generated servlet error:
Object cannot be resolved to a type

PWC6199: Generated servlet error:
JspWriter cannot be resolved to a type

PWC6199: Generated servlet error:
PageContext cannot be resolved to a type

PWC6199: Generated servlet error:
_jspxFactory cannot be resolved

PWC6199: Generated servlet error:
_jspx_resourceInjector cannot be resolved to a variable

PWC6199: Generated servlet error:
org.glassfish.jsp.api.ResourceInjector cannot be resolved to a type

PWC6197: An error occurred at line: 3 in the jsp file: /time.jsp
PWC6199: Generated servlet error:
java.util.Date cannot be resolved to a type

PWC6199: Generated servlet error:
Throwable cannot be resolved to a type

PWC6199: Generated servlet error:
SkipPageException cannot be resolved to a type

PWC6199: Generated servlet error:
ServletException cannot be resolved to a type

PWC6199: Generated servlet error:
_jspxFactory cannot be resolved


    at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:129)
    at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:299)
    at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:392)
    at org.apache.jasper.compiler.Compiler.compile(Compiler.java:453)
    at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:625)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:457)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1075)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:384)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1009)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:856)

Powered by Jetty://

Вот мой код конфигурации из основного действия:

public void startServer()
{
        server = new Server(8080);

        System.setProperty("org.apache.jasper.compiler.disablejsr199", "true");

      // Create a resource handler for static content.
        ResourceHandler staticResourceHandler = new ResourceHandler();
        staticResourceHandler.setResourceBase(Environment.getExternalStorageDirectory().getAbsolutePath() + "/web/static/");
        staticResourceHandler.setDirectoriesListed(false);

        // Create context handler for static resource handler.
        ContextHandler staticContextHandler = new ContextHandler();
        staticContextHandler.setContextPath("/static");
        staticContextHandler.setHandler(staticResourceHandler);

        // Create WebAppContext for JSP files.
        WebAppContext webAppContext = new WebAppContext();
        webAppContext.setContextPath("/");
        webAppContext.setResourceBase(Environment.getExternalStorageDirectory().getAbsolutePath() + "/web/");
        webAppContext.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");

        // Create servlet context handler for main servlet.
        ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletContextHandler.setContextPath("/servlet");
        servletContextHandler.setResourceBase(Environment.getExternalStorageDirectory().getAbsolutePath() + "/web/servlet/");

        terminalServlet = new TerminalServlet(this);
        networkServlet = new NetworkDrawerServlet(this);
        servletContextHandler.setClassLoader(Thread.currentThread().getContextClassLoader());
        servletContextHandler.addServlet(new ServletHolder(terminalServlet),"/terminal");
        servletContextHandler.addServlet(new ServletHolder(networkServlet),"/topology");
        //servletContextHandler.addServlet(new ServletHolder(new DefaultServlet()), "/*");

        // Create a handler list to store our static, jsp and servlet context handlers.
        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new org.eclipse.jetty.server.Handler[] { staticContextHandler, webAppContext, servletContextHandler });

        // Add the handlers to the server and start jetty.
        server.setHandler(handlers);
    try {
        server.start();
    } catch (Exception e) {
    }
}

Я помещаю файлы веб-сервера (статический контент и файл jsp) в каталог «/web/» во внешнем хранилище (и это работает для статического контента, я установил права чтения и записи в файле манифеста).

Я думаю, что это общая проблема конфигурации под Android, потому что тот же код, скомпилированный и выполненный на рабочем столе, работает нормально.


person Alvins    schedule 05.06.2013    source источник


Ответы (2)


JSP невозможен на Android.

Или, если быть более точным, компиляция JSP на устройстве Android невозможна.

Существующие реализации JspServlet будут пытаться скомпилировать *.java исходный код в каталог в виде *.class файлов, стандартного javac нет, поэтому можно подумать, что для этого можно использовать реализацию JDT, написанную Eclipse, но даже это не сработает для несколько основных причин.

  1. Базовая библиотека классов отсутствует в стандартных местах, которые ищет компилятор JDT. Вот почему вы видите все ошибки «не удается устранить».
  2. Компиляция в файлы *.class на Android бессмысленна, так как само устройство Android не понимает файлы *.class. Это не Java, а Dalvik, который совместим (во время разработки/сборки) с Java.
  3. Виртуальная машина Android Dalvik ожидает дексифицированный байт-код, компилятор JDT не может его создать.
  4. Я не знаю ни одного встроенного в устройство инструмента, библиотеки или утилиты для расшифровки, которые могли бы сделать этот последний шаг за вас. Если он существует, вам нужно будет разветвить и изменить реализацию JSP, чтобы включить этот дополнительный шаг.

Если вы хотите разрабатывать в JSP и иметь веб-приложение на Android, вам нужно сделать следующее:

  1. Удалите JspServlet из вашего файла web.xml или webdefault.xml. Вы не можете использовать его на Android в любом случае.
  2. Предварительно скомпилируйте JSP на своем компьютере для разработки.
  3. Обновите свой WEB-INF/web.xml, чтобы включить скомпилированные ссылки JSP. Посмотрите на различные инструменты JSPC, все они поддерживают эту концепцию (либо в виде XML-фрагмента, подходящего для включения, либо путем прямой модификации вашего существующего файла WEB-INF/web.xml.
  4. Расшифруйте посткомпилированный WAR-файл, используя методы, описанные в проекте i-jetty.

Это позволит вам разрабатывать с помощью JSP и использовать их на Android, но не в виде самого необработанного файла *.jsp, а скорее в виде скомпилированного файла *.class files (который затем дексифицируется в формате байт-кода Android).

person Joakim Erdfelt    schedule 05.06.2013
comment
Если бы я все обдумал, я бы понял, что функциональности .class-›dex просто не было. Хороший улов там. У меня все работает, хотя, удивлен, как далеко это зашло. - person stu; 13.04.2014

джетти не для этого?

http://www.eclipse.org/jetty/documentation/current/configuring-jsp.html#jsp-support

person pistoleta    schedule 14.02.2014