2015-09-25 3 views
17

У меня возникли трудности с настройкой функции Lambda на основе Java для приема сообщений от SNS. Моя функция выглядит следующим образом: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 
    } 
} 

Это компилируется нормально, и у меня нет никаких проблем с загрузкой файла банки с Lambda (через веб-консоль).

Однако, когда я публикую к нему (через SNS до подписной функции лямбды) с JSON, представляющая моделью SNSEvent, функция лямбды выдает следующее исключение:

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)

я использую Maven + Netbeans и это проект приложения Maven Java. Я загрузил функцию с консоли Lambda и подтвердил, что в jar есть каталог lib/со всеми банками для импорта, включая aws-lambda-java-events-1.1.0.jar, который сам включает в себя/com/amazonaws /services/lambda/runtime/events/SNSEvent.class.

Почему среда выполнения не может найти класс, когда он определенно находится в файле jar? Есть ли что-нибудь еще, что мне нужно сделать, установить любые переменные среды и т. Д.?

Любая помощь будет оценена!

EDIT 1 Я попытался понижая к AWS-лямбда-Java-событий 1.0.0, и это все еще сообщающих же исключение. В соответствии с запросом ниже приведен мой файл POM (только с измененным именем проекта). Я не знаю, как сказать Maven, чтобы поместить библиотеки в древовидную структуру.

<?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

Можете ли вы поделиться соответствующим разделом вашего файла Maven? Моя сопоставимая работая функция Лямбда не связывала aws-lambda-java-events-1.1.0.jar под lib, у нее был файл SNSEvent.class как com/amazonaws/services/lambda/runtime/events/SNSEvents.class. – James

+0

Я могу этим вечером, когда я вернусь домой, но что вы имеете в виду, что файл SNSEvent.class «свободен»? Как это работает, если оно не обеспечивает среду выполнения с банкой библиотеки? – Brooks

+0

Мой проект не связывает свою банку внутри моей банки. Он объединяет скомпилированные классы в моем банке в иерархии папок классов, а также скомпилированные классы для моего кода. – James

ответ

11

Используйте maven-shade plugin таким образом, что JAR содержит зависимостей в убер-банке.

Итак, добавьте в ваш 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> 

Источник: http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html

Потенциально вы можете иметь эту проблему https://github.com/aws/aws-lambda-java-libs/issues/2, которая требует перехода на использование AWS-лямбда-Java-событий -1.0.0.jar

+2

К сожалению, это не сработало для меня ... по-прежнему получалось то же исключение. – Brooks

+1

Ах, только что посмотрел ваш pom.xml. Попробуйте использовать плагин maven-shade, как описано здесь: http://docs.aws.amazon.com/lambda/latest/dg/java-create-jar-pkg-maven-no-ide.html – Mike76

+0

Работал! Я соглашусь, но вы должны поместить URL-адрес в свой ответ, чтобы его можно было поддержать. – Brooks

0

В разделе плагинов вашего pom.xml добавьте Apache Maven Shade Plugin. Он используется во время buil d процесс. Этот плагин используется для упаковки баннеров для создания автономного .jar. Плагин maven-shade будет принимать артефакты (банки), созданные по цели пакета, и создал автономный .jar, содержащий скомпилированный код, и разрешенные зависимости от pom.xml.

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

1

Иногда вы должны загрузить лямбда снова. Также я получил ту же проблему, которую я исправил с помощью этого 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

Не забудьте указать свои собственные зависимости aws! –

+0

Ха, «просто загружая банку снова», сработало для меня. Возможно, я случайно случайно загрузил «оригинал ... банку». –