2017-02-25 17 views
3

私はsca aws lambda関数と共にproguardの使用に関する質問があります。私はこのような非常に単純なAWSのラムダ関数を作成しました:Proguard for Scalaを使用するAWS Lambda

package example 

import scala.collection.JavaConverters._ 
import com.amazonaws.services.lambda.runtime.events.S3Event 
import com.amazonaws.services.lambda.runtime.Context 

object Main extends App { 

def kinesisEventHandler(event: S3Event, context: Context): Unit = { 
val result = event.getRecords.asScala.map(m => m.getS3.getObject.getKey) 
println(result) 
} 

} 

私は以下のパッケージにインポートしている:

"com.amazonaws" % "aws-lambda-java-core" % "1.1.0" 
"com.amazonaws" % "aws-lambda-java-events" % "1.3.0" 

を私は脂肪のjarを作成する場合、それは、サイズが13メガバイトであり、以下のように予想されるように動作しますAWSラムダ関数(テスト出力のみ)。

13メガバイト非常に大きいので、私は、jarファイルを縮小するProGuardのを試してみましたが、それが動作していないと私はいつも問題を取得し、2日後、私はそれを解決する方法がないより多くのアイデアを持っています。ここで

は私のProGuardの設定です:

-injars "/Users/x/x/x/AWS_Lambda/target/scala-2.12/lambda-demo-assembly-1.0.jar" 
-libraryjars "/Users/x/x/x/AWS_Lambda/lib_managed/jars/org.scala-lang/scala-library/scala-library-2.12.1.jar" 
-libraryjars "/Users/x/x/x/AWS_Lambda/lib_managed/jars/com.amazonaws/aws-lambda-java-core/aws-lambda-java-core-1.1.0.jar" 
-libraryjars "/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/rt.jar" 
-libraryjars "/Users/x/x/x/AWS_Lambda/lib_managed/jars/com.amazonaws/aws-java-sdk-s3/aws-java-sdk-s3-1.11.0.jar" 
-libraryjars "/Users/x/x/x/AWS_Lambda/lib_managed/jars/com.amazonaws/aws-lambda-java-events/aws-lambda-java-events-1.3.0.jar" 
-outjars "/Users/x/x/x/AWS_Lambda/target/scala-2.12/proguard/lambda-demo_2.12-1.0.jar" 
-dontoptimize 
-dontobfuscate 
-dontnote 
-dontwarn 

-keepattributes SourceFile,LineNumberTable 

# Preserve all annotations. 

-keepattributes *Annotation* 

# Preserve all public applications. 

-keepclasseswithmembers public class * { 
    public static void main(java.lang.String[]); 
} 

# Preserve some classes and class members that are accessed by means of 
# introspection. 

-keep class * implements org.xml.sax.EntityResolver 

-keepclassmembers class * { 
    ** MODULE$; 
} 

-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool { 
    long eventCount; 
    int workerCounts; 
    int runControl; 
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack; 
    scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack; 
} 

-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread { 
    int base; 
    int sp; 
    int runState; 
} 

-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask { 
    int status; 
} 

-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue { 
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head; 
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail; 
    scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe; 
} 

# Preserve some classes and class members that are accessed by means of 
# introspection in the Scala compiler library, if it is processed as well. 

#-keep class * implements jline.Completor 
#-keep class * implements jline.Terminal 

#-keep class scala.tools.nsc.Global 

#-keepclasseswithmembers class * { 
# <init>(scala.tools.nsc.Global); 
#} 

#-keepclassmembers class * { 
# *** scala_repl_value(); 
# *** scala_repl_result(); 
#} 

# Preserve all native method names and the names of their classes. 

-keepclasseswithmembernames,includedescriptorclasses class * { 
    native <methods>; 
} 

# Preserve the special static methods that are required in all  enumeration 
# classes. 

-keepclassmembers,allowoptimization enum * { 
    public static **[] values(); 
    public static ** valueOf(java.lang.String); 
} 

# Explicitly preserve all serialization members. The Serializable interface 
# is only a marker interface, so it wouldn't save them. 
# You can comment this out if your application doesn't use serialization. 
# If your code contains serializable classes that have to be backward 
# compatible, please refer to the manual. 

-keepclassmembers class * implements java.io.Serializable { 
    static final long serialVersionUID; 
    static final java.io.ObjectStreamField[] serialPersistentFields; 
    private void writeObject(java.io.ObjectOutputStream); 
    private void readObject(java.io.ObjectInputStream); 
    java.lang.Object writeReplace(); 
    java.lang.Object readResolve(); 
} 

# Your application may contain more items that need to be preserved; 
# typically classes that are dynamically created using Class.forName: 

# -keep public class mypackage.MyClass 
# -keep public interface mypackage.MyInterface 
# -keep public class * implements mypackage.MyInterface 

-keep,includedescriptorclasses class example.** { *; } 

-keepclassmembers class * { 
    <init>(...); 
} 

私はこれを実行すると、私のjarファイルは、(5メガバイトの周りに)非常に小さいですが、私は、ラムダを起動したとき、私は次のようなエラー

"errorMessage": "java.lang.NoSuchMethodException: com.amazonaws.services.s3.event.S3EventNotification.parseJson(java.lang.String)", 
"errorType": "lambdainternal.util.ReflectUtil$ReflectException" 

を取得します私はクラスを見て、proguardはこの関数を削除しました。このファイルを保存するように設定を変更したとき、別のファイルに別の問題が発生しました。

誰かがすでにScalaのAWSのラムダ関数とProGuardのを使用し、優れた設定を持っているか、この問題について知っていますか? jarのサイズを縮小するための他の良い解決策はありますか?

ベスト、 Lothium

答えて

0

は正直なところ、13メガバイトは、大きくはありません。しかし、これがScala開発者と異論を唱えると確信している限り、私はJavaで同等のメソッドを作成しましたが、これは7MBを少し超えています。私はそれでProguardを使用しようとしなかった - それはさらに縮小する可能性があります。

使用しているようS3Eventパッケージにした

。そのパッケージのために何が含まれているかを見れば、SQS、SNS、Dynamoなどの余分なものがたくさんあります。最終的にはそれが最大の部分です。私はaws-lambda-java-coreを除くすべてのライブラリを削除しようとする少しのテストを行い、その代わりにJsonPathを使用しました。それは私の瓶ファイルを458 Kに持っています。

私のコードは以下の通りです。私はScalaではないことを知っていますが、おそらくあなたはそれからいくつかのアイデアを得ることができます。その鍵は、できるだけ多くのAWSライブラリを削除することでした。もちろん、Lambdaのキーを印刷する以外に何かをしたいのであれば、もっと多くのAWSライブラリを持ち込む必要があります。このライブラリは、約7MBのサイズになります。

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.util.List; 

import com.amazonaws.services.lambda.runtime.Context; 
import com.amazonaws.services.lambda.runtime.RequestStreamHandler; 
import com.jayway.jsonpath.JsonPath; 


public class S3EventLambdaHandler implements RequestStreamHandler { 
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) { 

     try { 
      List<String> keys = JsonPath.read(inputStream, "$.Records[*].s3.object.key"); 

      for(String nextKey: keys) 
       System.out.println(nextKey); 
     } 
     catch(IOException ioe) { 
      context.getLogger().log("caught IOException reading input stream"); 
     } 
    } 
} 
+0

ねえ、あなたの応答に感謝! 5MBのオーバヘッドは、スカラライブラリで説明することができます。私はawsからイベントパッケージから不必要なライブラリを除外し、サイズを7MBまで下げました。これが正しい方向への最初の方法です。ご協力いただきありがとうございます! – Lothium

関連する問題