我最近開始使用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:bin
或java -jar bazel-bin/src/main/com/company/bin_deploy.jar
它會正常工作。
如果您在打開罐子,說,WinZip的(或列出其內容與'在Linux上unzip' )你看到依賴關係嗎?他們在正確的地方嗎?如果他們不應該在罐子裏,你有他們在正確的地方部署在服務器上嗎? –
是的,所有的課程都在那裏(包括Preconditions課程)。他們位於正確的位置。 就服務器而言,這就是AWS Lambda的用武之地。我將完整的jar(包含所有依賴關係)上傳到AWS Lambda,並從此處啓動。與此有關的事情似乎導致了問題。 – Zenton
您的構建依賴項可能會被錯誤地聲明。你的構建文件是什麼樣的? –