我一直在尝试将scala应用程序部署到一个带有sbt程序集的胖jar中。
容器和scala编译生成的类名存在着众所周知的问题:https://github.com/milessabin/shapeless/wiki/Shapeless-with-SBT-Assembly-inside-Docker,本质上它们不支持大于~242个字符的文件名,如果它们包含这些文件名,那么启动scala应用程序将不幸失败。问题是有几个库(scalaz,play)包含这些库。
scalacOptions in assembly ++= Seq("-Xmax-classfile-name", "73")此外,我还尝试替换了以前用于启动的命令,现在我正在研究使用替代构建包,但考虑到我甚至没有进入start命令,这些命令似乎都无法解决问题。
我目前的结果是:
➜ sample-generator git:(master) ✗ cf push sample-gen -p ./target/sample-generator-assembly-201608111441.jar -b java_buildpack --health-check-type=none -c "sleep(100)"
Creating app sample-gen in org pcfdev-org / space pcfdev-space as user...
OK
Using route sample-gen.local.pcfdev.io
Binding sample-gen.local.pcfdev.io to sample-gen...
OK
Uploading sample-gen...
Uploading app files from: /tmp/unzipped-app826671513
Uploading 120.3M, 38143 files
Done uploading
OK
Starting app sample-gen in org pcfdev-org / space pcfdev-space as user...
Downloading java_buildpack...
Downloaded java_buildpack
Creating container
Successfully created container
Downloading app package...
FAILED
Error restarting application: StagingError
TIP: use 'cf logs sample-gen --recent' for more information由于cf日志实际上没有返回任何内容,所以我必须登录到/var/vcap/data/sys/log/garden/garden.stdout.log:并通过跟踪PCFDev获取日志。
/*
* 提示:该行代码过长,系统自动注释不进行高亮。一键复制会移除系统注释
* {"timestamp":"1470918381.941401958","source":"garden-linux","message":"garden-linux.garden-server.stream-in.failed","log_level":2,"data":{"destination":"/tmp/app","error":"error streaming in: exit status 2. Output: tar: play/core/routing/GeneratedRouter$$anonfun$call$56$$anonfun$apply$178$$anonfun$$$$$85f6e7f12408688f578bcac985aee12$$$$$186$$anonfun$apply$187$$anonfun$apply$188$$anonfun$apply$189$$anonfun$apply$190$$anonfun$apply$191$$anonfun$apply$192$$anonfun$apply$193.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$59$$anonfun$apply$197$$anonfun$apply$198$$anonfun$apply$199$$anonfun$apply$200$$anonfun$apply$201$$anonfun$apply$202$$anonfun$apply$203$$anonfun$apply$204$$anonfun$apply$205$$anonfun$apply$206$$anonfun$apply$207.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$47$$anonfun$apply$127$$anonfun$apply$128$$anonfun$apply$129$$anonfun$apply$130$$anonfun$apply$131$$anonfun$apply$132$$anonfun$apply$133$$anonfun$apply$134$$anonfun$apply$135$$anonfun$apply$136$$anonfun$apply$137.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$44$$anonfun$apply$112$$anonfun$apply$113$$anonfun$apply$114$$anonfun$apply$115$$anonfun$apply$116$$anonfun$apply$117$$anonfun$apply$118$$anonfun$apply$119$$anonfun$apply$120$$anonfun$apply$121$$anonfun$apply$122.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$56$$anonfun$apply$178$$anonfun$apply$179$$anonfun$apply$180$$anonfun$apply$181$$anonfun$apply$182$$anonfun$apply$183$$anonfun$apply$184$$anonfun$apply$185$$anonfun$apply$186$$anonfun$apply$187$$anonfun$apply$188.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$59$$anonfun$apply$197$$anonfun$$$$$4d23ff5fc3821e643c952318248bfc6$$$$$205$$anonfun$apply$206$$anonfun$apply$207$$anonfun$apply$208$$anonfun$apply$209$$anonfun$apply$210$$anonfun$apply$211$$anonfun$apply$212.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$53$$anonfun$apply$160$$anonfun$apply$161$$anonfun$apply$162$$anonfun$apply$163$$anonfun$apply$164$$anonfun$apply$165$$anonfun$apply$166$$anonfun$apply$167$$anonfun$apply$168$$anonfun$apply$169$$anonfun$apply$170.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$41$$anonfun$apply$98$$anonfun$apply$99$$anonfun$apply$100$$anonfun$apply$101$$anonfun$apply$102$$anonfun$apply$103$$anonfun$apply$104$$anonfun$apply$105$$anonfun$apply$106$$anonfun$apply$107$$anonfun$apply$108.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$47$$anonfun$apply$127$$anonfun$$$$$a8626ce150a144689738daf9754d5e7$$$$$135$$anonfun$apply$136$$anonfun$apply$137$$anonfun$apply$138$$anonfun$apply$139$$anonfun$apply$140$$anonfun$apply$141$$anonfun$apply$142.class: Cannot open: File name too long\ntar: play/core/routing/GeneratedRouter$$anonfun$call$50$$anonfun$apply$143$$anonfun$apply$144$$anonfun$apply$145$$anonfun$apply$146$$anonfun$apply$147$$anonfun$apply$148$$anonfun$apply$149$$anonfun$apply$150$$anonfun$apply$151$$anonfun$apply$152$$anonfun$apply$153.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$70.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$tupled$11.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$67.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$66.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$73.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$68.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$76.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$71.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$74.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$75.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$72.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$77.class: Cannot open: File name too long\ntar: scalaz/syntax/ApplicativeBuilder$ApplicativeBuilder3$ApplicativeBuilder4$ApplicativeBuilder5$ApplicativeBuilder6$ApplicativeBuilder7$ApplicativeBuilder8$ApplicativeBuilder9$ApplicativeBuilder10$ApplicativeBuilder11$ApplicativeBuilder12$$anonfun$apply$69.class: Cannot open: File name too long\ntar: Exiting with failure status due to previous errors\n","handle":"a1ef2606-ead0-4cb1-b0fd-d464d64b8bc6-ff54adf06a8342f59eedfb022a9e9527","session":"11.7615","user":"vcap"}}
*/发布于 2016-08-16 12:41:24
为了防止这对任何人都有帮助,我们已经成功地使用了sbt本机包程序而不是sbt程序集的解决方案。
使用sbt本机打包程序和通用的:packageBin命令,可以生成一个zip,其中包含由sbt阶段生成的相同内容。jars是分开的(没有爆炸),避免了由sbt程序集引起的文件大小所产生的编译问题。在此之后,java_buildpack能够运行该应用程序,而不会出现以下问题:
cf push sample-app -p ./target/universal/stage -b java_buildpack --health-check-type=none或
cf push sample-app -p ./target/universal/sample-app-201608160251.zip -b java_buildpack --health-check-type=none发布于 2016-08-12 13:47:22
对于Java/Scala用户来说,在应用程序暂存过程中仍在与长嵌套文件名中断斗争或挣扎,有一种更简单的解决方案,不需要自定义构建包。
使用Java类路径清单指定绑定在其他jar中的其他类,然后推送主应用程序,而不是将所有内容打包为一个大jar文件。最后的结构应该是一个顶级Jar文件,包含多个内部Jar,所有这些都由主类路径清单条目引用。
1)将带有第三方库或依赖项的应用程序比特创建为其他文件夹中的单独jars (如lib/..)
样本结构:
com.mycompany.foo.class
com.mycompany.bar.class
com.mycompany.xyz.class
lib/myDepedencyA.jar
lib/myDepedencyB.jar
lib/myDepedencyC.jar
.....
lib/myDepedencyZ.jar2)创建一个类路径清单条目,该条目引用自定义清单(例如我的清单)中的这些附加jars。
Manifest-Version: 1.0
Implementation-Vendor: test
Implementation-Title: Test
Implementation-Version: 1.0
Implementation-Vendor-Id: test
Specification-Vendor: test
Specification-Title: TestApp
Specification-Version: 1.0
Main-Class: TestService
Class-Path: lib/akka-actor_2.10-2.1.4.jar
lib/casbah-commons_2.10-2.7.1.jar
lib/casbah-core_2.10-2.7.1.jar
lib/casbah-gridfs_2.10-2.7.0.jar
lib/casbah-query_2.10-2.7.1.jar
lib/config-1.0.0.jar
lib/joda-convert-1.2.jar
lib/joda-time-2.3.jar
lib/json4s-ast_2.10-3.2.9.jar
lib/json4s-core_2.10-3.2.9.jar
lib/myDepedencyA.jar
lib/myDepedencyB.jar
lib/myDepedencyC.jar
.....
lib/myDepedencyZ.jar3)在显式指定清单文件的同时创建最终jar。
jar cvfm MyApp.jar mymanifest -C foo/ .说明:在其中包含类之前,使用清单并转到foo目录。另外,参考https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html,jar会让appln类和第三方库都捆绑在一起,但是没有每个有问题的长类名。在推送之前,请检查清单内容以确保。
4)当应用程序推送发生时,只会打开顶级的app类,而不会从lib文件夹中打开第三方jars。java将在运行时自动将类路径清单中指定的jars添加到服务器类路径中。
$PWD/.:$PWD/lib/akka-actor_2.10-2.1.4.jar:$PWD/lib/casbah-commons_2.10-2.7.1.jar:$PWD/lib/casbah-core_2.10-2.7.1.jar:$PWD/lib/casbah-gridfs_2.10-2.7.0.jar:$PWD/lib/casbah-query_2.10-2.:$PWD/.java/open_jre/bin/java -cp start_command7.1.jar:$PWD/lib/config-1.0.0.jar:$PWD/lib/joda-convert-1.2.jar:$PWD/lib/joda-time-2.3.jar:$PWD/lib/json4s-ast_2.10-3.2.9.jar:$PWD/lib/json4s-core_2.10-3.2.9.jar:$PWD/lib/json4s-native_2.10-3.2.9.jar:$PWD/lib/mimepull-1.9.4.jar:$PWD/lib/mongo-java-driver-2.12.1.jar:$PWD/lib/nscala-time_2.10-1.0.0.jar:$PWD/lib/paranamer-2.6.jar:$PWD/lib/parboiled-core-1.1.6.jar:$PWD/lib/parboiled-scala_2.10-1.1.6.jar:$PWD/lib/salat-core_2.10-1.9.8.jar:$PWD/lib/salat-util_2.10-1.9.8.jar:$PWD/lib/sbinary_2.10-0.4.2.jar:$PWD/lib/sbt-0.13.1.jar:$PWD/lib/sbt-assembly-0.11.2.jar:$PWD/lib/sbt-idea-1.6.0.jar:$PWD/lib/scala-compiler-2.10.4.jar:$PWD/lib/scala-library-2.10.4.jar:$PWD/lib/scala-reflect-2.10.4.jar:$PWD/lib/scalap-2.10.4.jar:$PWD/lib/shapeless_2.10-1.2.4.jar:$PWD/lib/slf4j-api-1.7.2.jar:$PWD/lib/spray-can-1.1.1.jar:$PWD/lib/spray-http-1.1.1.jar:$PWD/lib/spray-httpx-1.1.1.jar:$PWD/lib/spray-io-1.1.1.jar:$PWD/lib/spray-json_2.10-1.2.5.jar:$PWD/lib/spray-routing-1.1.1.jar:$PWD/lib/spray-util-1.1.1.jar:$PWD/lib/task-system-0.13.1.jar:$PWD/lib/tasks-0.13.1.jar:$PWD/lib/test-agent-0.13.1.jar:$PWD/lib/test-interface-1.0.jar:$PWD/lib/testing-0.13.1.jar:$PWD/lib/tracking-0.13.1.jar -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh -Djava.io.tmpdir=$TMPDIR -Xmx1536M -Xms1536M -XX:MaxPermSize=209715K -XX:PermSize=209715K -Xss1M TestService
https://stackoverflow.com/questions/38899894
复制相似问题