eduardohl eduardohl - 3 months ago 14
Scala Question

How to deploy a Scala application with filenames larger than 242 characters in CloudFoundry garden container

I've been trying to deploy a scala application built into a fat-jar with sbt assembly.

There is well known issue with containers and scala compilation generated class names: https://github.com/milessabin/shapeless/wiki/Shapeless-with-SBT-Assembly-inside-Docker, essentially they don't support file names larger than ~242 chars and will fail miserably to start scala application if they do contain those. Problem is several libraries (scalaz, play) contain those.

scalacOptions in assembly ++= Seq("-Xmax-classfile-name", "73")


Also tried replacing the command used to start and right now I'm looking into using alternative buildpacks, but none of these seem to be able to fix the issue, given that I don't even get to the start command.

My current results are:

➜ 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


As cf logs doesn't really return me anything, I have to log into PCFDev and get logs by tailing /var/vcap/data/sys/log/garden/garden.stdout.log:

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

Answer

Just in case this might still help anyone, we've managed to use a solution with sbt-native-packager instead of sbt-assembly.

Using sbt-native-packager and the universal:packageBin command a zip can be produced, containing the same contents produced by sbt stage. The jars are kept separate (not-exploded) and avoid the compilation problem generated by the size of files caused by sbt-assembly. After that the java_buildpack is capable of running the app without issues:

cf push sample-app -p ./target/universal/stage -b java_buildpack --health-check-type=none

or

cf push sample-app -p ./target/universal/sample-app-201608160251.zip -b java_buildpack --health-check-type=none
Comments