如何将javax.activation.DataSource添加到App Engine devserver? [英] How to add javax.activation.DataSource to App Engine devserver?

查看:80
本文介绍了如何将javax.activation.DataSource添加到App Engine devserver?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl; dr:如何将javax.activation.DataSource依赖项添加到通过App Engine Maven插件运行的服务器上?

tl;dr: How do I add the javax.activation.DataSource dependency to a server run through the App Engine Maven plugin?

我正在使用 App Engine Maven插件部署到本地App Engine服务器,而我正尝试使用Blobstore API上载文件.我正在使用Java 11.

I'm using the App Engine Maven plugin to deploy to a local App Engine server, and I'm trying to use the Blobstore API to upload a file. I'm using Java 11.

pom.xml

<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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>io.happycoding</groupId>
  <artifactId>blobstore-test</artifactId>
  <version>1</version>
  <packaging>war</packaging>

  <properties>
    <!-- App Engine currently supports Java 8 -->
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-spec</artifactId>
      <version>1.2.5</version>
    </dependency>

    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>1.9.59</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-maven-plugin</artifactId>
        <version>1.9.71</version>
      </plugin>
    </plugins>
  </build>
</project>

index.jsp

<%@ page import="com.google.appengine.api.blobstore.BlobstoreServiceFactory" %>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>

    <form action="<%= BlobstoreServiceFactory.getBlobstoreService().createUploadUrl("/submit") %>" 
      method="POST"
      enctype="multipart/form-data">

      Enter some text:
      <br/>
      <textarea name="text"></textarea>
      <br/>
      Select a file:
      <input type="file" name="image">
      <br/>
      <input type="submit" value="Submit">
    </form>

  </body>
</html>

SubmitServlet.java

package io.happycoding.servlets;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/submit")
public class SubmitServlet extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("data submitted");
  }
}

运行本地服务器的命令: mvn appengine:devserver

我可以成功运行本地服务器,并且可以看到表单呈现正确,包括Blobstore URL.

I can successfully run a local server, and I can see that the form is rendered correctly, including the Blobstore URL.

但是,当我提交表单时,出现此错误:

However, when I submit the form, I get this error:

java.lang.NoClassDefFoundError: javax/activation/DataSource
    at com.google.appengine.api.blobstore.dev.UploadBlobServlet.handleUpload(UploadBlobServlet.java:171)
    at com.google.appengine.api.blobstore.dev.UploadBlobServlet.access$000(UploadBlobServlet.java:69)
    at com.google.appengine.api.blobstore.dev.UploadBlobServlet$1.run(UploadBlobServlet.java:115)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.google.appengine.api.blobstore.dev.UploadBlobServlet.doPost(UploadBlobServlet.java:112)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:867)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1623)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:134)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.appengine.tools.development.jetty9.StaticFileFilter.doFilter(StaticFileFilter.java:123)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1610)
    at com.google.appengine.tools.development.DevAppServerRequestLogFilter.doFilter(DevAppServerRequestLogFilter.java:44)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1602)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:540)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
    at com.google.appengine.tools.development.jetty9.DevAppEngineWebAppContext.doScope(DevAppEngineWebAppContext.java:94)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at com.google.appengine.tools.development.jetty9.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:595)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
    at org.eclipse.jetty.server.Server.handle(Server.java:502)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ClassNotFoundException: javax.activation.DataSource
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
    at com.google.appengine.tools.development.DevAppServerClassLoader.loadClass(DevAppServerClassLoader.java:108)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 57 more

一些谷歌搜索揭示了有关此问题的很多问题:

Some Googling reveals quite a few questions about this problem:

  • Migration to JDK 11 has error occure "java.lang.NoClassDefFoundError: javax/activation/DataSource"
  • java.lang.NoClassDefFoundError: javax/activation/DataSource on wsimport Intellij java 9
  • What is the replacement for javax.activation package in java 9?
  • NoClassDefFoundError: javax/activation/DataSource

这些问题的答案建议添加以下依赖项的组合:

The answers to these questions suggest adding a combination of these dependencies:

<dependency>
  <groupId>javax.activation</groupId>
  <artifactId>javax.activation-api</artifactId>
  <version>1.2.0</version>
</dependency>

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

<dependency>
    <groupId>com.sun.activation</groupId>
    <artifactId>javax.activation</artifactId>
    <version>1.2.0</version>
</dependency>

我尝试添加所有这些,并且尝试添加所有这些.但是无论如何,我仍然会遇到上述错误.

I've tried adding each of these, and I've tried adding all of them. But no matter what, I still get the above error.

我了解为什么发生这种情况:Java 8包含了javax.activation.DataSource类,随后将其删除了.因此,由于我使用的是Java 11,因此缺少该类.但是到目前为止,我尝试过的所有依赖项似乎都没有提供缺少的类,可能是因为我使用的是App Engine Maven插件,而不是运行自己的服务器?

I understand why this is happening: Java 8 included the javax.activation.DataSource class, and it was subsequently removed. So since I'm using Java 11, that class is missing. But none of the dependencies I've tried so far seem to provide the missing class, possibly because I'm using the App Engine Maven plugin instead of running my own server?

如何将此依赖项添加到使用App Engine Maven插件的项目中?

How do I add this dependency to a project that uses the App Engine Maven plugin?

推荐答案

我首先尝试添加

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
</dependency>

正如您所指出的,

但我的期望是您会收到NoClassDefFound错误,因为javax.activation类并未被maven加入战争.出于这个原因,我仍然主要还是用Ant来做罐子/战舰/耳部建筑:更加冗长,但魔术性却较低.如果查看项目的/target文件夹,则应该能够看到war文件:如果执行jar tf <warfile>,则应该能够看到添加到WEB-INF/lib的所有jar文件,这将告诉您是否它正在添加激活罐.

as you pointed out, but my expectation is that you're getting the NoClassDefFound error because the javax.activation classes aren't getting added to the war by maven. I still mostly do my jar/war/ear building with Ant for this very reason: more verbose, but less magic. If you look in your project's /target folder you should be able to see the war file: if you do a jar tf <warfile> you should be able to see all the jar files added to WEB-INF/lib, and this will tell you if it is adding the activation jar.

查看 https://github.com/GoogleCloudPlatform/appengine-maven-plugin,推荐的示例包括此插件:

Looking at https://github.com/GoogleCloudPlatform/appengine-maven-plugin, the recommended sample includes this plugin:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.3</version>
            <configuration>
                <archiveClasses>true</archiveClasses>
            </configuration>
        </plugin>

在pom的build部分中的appengine-maven-plugin条目之前.我会把它放进去,然后看看它是否能正确地引发战争.

before the appengine-maven-plugin entry in the build section of your pom. I'd put that in and then see if it properly builds the war.

这篇关于如何将javax.activation.DataSource添加到App Engine devserver?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆