2016-04-25 34 views
5

cerco di costruire vaso dal progetto pulire con sbt-assembly come descrive in docs:Come costruire barattolo da quadro gioco 2.5.x

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2") 

import AssemblyKeys._ 

assemblySettings 

mainClass in assembly := Some("play.core.server.ProdServerStart") 

fullClasspath in assembly += Attributed.blank(PlayKeys.playPackageAssets.value) 

ma mi dà un sacco di errori deduplicare. Come costruire un vaso "grasso" dal gioco con sbt-assembly?

+0

Sei sicuro che il vaso sia la scelta migliore. I pacchetti di installazione di Sbt-native packager sono quasi pronte per l'installazione – mgosk

+0

@zella, incollare parte del log degli errori. – Nio

risposta

9

Ci sono diversi bit che devono essere impostati per costruire un'applicazione di gioco come un barattolo di grasso.

A partire dal plugin asssembly. Deve esserci un file denominato assembly.sbt situato direttamente nella directory del progetto. Per essere precisi ed eliminare la confusione se il progetto è denominato MyPlayProject il file deve trovarsi in "MyPlayProject/project/assembly.sbt" e dovrebbe contenere solo quanto segue.

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3" 

Ovviamente la versione è soggetta a modifiche ma dovrebbe funzionare. Questo aggiungerà il plugin assembly al tuo progetto e non funzionerà se aggiunto al file plugins.sbt come altri plugin.

Per coprire tutte le basi, accertarsi inoltre di includere gli articoli standard SBT inclusi project/build.properties. Si noti che per la versione 2.5.x SBT Gioca 13.8 o superiore è necessario per https://www.playframework.com/documentation/2.5.x/Migration25#sbt-upgrade-to-0.13.11

sbt.version=0.13.11 

E la parte critica probabilmente causando i problemi è una parte del file build.sbt che dovrebbe includere la strategia di unione. Esistono numerosi file standard nei file jar (ad esempio MANIFEST.MF ecc.) E devi fare qualcosa per gestire questi file duplicati quando unisci tutti i barattoli in un singolo contenitore di grassi. Esempio di base

assemblyMergeStrategy in assembly := { 
    case r if r.startsWith("reference.conf") => MergeStrategy.concat 
    case PathList("META-INF", m) if m.equalsIgnoreCase("MANIFEST.MF") => MergeStrategy.discard 
    case x => MergeStrategy.first 
} 

vostra situazione potrebbe essere molto con i casi specifici da trattare, ma questo è abbastanza di base per uno standard un barattolo di grasso gioco.

alcuni dettagli di base sulla strategia di fusione di cui sopra come segue:

  • Unisci reference.conf tutto del vaso per singolo file per jar grasso. Ho dimenticato il problema specifico che ha portato a questo, ma non penso che sarete in grado di eseguire la vostra applicazione di gioco come jar grasso senza questo passaggio. Non ho alcuna prova di ciò)
  • Scarta i file MANIFEST.MF per ciascun jar. Molti esempi online mostrano questo come 'caso PathList ("META-INF", xs @ _ *) => MergeStrategy.discard'. Questo funziona rimuovendo qualsiasi cosa nella directory META-INF del jar. Comunque l'avvio dell'inietto di dipendenza di Play 2.4 è stato spinto piuttosto duramente con il gioco e se si utilizza l'integrazione delle dipendenze esiste una dipendenza della libreria su net.sf.ehcache che include i file di servizio richiesti per utilizzare l'iniezione delle dipendenze. La correzione è di lasciare tutti gli altri file e semplicemente scartare i file MANIFEST.MF in modo specifico come ho fatto o semplicemente rimuovere tutto e non utilizzare nulla di dipendenza (non consigliato)
  • Un caso generale che trattiene il primo di qualsiasi file duplicato e scarta gli altri. Utile quando si possono avere più dipendenze comuni sulla stessa libreria e non c'è motivo di conservare più copie.

Poiché non è possibile chiarire con i commenti qui è un file di esempio build.sbt completo.

name := """MyPlayProject""" 

version := "1.0" 

lazy val `root` = (project in file(".")).enablePlugins(PlayScala) 

scalaVersion := "2.11.8" 

// Set JS Engine to use 
JsEngineKeys.engineType := JsEngineKeys.EngineType.Node 

// Set repository details for resolving additional depenecies 
resolvers ++= Seq(
    "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases", 
    "ClouderaRepo" at "https://repository.cloudera.com/content/repositories/releases" 
) 

// Specifies dependencies to use in project 
libraryDependencies ++= Seq(
    "org.apache.kafka" % "kafka_2.11" % "0.9.0.1", 
    jdbc, 
    cache, 
    ws, 
    specs2 % Test 
) 

// Add an additional source content route besides the default 
unmanagedResourceDirectories in Test <+= baseDirectory (_ /"target/web/public/test") 

unmanagedSourceDirectories in Compile += baseDirectory.value/"src2"/"main"/"scala" 

sourceDirectory in Compile <<= baseDirectory/"src2/main/scala" 

scalaSource in Compile <<= baseDirectory/"src2/main/scala" 

// Informs SBT Assembly how to handle duplicated files when combining project and dependency jars into a single fat jar 
assemblyMergeStrategy in assembly := { 
    case n if n.startsWith("reference.conf") => MergeStrategy.concat 
    case PathList("META-INF", xs @ _*) => MergeStrategy.discard 
    case x => MergeStrategy.first 
} 

avrei lasciato commenti per ulteriori dettagli prima di rispondere in modo avrei potuto essere più preciso con la mia risposta, ma la questione è un po 'vecchio e che detta il mio rappresentante non è abbastanza alta in ogni modo ... Spero che questo aiuti .

P.S. Ho trovato la tua domanda mentre cercavo aiuto con i miei problemi di fusione migrando la riproduzione dalla 2.3.4 alla 2.5.4. Questo è il motivo per cui ho modificato la strategia di unione META-INF per scartare solo MANIFEST.MF, altrimenti causerebbe l'eccezione sottostante. Lo sto ripubblicando con la mia risposta nella speranza che possa essere rilevato nei risultati di ricerca poiché ho trovato pochissimi inizialmente quando lo stavo cercando.

Oops, cannot start the server. 
com.google.inject.CreationException: Unable to create injector, see the following errors: 

1) Error in custom provider, net.sf.ehcache.CacheException: java.lang.AssertionError: No net.sf.ehcache.EhcacheInit services found 
    while locating play.api.cache.CacheManagerProvider 
    while locating net.sf.ehcache.CacheManager 
    for field at play.api.cache.NamedEhCacheProvider.manager(Cache.scala:211) 
    while locating play.api.cache.NamedEhCacheProvider 
    at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149) 
    at play.api.cache.EhCacheModule.play$api$cache$EhCacheModule$$bindCache$1(Cache.scala:184): 
Binding(interface net.sf.ehcache.Ehcache qualified with QualifierInstance(@play.cache.NamedCache(value=play)) to ProviderTarget([email protected])) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1) 

1 error 
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) 
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:176) 
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) 
    at com.google.inject.Guice.createInjector(Guice.java:96) 
    at com.google.inject.Guice.createInjector(Guice.java:84) 
    at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181) 
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123) 
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) 
    at play.core.server.ProdServerStart$.start(ProdServerStart.scala:47) 
    at play.core.server.ProdServerStart$.main(ProdServerStart.scala:22) 
    at play.core.server.ProdServerStart.main(ProdServerStart.scala) 
Caused by: net.sf.ehcache.CacheException: java.lang.AssertionError: No net.sf.ehcache.EhcacheInit services found 
    at net.sf.ehcache.LibraryInit.init(LibraryInit.java:55) 
    at net.sf.ehcache.CacheManager.init(CacheManager.java:366) 
    at net.sf.ehcache.CacheManager.<init>(CacheManager.java:259) 
    at net.sf.ehcache.CacheManager.newInstance(CacheManager.java:1037) 
    at net.sf.ehcache.CacheManager.newInstance(CacheManager.java:936) 
    at net.sf.ehcache.CacheManager.create(CacheManager.java:904) 
    at play.api.cache.CacheManagerProvider.get$lzycompute(Cache.scala:205) 
    at play.api.cache.CacheManagerProvider.get(Cache.scala:202) 
    at play.api.cache.CacheManagerProvider.get(Cache.scala:201) 
    at com.google.inject.internal.ProviderInternalFactory.provision(ProviderInternalFactory.java:81) 
    at com.google.inject.internal.BoundProviderFactory.provision(BoundProviderFactory.java:72) 
    at com.google.inject.internal.ProviderInternalFactory.circularGet(ProviderInternalFactory.java:61) 
    at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:62) 
    at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:54) 
    at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:132) 
    at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:93) 
    at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:80) 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) 
    at com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:80) 
    at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:62) 
    at com.google.inject.internal.InjectorImpl.injectMembers(InjectorImpl.java:984) 
    at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149) 
    at com.google.inject.util.Providers$GuicifiedProviderWithDependencies$$FastClassByGuice$$2a7177aa.invoke(<generated>) 
    at com.google.inject.internal.cglib.reflect.$FastMethod.invoke(FastMethod.java:53) 
    at com.google.inject.internal.SingleMethodInjector$1.invoke(SingleMethodInjector.java:57) 
    at com.google.inject.internal.SingleMethodInjector.inject(SingleMethodInjector.java:91) 
    at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:132) 
    at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:93) 
    at com.google.inject.internal.MembersInjectorImpl$1.call(MembersInjectorImpl.java:80) 
    at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) 
    at com.google.inject.internal.MembersInjectorImpl.injectAndNotify(MembersInjectorImpl.java:80) 
    at com.google.inject.internal.Initializer$InjectableReference.get(Initializer.java:174) 
    at com.google.inject.internal.Initializer.injectAll(Initializer.java:108) 
    at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:174) 
    ... 9 more 
Caused by: java.lang.AssertionError: No net.sf.ehcache.EhcacheInit services found 
    at net.sf.ehcache.LibraryInit.initService(LibraryInit.java:78) 
    at net.sf.ehcache.LibraryInit.init(LibraryInit.java:50) 
    ... 42 more 
+0

un anno dopo, grazie !! Ho trovato il tuo testo modificato per PS. Ho fatto ciò che mi hai suggerito, ma poi ho ricevuto un errore 'Invalid Signature' sul jar. Eppure, ho un indizio su dove guardare grazie a te. Errore che ottengo: 'org.apache.flink.client.program.ProgramInvocationException: la classe del punto di ingresso del programma 'net.tagtog.services.documents.flink.Job' ha provocato un'eccezione durante l'inizializzazione: digest del file di firma non valido per gli attributi principali di manifest ' – juanmirocks

+0

Trovato la soluzione! (che almeno ha funzionato per me). Questo: '' 'Case PathList (" META-INF "," services ", xs @ _ *) => MergeStrategy.concat case PathList (" META-INF ", xs @ _ *) => MergeStrategy.discard'' '- Hai bisogno di tutti i file dei servizi – juanmirocks