0

J'ai créé un fichier jar, ajouté une classe principale et l'ai exécuté à l'aide de java -jar. Cette exécute normalement, mais quand je le télécharger à AWS Lambda, je reçois le texte suivant:Lorsque vous utilisez les bibliothèques de recherche personnalisées de Google avec AWS Lambda, une erreur NoClassDef ne se reproduit pas localement

{ 
"errorMessage": "Error loading class com.me.MyHandler:com/google/api/client/googleapis/json/GoogleJsonResponseException", 
"errorType": "class java.lang.NoClassDefFoundError" 
} 

est ici la sortie du journal:

Error loading class com.me.MyHandler: com/google/api/client/googleapis/json/GoogleJsonResponseException: class java.lang.NoClassDefFoundError 
java.lang.NoClassDefFoundError: com/google/api/client/googleapis/json/GoogleJsonResponseException 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:348) 
Caused by: java.lang.ClassNotFoundException: com.google.api.client.googleapis.json.GoogleJsonResponseException 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    ... 2 more 

Je dézippé le pot et trouvé GoogleJsonResponseException.class. Quelque chose de bizarre dans l'environnement d'exécution d'AWS? Même si je n'utilise pas l'exception de Google, il semble que je reçois des erreurs avec tous les cours Google.

Voici le fichier build.gradle

group 'com.me' 
version '1.0.1' 

apply plugin: 'java' 
apply plugin: 'application' 

sourceCompatibility = 1.8 

repositories { 
    mavenCentral() 
} 

dependencies { 
    compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.1.0' 
    compile group: 'com.amazonaws', name: 'aws-lambda-java-log4j', version: '1.0.0' 
    compile group: 'com.google.api-client', name: 'google-api-client', version: '1.22.0' 
    compile group: 'log4j', name: 'log4j', version: '1.2.17' 
    compile group: 'com.google.apis', name: 'google-api-services-customsearch', version: 'v1-rev54-1.22.0' 
    compile group: 'com.google.http-client', name: 'google-http-client-gson', version: '1.22.0' 
    compile group: 'com.google.http-client', name: 'google-http-client', version: '1.22.0' 
    compile group: 'com.google.api-client', name: 'google-api-client', version: '1.22.0' 
    compile group: 'commons-io', name: 'commons-io', version: '2.5' 
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.0.1' 
    testCompile group: 'junit', name: 'junit', version: '4.12' 
    testCompile group: 'org.assertj', name: 'assertj-core', version: '3.6.2' 
    runtime 'com.google.api-client:google-api-client:1.22.0' 
} 

mainClassName = "com.me.Main" 

jar { 
    from { 
     configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } 
    } 
    manifest { 
     attributes 'Main-Class': mainClassName 
    } 
} 

Voici la principale méthode:

public class Main { 
    public static void main(String[] args) { 
     System.out.println("starting main"); 
     MyHandler myHandler = new MyHandler(); 
     myHandler.handleRequest(null, null); 
    } 
} 

Voici le code appelant lib de Google:

public class MyHandler implements 
     RequestHandler<Map, String> { 

    static final Logger log = Logger.getLogger(MyHandler.class); 

    @Override 
    public String handleRequest(Map input, Context context) { 
     log.info("Handling request."); 

     try { 
     log.info("Initializing custom search"); 

     Customsearch.Builder builder = new Customsearch.Builder(
       GoogleNetHttpTransport.newTrustedTransport(), 
       new GsonFactory(), 
       null); 
     builder.setGoogleClientRequestInitializer(new CustomsearchRequestInitializer("test")); 
     builder.setApplicationName("testQuery"); 
     Customsearch customsearch = builder.build(); 
     Customsearch.Cse.List list = customsearch.cse().list("test"); 
      list.setKey("test"); 
      list.setCx("test"); 

      Search results; 
      try { 
       results = list.execute(); 
      } catch (GoogleJsonResponseException gjre) { 
       log.error(gjre.getMessage()); 
       throw gjre; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (GeneralSecurityException gse) { 
      gse.printStackTrace(); 
     } 

     return "test"; 
    } 
} 
+0

Ajoutez également vos dépendances au pot. – johni

+0

Il est emballé ici: configurations.compile.collect {it.isDirectory()? c'est: zipTree (it)}. L'utilisation de java -jar pour exécuter le code n'a pas posé de problème. En outre, j'ai décompressé le fichier jar et trouvé le fichier de classe incriminé. – caligarisdesk

Répondre

0

Je coupe un ticket de support pour AWS et a trouvé un moyen de contourner le problème. On dirait que le gros bocal n'a pas tout emballé. , Ils ont suggéré au lieu de télécharger un zip de construction (ajouter à la fin du fichier gradle):

task buildZip(type: Zip) { 
    from compileJava 
    from processResources    
    into('lib') { 
     from configurations.runtime 
    }   
} 

J'ai ajouté que téléversé le zip au lieu du pot. Travaillé très bien.