Help us understand the problem. What is going on with this article?

AWS LambdaではMANIFEST.MFの内容が捨てられる

More than 3 years have passed since last update.

TL;DR

AWS LambdaでJavaを実行する場合 jarファイルをlambda環境にアップロードするが、そのjarファイルの MANIFEST.MF に情報を入れていたとしても実行時に消されてしまう。おそらくLambda環境内でjarファイルが生成し直され、そのときに捨てられると推測される。

MANIFEST.MFに例えば jarファイルのバージョン番号を保存する設計だと Lambdaでは取得できない。別の場所に保存する必要がある。(プロパティファイルなど)

検証

サンプルソース

Main.java
package testmanifest;

import com.amazonaws.services.lambda.runtime.Context;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
  /** 自パッケージと、MANIFEST.MFの内容を収集して返す。*/
  static String getManifestInfo() throws IOException {
    StringBuilder sb = new StringBuilder();
    Package thisPack = Package.getPackage("testmanifest");
    sb.append(String.format("ImplementationVersion -> %s%n", thisPack.getImplementationVersion()));
    sb.append(String.format("ImplementationTitle   -> %s%n", thisPack.getImplementationTitle()));
    sb.append("-------------\n");
    try (BufferedReader buffer = new BufferedReader(
        new InputStreamReader(
            Main.class.getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"),
            StandardCharsets.UTF_8))) {
      sb.append(buffer.lines().collect(Collectors.joining("\n")));
    }
    return sb.toString();
  }

  public static void main(String[] args) throws Exception {
    System.out.println(getManifestInfo());
  }

  /** ハンドラ名  testmanifest.Main::awsStart */
  public void awsStart(Map<?, ?> name, Context context) throws IOException {
    context.getLogger().log(getManifestInfo());
  }
}
build.gradle
apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'

version = '1.2.3'

sourceCompatibility = '1.8'
targetCompatibility = '1.8'

def defaultEncoding = 'UTF-8'

tasks.withType(AbstractCompile) each { it.options.encoding = defaultEncoding }

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
  }
}
repositories {
  jcenter()
}

dependencies {
  compile 'com.amazonaws:aws-lambda-java-core:1.1.0'
}

jar {
  manifest {
    attributes(
      "Implementation-Title": "testmanifest",
      "Implementation-Version": "1.2.3",
      "Implementation-Vendor": "nantoka vender",
      "hoge": "fuga"
    )
  }
}

ビルド

>gradlew.bat shadowJar
:compileJava
:processResources UP-TO-DATE
:classes
:shadowJar

BUILD SUCCESSFUL

Total time: 3.26 secs
>dir /b build\libs
testManifest-1.2.3-all.jar

>

コネタ:com.github.johnrengelman.shadowにて、いわゆるUber JARを作ることができる。

コンソール実行

>java -cp build\libs\testManifest-1.2.3-all.jar testmanifest.Main
ImplementationVersion -> 1.2.3
ImplementationTitle   -> testmanifest
-------------
Manifest-Version: 1.0
Implementation-Title: testmanifest
Implementation-Version: 1.2.3
hoge: fuga
Implementation-Vendor: nantoka vender


>

Lambdaでの実行

CloudWatchにて出力を確認した。

lambda.png

ImplementationVersion などgradleで設定した値が消えていて、Ant-Versionや、Main-Class: が設定されている。

まとめ

MANIFEST.MFに情報をもたせられないので、別の場所に情報を保持させましょう。

kazurof
がんばりましょう。
http://kazurof.hateblo.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away