Ich habe vor kurzem begonnen, mit AWS Lambda mit Java herumzuspielen.AWS Lambda mit Java-NoClassDefFoundError verursacht durch ClassNotFoundException, die nicht lokal ausgelöst wird
Es lief gut, bis ich anfing, Dolch 2 für die Injektion zu verwenden.
Nun wirft Lambda den folgenden Fehler:
{
"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)"
]
}
}
jedoch dies nicht der Fall, wenn java -jar myjar.jar
lokal ausgeführt. Ich habe auch überprüft, dass die Klasse mit jar tvf myjar.jar
drin ist.
Ich baue mit Bazel.
Andere Fragen, die ich überprüft habe, haben darauf hingewiesen, dass es möglicherweise aufgrund einer Abhängigkeit nicht verfügbar sein, jedoch der Inhalt der Klasse hat keine Abhängigkeiten.
von the Dagger repo Genommen:
/*
* 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() {}
}
Was könnte das Problem auf AWS verursachen, die nicht auf meinem lokalen Umgebung auftritt, wenn ein in sich geschlossenes Gefäß läuft?
Vielen Dank im Voraus
Edit 1: ist die minimal-Datei BUILD:
java_binary(
name = "bin",
srcs = glob(["Action.java"]),
main_class = "com.company.Action",
deps = [
"//external:aws-lambda",
"//external:dagger",
]
)
Hier ist die Arbeitsbereich-Datei:
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",
)
Hier ist Action.java (beachten Sie, Ich verwende Preconditions direkt, um es zur minimalen Implementierung zu machen, in meinem tatsächlichen Code schlägt es fehl, wenn ich versuche, eine Komponente zu bauen):
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;
}
}
Wenn Sie bazel build //src/main/com/company:bin_deploy.jar
ausführen und es auf eine AWS Lambda-Funktion hochladen, sollte es fehlschlagen. Wenn Sie lokal bazel run //src/main/com/company:bin
oder java -jar bazel-bin/src/main/com/company/bin_deploy.jar
ausführen, wird es gut funktionieren.
Wenn Sie das Glas in öffnen, sagen wir, WinZip (oder seine Inhalte auflisten mit 'unzip' auf Linux) Siehst du die Abhängigkeiten? Sind sie am richtigen Ort? Wenn sie nicht im Jar enthalten sein sollen, haben Sie sie auf dem Server an der richtigen Stelle installiert? –
Ja, alle Klassen sind dort (einschließlich der Preconditions-Klasse). Sie sind am richtigen Ort. In Bezug auf den Server, das ist, wo AWS Lambda kommt. Ich lade mein volles Glas (mit allen Abhängigkeiten) zu AWS Lambda und es dauert es von dort. Etwas damit zu tun scheint Probleme zu verursachen. – Zenton
Ihre Build-Abhängigkeit wurde möglicherweise falsch deklariert. Wie sieht deine Build-Datei aus? –