2010-05-22 10 views
23

¿Hay alguna manera de decirle a sbt que empaque todas las bibliotecas necesarias (scala-library.jar) en el paquete principal, por lo que es independiente? (Estática?)Hacer jar individual con Simple Build Tool

+0

posible duplicado de [Cómo ejecutar un proyecto de aplicación gestionado por sbt sin sbt?] (Http://stackoverflow.com/questions/7195079/how-to-run-a-sbt-managed-application-project-without -sbt) –

+0

Duplicado de http://stackoverflow.com/q/7195079/1305344 y http://stackoverflow.com/q/7134993/1305344 –

+0

http://blog.prabeeshk.com/blog/2014/04/ 01/a-standalone-spark-application-in-scala/ –

Respuesta

14

Edición 2011:
Desde entonces, retronym (que registró un answer in this page back in 2010), hizo esta sbt-plugin "sbt-onejar", ahora en su new address on GitHub, con documentos actualizados para SBT 0,12.

Paquetes su proyecto usando One-JAR™

onejar-sbt es un plugin-build-herramienta sencilla para la construcción de un único ejecutable JAR que contiene todo el código y dependencias como frascos anidados.
Actualmente se utiliza One-JAR versión 0.9.7. Esto se incluye con el complemento y no es necesario descargarlo por separado.


respuesta Original:

Directamente, esto no es posible sin extender SBT (a custom action después de que el modelo de la "package" sbt action).

GitHub mentions an assembly task, hecho a medida para el despliegue de embarcadero. Sin embargo, podrías adaptarlo a tu necesidad.

El code is pretty generic (de this post, y el usuario Río):

project/build/AssemblyProject.scala 

import sbt._ 

trait AssemblyProject extends BasicScalaProject 
{ 
     def assemblyExclude(base: PathFinder) = base/"META-INF" ** "*" 
     def assemblyOutputPath = outputPath/assemblyJarName 
     def assemblyJarName = artifactID + "-assembly-" + version + ".jar" 
     def assemblyTemporaryPath = outputPath/"assembly-libs" 
     def assemblyClasspath = runClasspath 
     def assemblyExtraJars = mainDependencies.scalaJars 

     def assemblyPaths(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) = 
     { 
       val (libs, directories) = classpath.get.toList.partition(ClasspathUtilities.isArchive) 
       for(jar <- extraJars.get ++ libs) FileUtilities.unzip(jar, tempDir, log).left.foreach(error) 
       val base = (Path.lazyPathFinder(tempDir :: directories) ##) 
       (descendents(base, "*") --- exclude(base)).get 
     } 

     lazy val assembly = assemblyTask(assemblyTemporaryPath, assemblyClasspath, assemblyExtraJars, assemblyExclude) dependsOn(compile) 
     def assemblyTask(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) = 
       packageTask(Path.lazyPathFinder(assemblyPaths(tempDir, classpath, extraJars, exclude)), assemblyOutputPath, packageOptions) 
} 
+2

Funciona. ¿Pero no debería ser incorporado en SBT? –

+3

imho debería ser. He utilizado con éxito una versión ligeramente modificada de este AssemblyProject durante algunos meses. Fallará en archivos duplicados (algo a tener en cuenta si tiene un proyecto complejo con subproyectos), y fallará con la última versión de Hibernate (hibernate incluye algunas entradas zip raras que le causan dolor). – Michael

+1

La URL de sbt-onejar ha cambiado: https://github.com/sbt/sbt-onejar (tiene una nueva versión y documentos actualizados para SBT 0.12) – akauppi

6

Se necesita un poco de trabajo, pero también se puede utilizar Proguard desde dentro SBT para crear un JAR independiente.

Lo hice recientemente en el SBT build for Scalala.

+1

Proguard es poderoso, pero si tiene una gran cantidad de jar, debe definir manualmente cada clase o método llamado dinámicamente; consulte http://proguard.sourceforge.net/index.html#/manual/limitations.html y consulte "problemas en el tiempo de ejecución" http: // proguard .sourceforge.net/index.html #/manual/troubleshooting.html –

+0

Castigo justo por salirse del sistema de tipos;) – retronym

+0

https://github.com/ymasory/sbt-prototype utiliza [Proguard] (http: // proguard .sourceforge.net /) para hacer un jar ejecutable. El prototipo funciona de manera impecable al menos en aplicaciones simples. – user272735

0

Trabajando fuera de lo que @retronym ofreció anteriormente, construí un simple example que construye un contenedor independiente que incluye las bibliotecas de Scala (es decir, scala-library.jar) utilizando Proguard con sbt. Gracias, retronym.

0

El ejemplo más simple usando sbt-assembly

  1. Crear proyecto de directorio de su proyecto dir casa con assembly.sbt archivo incluyendo

    addSbtPlugin ("com.eed3si9n" % "SBT-ensamblaje" % "0.11 0.2")

  2. en archivo build.sbt

    importación AssemblyKeys._ // poner esto en la parte superior del archivo

    assemblySettings

    jarName + = "Mmyjarnameall.jar"

    libraryDependencies ++ = Seq ("exmpleofmydependency% "mydep" %" 0.1")

    mergeStrategy en el montaje < < = (mergeStrategy en el montaje) {(antiguo) =>

    {

    caso s si s.endsWith ("clase") => MergeStrategy.last

    caso s si s.endsWith ("pom.xml") => MergeStrategy.last

    caso s si s.endsWith ("pom.properties") => MergeStrategy.last

    caso x => edad (x)

    }

    }

0

El método más simple es sólo para crear el frasco de la línea de comandos. Si no sabes cómo hacerlo, te recomiendo encarecidamente que lo hagas. La automatización es útil, pero es mucho mejor si sabes lo que está haciendo la automatización.

La manera más fácil de automatizar la creación de un contenedor ejecutable es usar un script bash o un script por lotes en Windows.

La forma más sencilla de SBT es sólo para añadir la Scala bibliotecas que necesita a los directorios de recursos:

unmanagedResourceDirectories in Compile := Seq(file("/sdat/bins/ScalaCurrent/lib/scalaClasses")) 

Así que en mi entorno ScalaCurrent es un enlace a la biblioteca actual Scala. 2.11.4 al momento de escribir. El punto clave es que extraigo la biblioteca Scala pero la coloco dentro de un directorio ScalaClassses. Cada biblioteca extraída necesita ir a su directorio de nivel superior.

Cuestiones relacionadas