2015-09-25 26 views
17

Ho difficoltà con l'installazione di una funzione Lambda basata su Java per ricevere messaggi da SNS. La mia funzione è simile al seguito:AWS Lambda NoClassDefFoundError

package com.mycompany; 

import com.amazonaws.services.lambda.runtime.Context; 
import com.amazonaws.services.lambda.runtime.LambdaLogger; 
import com.amazonaws.services.lambda.runtime.events.SNSEvent; 

public class LambdaHandler { 
    public void Handler(SNSEvent event, Context context) { 
     //Process the event 
    } 
} 

Compila proprio bene e io non ho alcun problema di caricare il file jar di Lambda (tramite la console Web).

Tuttavia, quando pubblico ad esso (via SNS attraverso la funzione lambda sottoscritto) con JSON che rappresenta il modello SNSEvent, la funzione Lambda genera la seguente eccezione:

Error loading method handler on class com.mycompany.LambdaHandler: class java.lang.NoClassDefFoundError java.lang.NoClassDefFoundError: com/amazonaws/services/lambda/runtime/events/SNSEvent at

java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetPublicMethods(Class.java:2902) at java.lang.Class.getMethods(Class.java:1615) Caused by: java.lang.ClassNotFoundException: com.amazonaws.services.lambda.runtime.events.SNSEvent at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

Io uso Maven + Netbeans ed è un progetto di applicazione Java Maven. Ho scaricato la funzione dalla console Lambda e confermato, il barattolo ha una directory lib/con tutti i jar per le importazioni, incluso aws-lambda-java-events-1.1.0.jar, che a sua volta include/com/amazonaws /services/lambda/runtime/events/SNSEvent.class file.

Perché il runtime non è in grado di trovare la classe quando è definitivamente nel file jar? C'è qualcos'altro che devo fare, impostare qualsiasi variabile di ambiente, ecc.?

Qualsiasi aiuto sarebbe apprezzato!

EDIT 1 ho provato il downgrade a AWS-lambda-java-1.0.0 eventi ed è ancora segnalato la stessa eccezione. Come richiesto, di seguito è il mio file POM (con solo il nome del progetto modificato). Non so come dire a Maven di mettere le librerie in una struttura ad albero.

<?xml version="1.0" encoding="UTF-8"?> 
<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>com.app</groupId> 
    <artifactId>Handler</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 
    <dependencies> 
     <dependency> 
      <groupId>com.amazonaws</groupId> 
      <artifactId>aws-java-sdk-lambda</artifactId> 
      <version>1.10.6</version> 
     </dependency> 
     <dependency> 
      <groupId>com.amazonaws</groupId> 
      <artifactId>aws-lambda-java-core</artifactId> 
      <version>1.0.0</version> 
     </dependency> 
     <dependency> 
      <groupId>com.amazonaws</groupId> 
      <artifactId>aws-lambda-java-events</artifactId> 
      <version>1.0.0</version> 
     </dependency> 
    </dependencies> 
    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <maven.compiler.source>1.8</maven.compiler.source> 
     <maven.compiler.target>1.8</maven.compiler.target> 
    </properties> 
</project> 
+0

Puoi condividere la sezione pertinente del tuo file Maven? La mia funzione Lambda funzionante comparabile non associava aws-lambda-java-events-1.1.0.jar sotto lib, aveva il file SNSEvent.class libero com/amazonaws/services/lambda/runtime/events/SNSEvents.class. – James

+0

Posso arrivare stasera quando torno a casa, ma cosa vuoi dire che ha il file SNSEvent.class "loose"? Come funziona se non fornisce l'ambiente runtime con il vaso della libreria? – Brooks

+0

Il mio progetto non raggruppa il loro barattolo nel mio barattolo. Raggruppa le classi compilate nel mio jar nella gerarchia di cartelle classpath accanto alle classi compilate per il mio codice. – James

risposta

11

Utilizza la maven-shade plugin modo che il JAR contiene le dipendenze in un super-vaso.

Quindi, aggiungere questo al vostro pom.xml

<build> 
<plugins> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-shade-plugin</artifactId> 
    <version>2.3</version> 
    <configuration> 
     <createDependencyReducedPom>false</createDependencyReducedPom> 
    </configuration> 
    <executions> 
     <execution> 
     <phase>package</phase> 
     <goals> 
      <goal>shade</goal> 
     </goals> 
     </execution> 
    </executions> 
    </plugin> 
</plugins> 

Fonte: http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html

Potenzialmente si può avere questo problema https://github.com/aws/aws-lambda-java-libs/issues/2 che richiede un downgrade a AWS-lambda-java-eventi -1.0.0.jar

+2

Sfortunatamente, questo non ha funzionato per me ... ottenendo sempre la stessa eccezione. – Brooks

+1

Ah, ho appena visto il tuo pom.xml. Prova a utilizzare il plugin maven-shade come descritto qui: http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html – Mike76

+0

Worked! Accetterò, ma dovresti inserire l'URL nella tua risposta in modo che possa essere ulteriormente pubblicizzato. – Brooks

0

Nella sezione plugin del tuo pom.xml, aggiungi lo Apache Maven Shade Plugin. Viene utilizzato durante l'edificio processo d. Questo plugin è usato per confezionare i jar per creare un file .jar autonomo. Il plugin maven-shade prenderà artefatti (jar) prodotti dall'obiettivo del pacchetto e creerà un file .jar autonomo che contiene il codice compilato e le dipendenze risolte dal pom.xml.

<dependency> 
<groupId>org.apache.maven.plugins</groupId> 
<artifactId>maven-shade-plugin</artifactId> 
<version>3.0.0</version> 

1

A volte è necessario per caricare nuovamente la lambda. Inoltre ho ottenuto lo stesso problema che ho risolto con questo pom.xml:

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencyManagement> 
    <dependencies> 
    <dependency> 
     <groupId>com.amazonaws</groupId> 
     <artifactId>aws-java-sdk-bom</artifactId> 
     <version>1.11.83</version> 
     <type>pom</type> 
     <scope>import</scope> 
    </dependency> 
    </dependencies> 

</dependencyManagement> 

    <dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>3.8.1</version> 
     <scope>test</scope> 
    </dependency> 
    </dependencies> 

    <build> 
<plugins> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-shade-plugin</artifactId> 
    <version>2.3</version> 
    <configuration> 
     <createDependencyReducedPom>false</createDependencyReducedPom> 
    </configuration> 
    <executions> 
     <execution> 
     <phase>package</phase> 
     <goals> 
      <goal>shade</goal> 
     </goals> 
     </execution> 
    </executions> 
    </plugin> 
</plugins> 
</build> 
</project> 
+1

Ricorda di includere le tue dipendenze aws! –

+0

Ha, "caricare di nuovo il barattolo di nuovo" ha funzionato per me. Forse ho accidentalmente caricato il "vaso originale" per sbaglio. –