2016-07-01 11 views
1

最近、AWSラムダをJavaで使い始めました。AWSラムダとJavaのスローNoClassDefFoundError by ClassNotFoundExceptionローカルスローされていない

私はDagger 2を注射用に使用するまでうまくいっています。

今、ラムダは、次のエラーがスローされます。

{ 
    "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() {} 
} 

自己完結型のjarファイルを実行しているときに、私のローカル環境では発生しませんAWS上の問題を引き起こしている可能性がありますか?事前に

おかげ

編集1: ここでは最小限のビルドファイルされる:

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(ノート、あります前提条件を直接使用して最小限の実装にします。実際のコードでは、コンポーネントを作成しようとすると失敗します。

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ラムダ関数にアップロードすると失敗します。ローカルでbazel run //src/main/com/company:binまたはjava -jar bazel-bin/src/main/com/company/bin_deploy.jarを実行すると正常に動作します。

+0

を)依存関係は見えますか?彼らは正しい場所にいますか?それらが瓶の中になければならない場合は、それらを正しい場所にサーバーに配備していますか? –

+0

はい、すべてのクラスがそこにあります(Preconditionsクラスを含む)。彼らは正しい場所にいます。 AWS Lambdaが入っているのはサーバーの点です。すべての依存関係(すべての依存関係を含む)をAWS Lambdaにアップロードし、そこから取得します。そのことと何かが問題を引き起こしているようです。 – Zenton

+0

ビルドの依存関係が誤って宣言されている可能性があります。あなたのビルドファイルはどうなっていますか? –

答えて

0

私のjarファイル内のdaggerフォルダのパーミッションが原因でした。他のすべてのフォルダ(例:com、org、mozilla)には755がありましたが、ダガーフォルダはありませんでした。私は私の瓶を解凍し、ディレクトリを755に変換する2つのコマンドを実行し、ファイルを644に変換して、それをバックアップしました。アクセス権を変更するための

コマンド:

From inside the unzipped directory: 
find . -type f -exec chmod 644 {} + 
find . -type d -exec chmod 755 {} + 

Bazelがそれを構築しているとき、それは他のディレクトリに異なっている理由を私は知りません。しかし、それは問題です。将来Bazelサーチャーのために


、ここで私が今使っているgenruleです:あなたは(WinZipの、たとえば、中にjarファイルを開くまたはLinux上unzip` `でその内容を一覧表示した場合

genrule(
    name = "target-aws", 
    srcs = ["target_deploy.jar"], 
    outs = ["target-aws.jar"], 
    cmd = """ 
    unzip -q $< -d t 
    cd t 
    find . -type f -exec chmod 644 {} + 
    find . -type d -exec chmod 755 {} + 
    zip ../[email protected] -q -r . 
    rm -rf t 
    """ 
) 
+0

面白い、知っておいてよかった! – blueskin

関連する問題