2011-10-19 16 views
12

Estoy convirtiendo un proyecto jar heredado a SBT y por extrañas razones que no se resuelven fácilmente, este proyecto viene con "javax/servlet/Servlet.class" dentro de él. Así que de alguna manera debo excluir esta clase del archivo jar generado por bin-paquete. ¿Cómo logro esto? Preferiblemente, me gustaría excluir el uso de un comodín (es decir, javax. *).SBT: Excluir clase de Jar

El conjunto de plug-in SBT hace que parezca que tiene características que lo hará, pero me preocupa que confiar en montaje SBT significa que mi proyecto frasco no trabajará en un proyecto de módulo muliti (es decir, si lo incluyo como una dependencia en un archivo war entonces los proyectos de guerra necesitan ser contados para ejecutar el ensamblado en el proyecto jar dependiente en vez de bin-paquete - pero puedo estar equivocado aquí).

Respuesta

13

Cada tarea declara las otras tareas y configuraciones que utiliza. Puede usar inspect para determinar estas entradas como se describe en Inspecting Settings y en un estilo de tutorial reciente blog post by John Cheng.

En este caso, la tarea relevante utilizada por packageBin es mappings. La tarea mappings recopila los archivos que se incluirán en el contenedor y los asigna a la ruta en el contenedor. Algunos antecedentes se explican en Mapping Files, pero el resultado es que mappings produce un valor de tipo Seq[(File, String)]. Aquí, el archivo es el archivo de entrada que proporciona el contenido y la cadena es la ruta en el contenedor.

Por lo tanto, para modificar las asignaciones para la tarea packageBin, filtrar los caminos de las asignaciones predeterminadas que no desea incluir:

mappings in (Compile,packageBin) ~= { (ms: Seq[(File, String)]) => 
    ms filter { case (file, toPath) => 
    toPath != "javax/servlet/Servlet.class" 
    } 
} 

mappings in (Compile,packageBin) selecciona las asignaciones para la tarea principal de paquetes (como se opuesto a las fuentes de prueba o la tarea packageSrc).

x ~= f significa "establecer x en el resultado de aplicar la función f al valor anterior de x". (Consulte More About Settings para obtener más información.)

El filtro elimina todos los pares donde la ruta corresponde a la clase Servlet.

+0

esta es una solución mucho mejor que la mía y una respuesta fantástica, ya que también logró aclarar algunos conceptos básicos de SBT en el camino. –

+0

Tenga en cuenta que ~ = no está documentado en la página de 0.13, la explicación existe en 0.12 documentos http://www.scala-sbt.org/0.12.4/docs/Getting-Started/More-About-Settings.html –

+0

Sintaxis de 0.13 : '' 'asignaciones en (Compilar, packageBin): = { (asignaciones en (Compilar, packageBin)). Value.filter {case (file, toPath) => toPath! =" Javax/servlet/Servlet.class " } }' '' –

2

me ocurrió con esta solución, se define una nueva tarea de compilación, que depende de la tarea de compilación anterior (lo que permite efectivamente me engancho en la derecha después se compila la fuente y antes de que sea empaquetada)

def mySettings = { 
    // add functionality to the standard compile task 
    inConfig(Compile)(Seq(compile in Compile <<= (target,streams,compile in Compile) map{ 
    (targetDirectory, taskStream, analysis) => 
     import taskStream.log 
     // this runs after compile but before package-bin 
     recursiveListFiles(targetDirectory, ".*javax.*".r) foreach { 
     file => 
      log.warn("deleting matched resource: " + file.getAbsolutePath()) 
      IO.delete(file) 
     } 
     analysis 
    })) ++ 
    Seq(name := "MyProject", version := "1.0", exportJars := true) 
} 

def recursiveListFiles(f: File, r: Regex): Array[File] = { 
    val these = f.listFiles 
    val good = these.filter(f => r.findFirstIn(f.getName).isDefined) 
    good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_, r)) 
} 

Es un poco más complicado de lo que esperaba pero me permite hacer todo tipo de modificaciones antes de empaquetar (en este caso, buscar en la carpeta de destino eliminando todos los archivos de clase que coincidan con una expresión regular). También logró mi segundo objetivo de seguir con el ciclo de vida SBT predeterminado.

Cuestiones relacionadas