I would like to change the name of the jar when I do a
./gradlew clean assemble
The name of my jar is my-awsome-app-0.0.1-SNAPSHOT.jar and I want to generate my-awsome-app.jar.
I tested to do this in the build.gradle:
configurations {
jar.archiveName = "my-awsome-app.${jar.extension}"
}
...but this is not working, the name is still the same
Since you are using Spring Boot, you should use the bootJar task instead (notice bootJar extends Jar).
Since archiveName in Jar has been deprecated, use archiveFileName:
bootJar {
archiveFileName = 'my-awesome-app.jar'
}
Related
Basically what I'm trying to do is publish a jar file to GitHub Packages with a certain name. What I have now is:
shadowJar {
archiveFileName = "Some-Name-${parent.version}.${extension}"
}
publishing {
...
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
artifactId = 'me.project'
groupId = 'some-project'
version = 1.1.0
}
}
}
But from this I get some-project-1.1.0-all.jar, I would like to get some-project-1.1.0.jar but cant seem to find the way how. Changing the archiveFileName in the shadowJar task doesn't seem to affect the publishing jar only the build jar.
I believe you need to change the archiveClassifier of the shadowJar task. By default, this is configured as all.
Point 5: https://github.com/johnrengelman/shadow/blob/master/src/docs/getting-started/README.md#default-javagroovy-tasks
https://github.com/johnrengelman/shadow/blob/7.0.0/src/main/groovy/com/github/jengelman/gradle/plugins/shadow/ShadowJavaPlugin.groovy#L66
Something like:
tasks.shadowJar {
archiveClassifier = ""
}
The shadowJar task extends of the Jar task type. By default, with the Java plugin, archiveClassifier is configured as an empty String "". The Shadow plugin reconfigures its shadowJar task with all.
I want to run my app after building it with the shadow jar plugin.
build.gradle:
plugins {
id 'java'
id "org.jetbrains.kotlin.jvm" version "1.3.21"
id "com.github.johnrengelman.shadow" version "5.0.0"
}
group 'org.example.java'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
repositories {
jcenter()
}
dependencies {
compile "io.ktor:ktor-server-netty:1.1.3"
}
I also have a global init.gradle:
gradle.projectsLoaded {
rootProject.allprojects {
buildDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
}
So now the fat jar can be built to my global build directory with the shadowJar task. But I want to be able to run and build it with just one run configuration in IntelliJ. How do I do that?
Maybe there is another way to let gradle redirect all my output to a global build directory. I don't want to configure each IntelliJ project with the same output path manually. Suggestions are welcome.
Thank you :)
You should not touch the buildDir property for achieving what you want.
Instead, you should create a JavaExec task that will start the application from the shadow jar.
If you want that execution to be at a different place than the default location of the generated jar, you should either change the output of the shadow task itself, and only that output or make your execution task depend on a copy task that would move the shadow jar around.
Something like:
shadowJar {
destinationDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
task runApp(type: JavaExec) {
main = "your.main.Class
classpath = shadowJar.archiveFile // use archivePath before Gradle 5.1
}
I am doing the simple HelloWorld example from https://spring.io/guides/gs/gradle/.
I had to do some changes (I'm using Gradle 5.2.1 on Ubuntu 18) to the build.gradle. I used gradlew wrapper. I managed to get tasks like 'build' and 'run' working. Everything is generated correctly, it seems. But running the app without gradle using the generated build/scripts/<appscript> does not work. Running the jar with
java -jar build/libs/hello-1.0.jar
works. But
./build/scripts/sayhello
Does not work and produces an error:
erno#moongate:~/Projects/java/sayhello$ ./build/scripts/sayhello
Error: Could not find or load main class hello.HelloWorld
Caused by: java.lang.ClassNotFoundException: hello.HelloWorld
Project file structure is as suggested:
sayhello/
build.gradle
gradlew
src/
main/
java/
hello/
Greeter.java
HelloWorld.java
I had to add the manifest and the mainclass attribute to the build configuration file as it seems that the gradle init --type java-application does not do it. Meaning that even trying to run the gradle generated base project does not work.
My build.gradle is like this:
plugins {
id 'java'
id 'application'
}
mainClassName = 'hello.HelloWorld'
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile "joda-time:joda-time:2.10"
testCompile "junit:junit:4.12"
}
jar {
manifest {
attributes(
'Main-Class': 'hello.HelloWorld'
)
}
baseName = 'hello'
version = '1.0'
}
The problem with the startScripts task is that it generates a very basic script. It does not make sure dependent jars are in the right places - it expects this to be done by you. Also it assumes that you will be running the script from a directory it refers to as the $APP_HOME and this folder needs to contain a lib folder which contains all the jars your app needs.
My very hacky solution is to generate an even more basic unix script instead of relying on the default one.
startScripts {
dependsOn jar
doFirst {
unixStartScriptGenerator = configure(new CustomUnixStartScript()) {
classpath = configurations.runtimeClasspath + jar.outputs.files
}
}
}
class CustomUnixStartScript implements ScriptGenerator {
#InputFiles
FileCollection classpath
#Override
void generateScript (JavaAppStartScriptGenerationDetails details, Writer destination) {
destination << """java -classpath $classpath.asPath ${details.mainClassName}"""
}
}
You can extend this as you see fit.
I'm trying to build an executable jar in Spring Boot + Gradle project, but for now nothing works. Here is the simplest possible structure. Possibly, something is missing in Gradle configuration.
Gradle:
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
jar {
manifest {
attributes 'Main-Class': 'com.example.demo.DemoApplication'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
}
Main config file:
#RestController
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#GetMapping(value = "/")
public String index() {
return "index";
}
}
When I ran the jar file like java -jar 1.jar, I got this exception:
[main] ERROR org.springframework.boot.SpringApplication - Applicati
on startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to proces
s import candidates for configuration class [com.example.demo.DemoApplication];
nested exception is java.lang.IllegalArgumentException: No auto configuration cl
asses found in META-INF/spring.factories. If you are using a custom packaging, m
ake sure that file is correct.
at org.springframework.context.annotation.ConfigurationClassParser.proce
ssDeferredImportSelectors(ConfigurationClassParser.java:556)
at org.springframework.context.annotation.ConfigurationClassParser.parse
(ConfigurationClassParser.java:185)
at org.springframework.context.annotation.ConfigurationClassPostProcesso
r.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308)
at org.springframework.context.annotation.ConfigurationClassPostProcesso
r.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228)
at org.springframework.context.support.PostProcessorRegistrationDelegate
.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.ja
va:272)
at org.springframework.context.support.PostProcessorRegistrationDelegate
.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92)
at org.springframework.context.support.AbstractApplicationContext.invoke
BeanFactoryPostProcessors(AbstractApplicationContext.java:687)
at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:525)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationConte
xt.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.
java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringAppli
cation.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java
:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java
:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java
:1107)
at com.example.demo.DemoApplication.main(DemoApplication.java:13)
Caused by: java.lang.IllegalArgumentException: No auto configuration classes fou
nd in META-INF/spring.factories. If you are using a custom packaging, make sure
that file is correct.
at org.springframework.util.Assert.notEmpty(Assert.java:277)
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelecto
r.getCandidateConfigurations(AutoConfigurationImportSelector.java:153)
at org.springframework.boot.autoconfigure.AutoConfigurationImportSelecto
r.selectImports(AutoConfigurationImportSelector.java:95)
at org.springframework.context.annotation.ConfigurationClassParser.proce
ssDeferredImportSelectors(ConfigurationClassParser.java:547)
... 14 common frames omitted
What might be wrong?
In Boot 2.x, the bootJar and bootWar tasks are responsible for packaging the application.
The bootJar task is responsible for creating the executable jar file. This is created automatically once the java plugin is applied.
In case the executable jar/war file is not generated run the below gradle task manually.
$./gradlew bootJar
Similarly, bootWar generates an executable war file and gets created once the war plugin is applied.
We can execute the bootWar task using:
$./gradlew bootWar
Note that for Spring Boot 2.x, we need to use Gradle 4.0 or later.
I created a project with all the sources you provided. Running "gradle build" from terminal, switching to /build/libs and then running "java -jar artifactname" works just fine.
Have you tried to clean and recompile? Which Version of Gradle are you using?
In spring boot you can directly create executable jar file by
springBoot {
executable = true
}
Please try
jar{
baseName = 'myapp'
version = 'version'
}
It will create jar with name myapp-version.jar
Do ./myapp-version.jar from command line.it will execute
Refer following link for more info. https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html
I just recently tried a Spring boot application with 2.1.4.Release with Gradle build.
I ran the following command from the directory in Windows CMD.
gradlew clean build
(upon required JDK8 installed in the system), I was able to see the JAR generated under,
<project-directory>/build/libs/<project-name-version.jar>
Hope this helps though older question.
Reference:
My two cents.
When using spring-boot if you want to customize the MANIFEST.MF file, you need to set the bootJar task, it won't work on the default jar task.
bootJar {
manifest {
attributes 'Start-Class': 'com.baeldung.DemoApplication'
}
}
https://www.baeldung.com/spring-boot-main-class
If you're trying to make your .jar file executable, for use such as in a systemd service. You'll have to edit the bootJar task and enable launchScript.
build.gradle
bootJar {
launchScript()
}
or with Gradle Kotlin DSL build.gradle.kts
tasks {
bootJar {
launchScript()
}
}
You should now be able to run your project's .jar file as an executable.
I am new to Gradle. I would like to manipulate the following build.gradle contents to do this. Instead of separately running the tests then building the jar via separate commands, I'd like to do both in one command, except that the jar does not get created if one of the tests fail (it will not even try to build the jar).
apply plugin: 'java'
apply plugin: 'eclipse'
version = '1.0'
sourceCompatibility = 1.6
targetCompatibility = 1.6
// Create a single Jar with all dependencies
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'com.axa.openam'
}
baseName = project.name
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
// Get dependencies from Maven central repository
repositories {
mavenCentral()
}
test {
testLogging {
showStandardStreams = true
}
}
// Project dependencies
dependencies {
compile 'com.google.code.gson:gson:2.5'
testCompile 'junit:junit:4.12'
}
Thanks!
The simplest solution is to place all the tasks you want gradle to execute in order. So you may use the following:
gradle clean test jar
Tasks Breakout
clean: this is used mainly just to safely remove the last outdated jar (this is not mandatory);
test: execute the tests;
jar: create the jar artifact.
Key point: if one of the task fails for some reason gradle stops its execution.
So if just a single test fails for some reason an exception is thrown and the jar file is not created at all.
Alternative solution: add 'test' as dependency of 'jar'
Just to explore some other possibilities: modify the build.gralde file as follows:
[...]
jar {
dependsOn 'test'
[...]
}
[...]
Now every time you run gradle jar the test task is automatically executed before.
Emulate the pure command line solution using 'dependsOn'
To emulate the first command line approach (i.e., gradle clean test jar) using the dependency method you have to further modify the build.gradle. This is because is not assured that multiple dependsOn statements are evaluated in order:
[...]
jar {
dependsOn 'clean'
dependsOn 'test'
tasks.findByName('test').mustRunAfter 'clean'
[...]
}
[...]
Now you can use:
gradle jar
and both the tasks clean and test are executed (in the right order) before the actual jar task.