2

最近、AWS Lambda with Java をいじり始めました。

ダガー2を注射に使い始めるまでは順調でした。

現在、Lambda は次のエラーをスローします。

{
  "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 を使用してビルドします。

私がチェックした他の質問は、依存関係が利用できないことが原因である可能性があることを示唆していますが、クラスの内容には依存関係がありません。

Dagger リポジトリから取得:

/*
 * 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: 最小限の BUILD ファイルは次のとおりです。

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 があります (注: Preconditions を直接使用して最小限の実装にしています。実際のコードでは、コンポーネントをビルドしようとすると失敗します)。

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 Lambda 関数にアップロードすると、失敗するはずです。ローカルで実行するbazel run //src/main/com/company:binか、正常に動作する場合java -jar bazel-bin/src/main/com/company/bin_deploy.jar

4

1 に答える 1

0

それはすべて、私のjarファイル内のdaggerフォルダーの許可によるものでした. 他のすべてのフォルダ (com、org、mozilla など) には 755 がありましたが、dagger フォルダにはありませんでした。jar を解凍し、2 つのコマンドを実行して、ディレクトリを 755 に、ファイルを 644 に変換してから、圧縮して元に戻しました。

権限を変更するためのコマンド:

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

Bazel がビルドしているときに、なぜ他のディレクトリと異なるのかわかりません。しかし、それが問題です。


将来の Bazel 検索者のために、ここに私が現在使用している genrule を示します。

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 ../$@ -q -r .
  rm -rf t
  """
)
于 2016-07-04T08:59:58.317 に答える