no main manifest attribute, in application.jar - java

I am getting the following error while spring boot jar in CI environment
java -jar application.jar
no main manifest attribute, in application.jar
The weird thing is, it does not give the issue in my local or jenkins slave. It starts all right.
It faces issue when I upload the jar to Nexus artifactory and download it on my CI environment.
Building jar using
gradle clean build -x test
My gradle.build file
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
jcenter()
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.akhikhl.gretty:gretty:1.2.4'
classpath 'org.ajoberstar:gradle-jacoco:0.1.0'
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:1.2'
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")
}
}
repositories {
mavenCentral()
mavenLocal()
maven {
credentials {
username "hello"
password "world"
}
url "Nexus URL"
}
}
apply plugin: 'maven-publish'
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'spring-boot'
apply plugin: "org.sonarqube"
apply plugin: 'jacoco'
group = 'com.company.pod'
/* Determining version from jenkins pipeline, otherwise is set to 1.0.0-SNAPSHOT */
version = new ProjectVersion(1, 0, System.env.SOURCE_BUILD_NUMBER, System.env.RELEASE_TYPE)
println(version)
class ProjectVersion {
Integer major
Integer minor
String build
String releaseType
ProjectVersion(Integer major, Integer minor, String build, String releaseType) {
this.major = major
this.minor = minor
this.build = build
this.releaseType = releaseType
}
#Override
String toString() {
String fullVersion = "$major.$minor"
if(build) {
fullVersion += ".$build"
}
else{
fullVersion += ".0"
}
if(releaseType) {
fullVersion += "-RELEASE"
}
else{
fullVersion += "-SNAPSHOT"
}
fullVersion
}
}
/*Sonarqube linting of your repository.*/
sonarqube {
properties {
property "sonar.language", "java"
}
}
/* Please don't comment out the part below
To run the same on your laptops/prod boxes/CUAT boxes, just edit the gradle.properties file.
(It will be present in the home directory of the user you are using to run gradle with.`sudo` means root user and likewise)
Enter the following lines(and yes, it will run without values, thank you gradle!)
nexusUrl=
nexusRelease=
nexusSnapshot=
nexusUsername=
nexusPassword=
*/
uploadArchives {
repositories {
mavenDeployer {
repository(url: nexusUrl+"/"+nexusRelease+"/") {
authentication(userName: nexusUsername, password: nexusPassword)
}
snapshotRepository(url: nexusUrl+"/"+nexusSnapshot+"/"){
authentication(userName: nexusUsername, password: nexusPassword)
uniqueVersion = false
}
}
}
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
publishing {
publications {
maven(MavenPublication) {
groupId 'com.company.something'/*This is different from group variable before*/
artifactId 'something'
version '2.0.0'
from components.java
}
}
}
/*
publishing {
repositories {
maven {
url "~/.m2/repository/"
}
}
}
*/
task wrapper(type: Wrapper) {
gradleVersion = '2.9'
distributionUrl = "https://services.gradle.org/distributions/gradle-$GradleVersion-all.zip"
}
dependencies {
compile('org.projectlombok:lombok:1.16.6')
compile("com.company.commons:company-app:0.0.1-RELEASE")
compile group: 'com.google.guava', name: 'guava', version: '19.0'
compile("com.squareup.retrofit2:retrofit:2.0.1")
compile("com.squareup.retrofit2:converter-jackson:2.0.1")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7'
compile("com.getsentry.raven:raven-logback:7.2.2")
compile("org.springframework.boot:spring-boot-starter-actuator")
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile("com.h2database:h2")
testCompile("junit:junit")
// testCompile("org.springframework.boot:spring-boot-starter-test")
// testCompile group: 'org.hibernate', name: 'hibernate-validator', version: '4.2.0.Final'
}
Articles consulted with no vain
1. Gradle- no main manifest attribute
2. http://www.vogella.com/tutorials/Gradle/article.html#specifying-the-java-version-in-your-build-file
3. Can't execute jar- file: "no main manifest attribute"

The default packaged jar file does not contain MANIFEST file.
I don't know how to configure in Gradle, but in Maven when I added plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>vn.dung.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
And it works for me.
You could change that Maven plugin config to Gradle.

i had to run gradle bootRepackage after building the jar and git a jar that I could execute!

It worked with
gradle upload -x jar

In build.gradle, I noticed boot repackaging was disabled so I enabled it :
bootRepackage {
enabled = true
}

Hi I had exactly same problem, and I found the answer in:
Spring Boot Upload BootRepackage Executable Jar
I used the solution 2
publish {
dependsOn assemble
}

Related

no main manifest attribute, in jar

I have a spring project with Gradle. I created a task in the build.gradle:
task dockerFile(type: Dockerfile) {
destFile.set(project.file('Dockerfile'))
from "alpine:$alpineVersion"
runCommand 'apk add --no-cache openjdk11'
copyFile "build/libs/${jar.archiveFileName.get()}", '/app/'
workingDir '/app/'
entryPoint 'java'
defaultCommand '-jar', "/app/${jar.archiveFileName.get()}"
}
Everything works fine. Dockerfile is generated. But when I try to run the image it gives me the error: no main manifest attribute, in /app/demo-0.0.1-SNAPSHOT-plain.jar
Also here is my entire build.gradle:
import com.bmuschko.gradle.docker.tasks.image.Dockerfile
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'com.bmuschko.docker-remote-api' version '6.6.1' apply false
}
group = 'ms10gradle2'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$jpaVersion"
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
task printJpaVer{
print "JPA VERSION: ${jpaVersion}"
}
task printfiles {
doLast {
def files = "cmd.exe /c dir".execute().text.trim()
println(files)
project.getAllprojects().forEach(System.out::print)
}
}
task printTasks{
project.getTasks().forEach{
println("task name: "+ it)
}
}
task printTasksInsideSubModulesTrueOrFalse{
project.getAllTasks(false).entrySet().forEach(System.out::println)
}
task printTaskVersion{
project.getAllprojects()
.forEach(p -> println p.name +"- "+p.getVersion())
print "================================================================"
project.getAllprojects().forEach(p -> println p.getVersion())
}
task dockerFile(type: Dockerfile) {
destFile.set(project.file('Dockerfile'))
from "alpine:$alpineVersion"
runCommand 'apk add --no-cache openjdk11'
copyFile "build/libs/${jar.archiveFileName.get()}", '/app/'
workingDir '/app/'
entryPoint 'java'
defaultCommand '-jar', "/app/${jar.archiveFileName.get()}"
}
and Dockerfile:
FROM alpine:3.11.2
RUN apk add --no-cache openjdk11
COPY build/libs/demo-0.0.1-SNAPSHOT-plain.jar /app/
WORKDIR /app/
ENTRYPOINT ["java"]
CMD ["-jar", "/app/demo-0.0.1-SNAPSHOT-plain.jar"]
Looks like you tried to run jar is not executable.
Let's say you have main class in your code with name fully.qualified.MainClass
There are 2 ways:
It it necessary to add manifest with main-class(preferable):
for maven:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
...
</plugin>
maven documentation for more info.
for gradle
it is necessary to add jar task with Main-Class:
jar {
manifest {
attributes 'Main-Class': 'fully.qualified.MainClass'
}
}
Jar task documentation
and also there was question about gradle executable jar: Creating runnable JAR with Gradle
run jar with your main class as param:
java -cp MyJar.jar fully.qualified.MainClass
How to run a class from Jar which is not the Main-Class in its Manifest file

Extracting spring boot starters to separate JAR

What I'm trying to do is to extract all of spring-boot-starters to a separate app, pack all of it into a single JAR (using gradle shadow plugin) and then deploy it to local nexus artifacts repository, so I can import it and all of its dependencies to my spring boot application.
Here is build.gradle of app that contains spring-boot-starters:
buildscript {
ext {
springBootVersion = '2.1.0.RELEASE'
}
repositories {
mavenCentral()
jcenter()
maven {
url "http://localhost:8081/repository/testowe/"
credentials {
username 'admin'
password 'admin123'
}
}
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.4'
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
subprojects {
apply plugin: 'java-library'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'maven-publish'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'org.springframework.boot'
version = '1.0'
sourceCompatibility = 1.11
jar { enabled = true }
shadowJar { classifier(null) }
repositories {
jcenter()
mavenCentral()
maven {
url "http://localhost:8081/repository/testowe/"
credentials {
username 'admin'
password 'admin123'
}
}
}
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
}
}
repositories {
maven {
url "http://localhost:8081/repository/testowe/"
credentials {
username 'admin'
password 'admin123'
}
}
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web') {
transitive = true
}
compile('org.springframework.boot:spring-boot-starter-actuator') {
transitive = true
}
compile('org.springframework.boot:spring-boot-starter-data-jpa') {
transitive = true
}
compile('org.springframework.boot:spring-boot-starter-security') {
transitive = true
}
compile('org.springframework.boot:spring-boot-starter-test') {
transitive = true
}
}
}
Here is build.gradle of spring-boot app that I want to run with all spring-boot-starter dependencies coming from built JAR:
buildscript {
ext {
springBootVersion = '2.1.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = 11
repositories {
mavenCentral()
maven {
url "http://localhost:8081/repository/testowe/"
credentials {
username 'admin'
password 'admin123'
}
}
}
dependencies {
// When I'm running app with starters placed here everything works fine
// implementation('org.springframework.boot:spring-boot-starter-data-jpa')
// implementation('org.springframework.boot:spring-boot-starter-security')
// implementation('org.springframework.boot:spring-boot-starter-test')
// implementation('org.springframework.boot:spring-boot-starter-web')
// When I'm trying to run it with my JAR it doesn't work
implementation("pl.mplan:web-common:1.0")
compile group: 'org.javassist', name: 'javassist', version: '3.23.2-GA'
compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
runtimeOnly('org.postgresql:postgresql')
compileOnly('org.projectlombok:lombok')
testImplementation('org.springframework.boot:spring-boot-starter-test')
compile("com.querydsl:querydsl-core:4.2.1")
compile("com.querydsl:querydsl-jpa:4.2.1")
compile("com.querydsl:querydsl-apt:4.2.1:jpa")
}
compileJava {
options.annotationProcessorGeneratedSourcesDirectory = file("$projectDir/generated/java")
}
idea {
module {
sourceDirs += file("$projectDir/generated/java")
}
}
When I'm trying to run app with gradle bootRun task here's what I get:
17:55:32.169 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Retrieved dependent beans for bean 'objectPostProcessor': [org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration]
17:55:32.169 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy() on bean with name 'objectPostProcessor'
17:55:32.175 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
at pl.mplan.brew.it.BrewItBackendApplication.main(BrewItBackendApplication.java:12)
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:204)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:178)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152)
... 8 common frames omitted
(I'm using gradle 4.8 and shadow plugin 4.0.4)
Any ideas how to fix it? Thanks in advance!

Move all libs version to root gradle file in multi module gradle project

I have gradle project with modules.
-RootProject
-my-server(spring boot 2server)
-my-generator(module)
Now my root project's gradle file look like this:
group = 'com.mayprojekt'
version = '0.0.1-SNAPSHOT'
Gradle settings file look like this:
rootProject.name = 'root-project'
include 'my-generator'
include 'my-server'
my-server's gradle file look like this:
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
cxfVersion = '3.2.2'
uuidGeneratorVersion = '3.1.5'
commonLang3Version = '3.7'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group 'com.mayprojekt'
version '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
mavenLocal()
}
bootJar {
mainClassName = 'com.mayprojekt.Application'
archiveName = 'my-server.jar'
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter'
compile "org.apache.cxf:cxf-spring-boot-starter-jaxws:${cxfVersion}"
compile "com.fasterxml.uuid:java-uuid-generator:${uuidGeneratorVersion}"
compile "org.apache.cxf:cxf-rt-features-logging:${cxfVersion}"
compile "org.apache.commons:commons-lang3:${commonLang3Version}"
compileOnly('org.projectlombok:lombok')
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("oracle:ojdbc6:11.2.0.3")
compile project(':my-generator')
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
my-generator module just module with some classes.
But I want move all libraries versions to root gradle file. I make it in maven project and I need something look like this:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring.ws.version>3.0.0.RELEASE</spring.ws.version>
<jvnet.jaxb2.maven2.version>0.13.2</jvnet.jaxb2.maven2.version>
<cxf.version>3.2.4</cxf.version>
<commons.codec.version>1.11</commons.codec.version>
<springfox.version>2.7.0</springfox.version>
<oracle.version>11.2.0.3</oracle.version>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
But I don know how can I make this with gradle.
Assuming your my-generator project is a gradle project, then you can do this in the root build.gradle:
...
project(':my-server') {
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
....
}
project(':my-generator') {
apply plugin: 'java'
dependencies {
compile 'org.springframework.boot:spring-boot-dependencies:2.0.2.RELEASE'
}
}
...
Using the 'project' clause, you can apply configurations only to children module projects from the root project.
using the 'allprojects' clause you can apply certain configurations to all your child module projects:
allprojects {
dependencies { ... }
}
Check this out https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-creating-a-multi-project-build/
Hope this helps

Class in main/resources not found

I'm using the Spring Boot gradle plugin to build an executable war. I have a FindResource.java class in src/main/resources to locate files:
FindResource.class.getResource(templateName).toURI()
When I execute gradle build I get an error, that the class FindResource cannot be resolved. Do I need to the the Spring Boot gradle plugin, that it should also use classes from the resources directory. How can I do so?
My build.gradle looks as follows:
buildscript {
ext {
springBootVersion = '1.2.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("io.spring.gradle:dependency-management-plugin:0.5.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'io.spring.dependency-management'
jar {
baseName = 'abc'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-jersey")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.apache.pdfbox:pdfbox:1.8.10")
compile('org.apache.poi:poi-ooxml:3.12')
compile('org.apache.poi:poi-scratchpad:3.12')
runtime("org.hsqldb:hsqldb")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
As mentioned in the comment class files to load need to be in src/main/java/ and not in src/main/resources. This link may help give you more information on the convention of this structure.

Generates the OSGI-INF/serviceComponent.xml using gradle

OSGI-INF/serviceComponent.xml can be generated using maven scr felix plugin by adding dependency like
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
<version>1.15.0</version>
<executions>
<execution>
<id>generate-scr-scrdescriptor</id>
<goals>
<goal>scr</goal>
</goals>
</execution>
</executions>
</plugin>
but for gradle I am not able to generate.. I have tried to add the
buildscript {
dependencies {
classpath group:'be.jlr-home.gradle' , name:'scrPlugin', version:'0.1.0'
}}
apply plugin: 'java'
`apply plugin: 'eclipse'
apply plugin: 'maven'
apply plugin: 'osgi'
apply plugin: 'scr'
It's giving error that be.jlr-home.gradle not found.
I am doing something wrong???
basically I need the dependency to add in gradle to generate the servicecomponent.xml
Your maven pom snippet configures the maven plugin for scr from felix. You need a gradle plugin for scr annotation processing. I don't know that felix has one. The bnd project has added gradle support (2.4.0.M1 includes a gradle plugin for bnd) and bnd can process annotations for DS (but maybe not the one's from Felix).
I have resolved the issue
add the below lines to your gradle file and it will work.
ant.properties.src = 'src/main/java'
ant.properties.classes = 'build/classes/main'
task genscr(dependsOn: compileJava) << {
println ant.properties.classes
ant.taskdef(resource: 'scrtask.properties', classpath: configurations.compile.asPath)
ant.scr(srcdir: ant.properties.src, destdir: ant.properties.classes, classpath: configurations.compile.asPath)
}
jar.dependsOn(genscr)
jar {
manifest {
// version = '1.0'
name = 'xxxxxxxxx'
instruction 'Service-Component', 'OSGI-INF/<PKGNAME>.<CLASSNAME>.xml'
}
dependencies {
......//All other dependencies........
compile 'org.apache.felix:org.apache.felix.scr.annotations:1.9.8'
compile 'org.apache.felix:org.apache.felix.scr.ds-annotations:1.2.4'
compile group: 'org.apache.felix', name: 'org.apache.felix.scr.ant', version: '1.110.'
}
sourceSets.main.compileClasspath += configurations.compile
#saviour23's solution did not work for me
It turns out we need to change the buildscript, and that gradle 1.6 does not work; after I upgraded to gradle 2.1, it works fine.
java code:
import org.apache.felix.scr.annotations.*;
#Component
public class Bndtest {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'be.jlr-home.gradle:scrPlugin:0.1.3'
}
}
apply plugin: 'java'
apply plugin: 'osgi'
apply plugin: 'scr'
apply plugin: 'groovy'
apply plugin: 'maven'
sourceCompatibility = 1.6
targetCompatibility = 1.6
version = '0.0.1-SNAPSHOT'
group = 'be.jlrhome.gradle.scr'
description = 'Gradle scr example'
dependencies {
compile 'org.apache.felix:org.apache.felix.scr.annotations:1.9.8'
}
gradle will wrap a jar with correct MANIFEST and OSGI XML

Categories