2016-07-01 79 views
1

我最近開始使用Java來處理AWS Lambda。帶有Java拋出的AWS Lambda NoClassDefFoundError是由本地拋出的ClassNotFoundException導致的

它一直很好,直到我開始使用Dagger 2進行注射。

現在LAMBDA引發以下錯誤:

{ 
    "errorMessage": "dagger/internal/Preconditions", 
    "errorType": "java.lang.NoClassDefFoundError", 
    "stackTrace": [ 
    "com.company.server.user.SignUpActionAws.handler(SignUpActionAws.java:27)", 
    "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)", 
    "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)", 
    "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)", 
    "java.lang.reflect.Method.invoke(Method.java:498)" 
    ], 
    "cause": { 
    "errorMessage": "dagger.internal.Preconditions", 
    "errorType": "java.lang.ClassNotFoundException", 
    "stackTrace": [ 
     "java.net.URLClassLoader.findClass(URLClassLoader.java:381)", 
     "java.lang.ClassLoader.loadClass(ClassLoader.java:424)", 
     "java.lang.ClassLoader.loadClass(ClassLoader.java:357)", 
     "com.company.server.user.SignUpActionAws.handler(SignUpActionAws.java:27)", 
     "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)", 
     "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)", 
     "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)", 
     "java.lang.reflect.Method.invoke(Method.java:498)" 
    ] 
    } 
} 

然而,這並不運行java -jar myjar.jar當本地發生。我也檢查過,班上有使用jar tvf myjar.jar

我使用Bazel構建。

我檢查過的其他問題表明,它可能是由於依賴不可用,但是,類的內容沒有依賴關係。

the Dagger repo摘自:

/* 
* Copyright (C) 2016 Google, Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package dagger.internal; 

/** 
* An adaptation of Guava's {@code com.google.common.base.Preconditions} that is specially tailored 
* to support checks applied in Dagger's generated code. 
*/ 
public final class Preconditions { 
    /** 
    * Ensures that an object reference passed as a parameter to the calling method is not null. 
    * 
    * @param reference an object reference 
    * @return the non-null reference that was validated 
    * @throws NullPointerException if {@code reference} is null 
    */ 
    public static <T> T checkNotNull(T reference) { 
    if (reference == null) { 
     throw new NullPointerException(); 
    } 
    return reference; 
    } 

    /** 
    * Ensures that an object reference passed as a parameter to the calling method is not null. 
    * 
    * @param reference an object reference 
    * @param errorMessage the exception message to use if the check fails 
    * @return the non-null reference that was validated 
    * @throws NullPointerException if {@code reference} is null 
    */ 
    public static <T> T checkNotNull(T reference, String errorMessage) { 
    if (reference == null) { 
     throw new NullPointerException(errorMessage); 
    } 
    return reference; 
    } 

    private Preconditions() {} 
} 

什麼可能運行一個獨立的罐子時不會對我的本地環境發生AWS會導致此問題?

在此先感謝

編輯1: 這裏是最小的BUILD文件:

java_binary(
    name = "bin", 
    srcs = glob(["Action.java"]), 
    main_class = "com.company.Action", 
    deps = [ 
    "//external:aws-lambda", 
    "//external:dagger", 
    ] 
) 

這裏是工作區文件:

bind(name = "aws-lambda", actual = "@com_amazonaws_aws_lambda_java_core//jar") 
maven_jar(
    name = "com_amazonaws_aws_lambda_java_core", 
    artifact = "com.amazonaws:aws-lambda-java-core:1.1.0" 
) 
bind(name = "dagger", actual = "@com_google_dagger//jar") 
maven_jar(
    name = "com_google_dagger", 
    artifact = "com.google.dagger:dagger:2.5", 
) 

這裏是Action.java(注意,我使用Preconditions直接使其成爲最小的實現,在我的實際代碼中,它嘗試構建組件時失敗):

package com.company; 

import com.amazonaws.services.lambda.runtime.Context; 

public class Action { 
    public static void main(String[] s) { 
    Action.handler(null, null); 
    } 

    public static String handler(String request, Context context) { 
    dagger.internal.Preconditions.checkNotNull(new Object(), "Test"); 
    return null; 
    } 
} 

如果您運行bazel build //src/main/com/company:bin_deploy.jar並將其上載到AWS Lambda函數,則應該失敗。如果你在本地運行bazel run //src/main/com/company:binjava -jar bazel-bin/src/main/com/company/bin_deploy.jar它會正常工作。

+0

如果您在打開罐子,說,WinZip的(或列出其內容與'在Linux上unzip' )你看到依賴關係嗎?他們在正確的地方嗎?如果他們不應該在罐子裏,你有他們在正確的地方部署在服務器上嗎? –

+0

是的,所有的課程都在那裏(包括Preconditions課程)。他們位於正確的位置。 就服務器而言,這就是AWS Lambda的用武之地。我將完整的jar(包含所有依賴關係)上傳到AWS Lambda,並從此處啓動。與此有關的事情似乎導致了問題。 – Zenton

+0

您的構建依賴項可能會被錯誤地聲明。你的構建文件是什麼樣的? –

回答

0

這一切都歸功於我的罐子裏面的匕首文件夾的權限。所有其他文件夾(例如com,org,mozilla)有755個,但不是匕首文件夾。我解壓縮了我的jar,運行了兩個命令將目錄轉換爲755,將這些文件轉換爲644,然後將其壓縮。

改變權限的命令:

From inside the unzipped directory: 
find . -type f -exec chmod 644 {} + 
find . -type d -exec chmod 755 {} + 

我不知道爲什麼它是到其他目錄不同的,當巴澤勒正在建設它。但這是問題。


對於未來的巴澤爾搜索,這裏是我現在使用genrule:

genrule(
    name = "target-aws", 
    srcs = ["target_deploy.jar"], 
    outs = ["target-aws.jar"], 
    cmd = """ 
    unzip -q $< -d t 
    cd t 
    find . -type f -exec chmod 644 {} + 
    find . -type d -exec chmod 755 {} + 
    zip ../[email protected] -q -r . 
    rm -rf t 
    """ 
) 
+0

有趣,很高興知道! – blueskin

相關問題