【问题标题】:Initialising AWS in a Java Applet on a Spring server在 Spring 服务器上的 Java Applet 中初始化 AWS
【发布时间】:2016-01-20 00:03:48
【问题描述】:

我正在尝试使用 Amazon 的 SDK 将文件从 Java 小程序上传到 Amazon S3。小程序位于运行 Spring 的 Web 服务器上。

问题是,在我尝试上传文件之前,我需要初始化 Amazon S3 客户端。这通常很简单:

AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
AmazonS3Client s3Client = new AmazonS3Client(credentials);

但是当我这样做时,第二行会触发此错误消息(无论凭据是否正确):

java.lang.ClassFormatError: Incompatible magic value 1008813135 in class file <!DOCTYPE html>
    at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_66]
    at java.lang.ClassLoader.defineClass(Unknown Source) ~[na:1.8.0_66]
    at java.security.SecureClassLoader.defineClass(Unknown Source) ~[na:1.8.0_66]
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source) ~[na:na]
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source) ~[na:na]
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source) ~[na:na]
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source) ~[na:na]
    at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_66]
    at org.apache.commons.logging.LogFactory.createFactory(LogFactory.java:1131) ~[upload.jar:na]
    at org.apache.commons.logging.LogFactory$2.run(LogFactory.java:1065) ~[upload.jar:na]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_66]
    at org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:1062) ~[upload.jar:na]
    at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:569) ~[upload.jar:na]
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685) ~[upload.jar:na]
    at com.amazonaws.AmazonWebServiceClient.<clinit>(AmazonWebServiceClient.java:56) ~[upload.jar:na]

这里发生的是 AWS 库正在尝试初始化其日志记录系统,因此它开始搜索将处理任何内部日志记录消息的 LogFactory。问题是它开始在小程序之外搜索,通过对

发出 GET 请求
http://localhost/...myUrl.../commons-logging.properties

(我从这里的文档中发现了这一点:https://commons.apache.org/proper/commons-logging/apidocs/org/apache/commons/logging/package-summary.html

现在,附注一下:我的 security-app-context.xml Spring 文件包含以下入口点 bean,以确保未经身份验证的用户只能看到登录页面:

<beans:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:constructor-arg value="/loginPage" />
</beans:bean>

在这个阶段,我的 Spring 设置正在捕获 GET 请求并将其重定向到服务器登录页面。此重定向最终会发送一个有效的 HTML 页面作为此 GET 请求的结果。 HTML 页面的第一行是 '',Logging Framework 对其进行解析并尝试使用它来初始化 Java 类。显然,一个名为 .class 的类不存在,所以我得到了 ClassFormatError。

有没有办法让 AWS 库与此设置完美配合?理想情况下不禁用 Spring 的重定向策略。

【问题讨论】:

  • 也许我遗漏了一些东西...但是您真的认为在小程序中分发您的 aws 凭据是个好主意吗? (在客户端机器上运行!)
  • 这是一个公平的观点,在正常情况下我会同意。但是,在这种情况下,AWS 凭证适用于具有严格限制访问权限的帐户,并且对小程序本身的访问受到我正在尝试解决的同一登录系统的保护。

标签: java spring amazon-web-services amazon-s3 applet


【解决方案1】:

您可以通过将此行放在new AmazonS3Client() 调用之前的某处,告诉日志记录框架在哪里可以找到 LogFactory 实现来解决该特定错误:

System.setProperty("org.apache.commons.logging.LogFactory", "org.apache.commons.logging.impl.LogFactoryImpl");

但是,您可能会发现不同的文件也会出现同样的问题,实际上其中两个文件在 Amazon 的库中更深一些。再次使用 GET 请求搜索它们(如 Java 控制台中所示)。

http://localhost/...myUrl.../com/amazonaws/services/s3/request.handlers
http://localhost/...myUrl.../com/amazonaws/services/s3/request.handler2s

因此,您需要一个名为 request.handlers 的文件和另一个名为 request.handler2s 的文件,它们都位于 com/amazonaws/services/s3 的文件夹结构中,其中一个 Classpath 文件夹中的 com 文件夹(可能是您的小程序 JAR 的根目录)文件)。文件应该是空的。

将 LogFactory 属性设置为防止搜索 commons-logging.properties,并且 Amazon 请求处理程序文件就位,初始化应该会成功完成。

(这个答案感觉有点笨拙,我对此并不完全满意,因此非常欢迎替代方案)。

【讨论】:

    猜你喜欢
    • 2023-03-09
    • 2023-03-18
    • 2014-06-25
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多