reference - hacer - exportar en eclipse
cómo exportar un jar ejecutable en gradle, y este jar puede ejecutarse como incluye bibliotecas de referencia (5)
Respuesta rápida
Agregue lo siguiente a su
build.gradle
:apply plugin: ''application'' mainClassName = ''org.example.app.MainClass'' jar { manifest { attributes ''Main-Class'': mainClassName, ''Class-Path'': configurations.runtime.files.collect {"$it.name"}.join('' '') } }
- Desde el directorio del proyecto, ejecuta
gradle installDist
- Ejecute
java -jar build/install/<appname>/lib/<appname>.jar
Recomiendo agregar la versión de la aplicación a su build.gradle
también, pero no es obligatorio. Si lo hace, el nombre del jar creado será <appname>-<version>.jar
.
Nota: estoy usando gradle 2.5
Detalles
Para crear un archivo ejecutable autónomo con el que simplemente pueda ejecutar:
java -jar appname.jar
necesitará:
- su jar para incluir un archivo MANIFEST apuntando a la clase principal de su aplicación
- todas sus dependencias (clases de frascos fuera de su aplicación) para ser incluidas o accesibles de alguna manera
- su archivo MANIFEST para incluir el classpath correcto
Como señalan otras respuestas, puede usar un complemento de terceros para lograr esto, como shadow o one-jar .
Probé con shadow, pero no me gustó el hecho de que todas mis dependencias y sus recursos se vierten directamente en el contenedor integrado junto con mi código de aplicación. También prefiero minimizar el uso de complementos externos.
Otra opción sería usar el plugin de la aplicación gradle como @erdi respondió anteriormente. Al ejecutar gradle build
creará un jar para usted y se lo gradle build
con todas sus dependencias en un archivo zip / tar. También puede ejecutar gradle installDist
para omitir la gradle installDist
.
Sin embargo , como @jeremyjjbrown escribió en un comentario allí, el complemento no crea un archivo ejecutable per se. Crea un jar y un script que construye el classpath y ejecuta un comando para ejecutar la clase principal de tu aplicación. No podrá ejecutar java -jar appname.jar
.
Para obtener lo mejor de ambos mundos, siga los pasos anteriores que crean su jar junto con todas sus dependencias como frascos separados y agregue los valores correctos a su MANIEST.
cómo exportar un jar ejecutable en gradle, y este jar puede ejecutarse como incluye bibliotecas de referencia.
build.gradle
apply plugin: ''java''
manifest.mainAttributes("Main-Class" : "com.botwave.analysis.LogAnalyzer")
repositories {
mavenCentral()
}
dependencies {
compile (
''commons-codec:commons-codec:1.6'',
''commons-logging:commons-logging:1.1.1'',
''org.apache.httpcomponents:httpclient:4.2.1'',
''org.apache.httpcomponents:httpclient:4.2.1'',
''org.apache.httpcomponents:httpcore:4.2.1'',
''org.apache.httpcomponents:httpmime:4.2.1'',
''ch.qos.logback:logback-classic:1.0.6'',
''ch.qos.logback:logback-core:1.0.6'',
''org.slf4j:slf4j-api:1.6.0'',
''junit:junit:4.+''
)
}
después de ejecutar: construcción gradle
crea la carpeta de compilación y ejecuto el jar en build / libs / XXX.jar:
java -jar build / libs / XXX.jar
aquí hay una ejecución dice:
Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/joran/spi/JoranException
¿Cómo puedo ejecutarlo con las bibliotecas de referencia?
Espero que esto ayude a alguien (ya que desafortunadamente pasé bastante tiempo tratando de encontrar la solución). Aquí está la solución que funcionó para mí para crear un JAR ejecutable. Incrustaré Jetty en el método principal, Jetty 9 para ser específico y usar Gradle 2.1.
Incluya el siguiente código en su archivo build.gradle (si un subproyecto es el proyecto "principal" del que se debe construir el contenedor, agréguelo al subproyecto que debe comenzar como este proyecto ('':'') {inserte el código en algún lugar aquí, después de las dependencias.}.
Además, necesitas agregar el plugin java para que esto funcione: aplica el plugin: ''java''.
Mi tarea jar se ve de la siguiente manera:
apply plugin: ''java''
jar {
archiveName = "yourjar.jar"
from {
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes ''Main-Class'': ''your.package.name.Mainclassname''
}
exclude ''META-INF/*.RSA'', ''META-INF/*.SF'',''META-INF/*.DSA''
}
Y luego puede ejecutar su yourjar.jar a través de la línea de comandos:
java -jar yourjar.jar
El META-INF / .RSA, META-INF / .SF y META-INF / *. DSA tienen que ser excluidos para que funcione. De lo contrario, se lanza una SecurityException.
El problema parece residir en Jetty integrado, ya que Jetty se movió a Eclipse y ahora está firmando sus JAR, lo que leo se vuelve problemático cuando otros JAR sin firmar quieren cargar los firmados. Por favor, siéntanse libres de educarme si me equivoco en esto, eso es exactamente lo que leo.
Los JAR de los que depende el proyecto se definen en las dependencias de la siguiente manera:
dependencies {
// add the subprojects / modules that this depends on
compile project('':subproject-1'')
compile project('':subproject-2'')
compile group: ''org.eclipse.jetty'', name: ''jetty-server'', version: ''9.2.6.v20141205''
compile group: ''org.eclipse.jetty'', name: ''jetty-servlet'', version: ''9.2.6.v20141205''
compile group: ''org.eclipse.jetty'', name: ''jetty-http'', version: ''9.2.6.v20141205''
}
EDITAR: Antes, en lugar de solo
configurations.runtime.collect{...}
tuve
configurations.runtime.asFileTree.files.collect{...}
Esto causó un comportamiento extraño en un proyecto más grande en construcción limpia. Al ejecutar el jar después de ejecutar gradle clean build por primera vez (después de limpiar manualmente el directorio de compilación) arrojaría NoClassDefFoundException (en nuestro proyecto con muchos subproyectos), pero ejecuta el jar después de ejecutar gradle clean build por segunda vez (sin vaciar manualmente el directorio de compilación), por alguna razón tenía todas las dependencias. Esto no sucedió si se omitió asFileTree.files.
También debo tener en cuenta que todas las dependencias de compilación se incluyen en el tiempo de ejecución, sin embargo, no todo el tiempo de ejecución se incluye en la compilación. Entonces, si solo estás usando compilar
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
Luego, asegúrese de recordar que si se lanza una excepción NoClassDefFoundException, no se encuentra alguna clase en el tiempo de ejecución, lo que significa que también debe incluir esto:
configurations.runtime.collect {
it.isDirectory() ? it : zipTree(it)
}
Puedes lograrlo con el plugin de aplicaciones Gradle
Todas estas respuestas son incorrectas o están desactualizadas.
El OP está pidiendo lo que se conoce como un "tarro de grasa". Es un contenedor ejecutable que contiene todas las dependencias para que no requiera de dependencias externas para ejecutarse (¡excepto por un JRE, por supuesto!).
La respuesta al momento de escribir es el complemento Gradle Shadow Jar, explicado con bastante claridad en la Guía del usuario de Shadow Plugin & Examples .
Luché un poco. Pero esto funciona:
ponga todas estas líneas en algún lugar de su archivo build.gradle (las puse cerca de la parte superior):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath ''com.github.jengelman.gradle.plugins:shadow:1.2.4''
}
}
apply plugin: ''com.github.johnrengelman.shadow''
shadowJar {
baseName = ''shadow''
classifier = null
version = null
}
jar {
manifest {
attributes ''Class-Path'': ''/libs/a.jar''
attributes ''Main-Class'': ''core.MyClassContainingMainMethod''
}
}
PD: no se preocupe por ninguna otra línea de "repositorios", "dependencias" o "complementos" en ningún otro lugar de su archivo de compilación, y deje las líneas dentro de este bloque de "compilación" (no tengo ni idea de por qué debe hacerlo) ese).
PPS, la Guía de usuario y ejemplos de Shadow Plugin está bien escrita, pero no le dice que incluya la línea
attributes ''Main-Class'': ''core.MyClassContainingMainMethod''
donde lo he puesto arriba. Tal vez porque el autor asume que estás menos despistado que yo, y probablemente lo estés. No tengo ni idea de por qué se nos dice que pongamos un extraño atributo de "Ruta de clase", pero si no está roto, no lo arregles.
Cuando tu vas
> gradle shadowjar
Se espera que Gradle construya un jar ejecutable gordo en / build / libs (nombre predeterminado "shadow.jar") que puedes ejecutar haciendo esto:
> java -jar shadow.jar
Revisé algunos enlaces para la solución, finalmente hice los pasos mencionados a continuación para que funcione. Estoy usando Gradle 2.9.
Realice los siguientes cambios en su compilación, archivo gradle:
1. Complemento de Mención:
apply plugin: ''eu.appsatori.fatjar''
2. Proporcione el Buildscript:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
}
}
3. Proporcione la clase principal:
fatJar {
classifier ''fat''
manifest {
attributes ''Main-Class'': ''my.project.core.MyMainClass''
}
exclude ''META-INF/*.DSA'', ''META-INF/*.RSA'', ''META-INF/*.SF''
}
4. Crea el fatjar:
./gradlew clean fatjar
5. Ejecute el fatjar desde / build / libs /:
java -jar MyFatJar.jar