First off, this might be a dupe of Gradle build successful, error running jar
I've build a very basic Dropwizard project that is built with Gradle. My build.gradle file looks something like this:
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
// use Java 1.8 by default
sourceCompatibility = 1.8
targetCompatibility = 1.8
// default to UTF-8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
// application version and name
mainClassName='com.mydomain.WebServiceApplication'
version = '0.1-' + (System.getenv("SVN_REVISION") == null ? "0" : System.getenv("SVN_REVISION"))
jar {
manifest {
attributes 'Implementation-Title': 'WebService',
'Implementation-Version': version,
'Main-Class': mainClassName
}
}
// project variables go here
project.ext {
dropwizardVersion='0.9.1'
}
// repositories that we're getting libraries from
repositories {
mavenCentral()
}
dependencies {
// compile-time dependencies
compile (
'commons-collections:commons-collections:3.2',
'io.dropwizard:dropwizard-core:' + dropwizardVersion,
'io.dropwizard:dropwizard-client:' + dropwizardVersion,
'org.logback-extensions:logback-ext-loggly:0.1.4',
'ch.qos.logback.contrib:logback-json-classic:0.1.2',
'ch.qos.logback.contrib:logback-jackson:0.1.2'
)
// test dependencies - these will be stripped from production jar
testCompile (
'io.dropwizard:dropwizard-testing:' + dropwizardVersion,
'junit:junit:4.+'
)
}
run {
args 'server', './src/main/resources/config.yml'
}
When I run gradle build, a ./build/libs/ folder is created that contains a jar called webservice-0.1.jar. If I try to execute this jar with java -jar webservice-0.1.jar, I get the error Error: Could not find or load main class com.mydomain.WebServiceApplication.
Thing is, that file most certainly exists. I can do the following:
$ makedir tmp
$ cd tmp
$ unzip ../webservice-0.1.jar
$ ls ./com/mydomain/
and the file WebServiceApplication.class is there. Is there some kind of classpath thing that I have to do in order to get java to find classes inside of my jar? I'm lost here.
Related
I am using IntelliJ and gradle to create a multi-module spring project as shown below.
With the following build.gradle in the root folder, I have the following settings below. When invoked gradle build, a jar gets created in build/libs, however executing that jar I get the error message:
**Error: Could not find or load main class com.connect.configuration.ConnectApplication
** When running the application without building via: gradle bootRun -- the application loads up correctly. However, executing the jar file after building the project, produces the error and the jar prints out the following: using
jar -tf myJar.jar
META-INF/
META-INF/MANIFEST.MF
plugins {
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
subprojects {
group = 'com.connect.connect'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.9
targetCompatibility = 1.9
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'java-library'
repositories {
jcenter()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.10'
annotationProcessor 'org.projectlombok:lombok:1.18.10'
}
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:2.1.9.RELEASE")
}
}
}
settings.gradle
include 'connect-common'
include 'connect-ui'
include 'connect-services'
include 'connect-application'
include 'connect-configuration'
I have a project that generates a client and a server jar file. The client uses an old version of WorldWind (1.5.1) in a set of "do not touch it code", meaning I can't upgrade to a newer WorldWind. This WorldWind, in turn, depends on old versions of jogl (1.1.1a), gluegen (1.0b06), etc... The client and server both use jackson (2.6.3 is latest we have in our Artifactory) to pass JSON messages to each other, with the server using some additional jackson libraries to support another 3rd party library it needs. There is some sort of conflict between the old jogl and the jackson that makes it so that if all these libraries are together in one classpath (lib folder) they stomp on each other and running the client at startup it claims it cannot find jogl.
I had solved this in the past by generating a lib_worldwind folder that would contain only the worldwind jar, a lib_jackson folder that would contain only the server-specific jackson jars, and a lib folder that would contain everything else. I did this via ant. Then I'd tell the client its classpath was lib and lib_worldwind, and I'd tell the server it is lib and lib_jackson.
We recently have converted everything to Gradle, which in the long run will let me actually try and update some of my dependencies to never versions easier and then see what breaks (and I can then fix piecemeal). Nonetheless, it seems Gradle puts everything into one lib folder.
So my question is, how do I replicate the old behavior where stuff ends up in 3 different folders (while makeing sure Gradle also tells Eclipse where it ended up putting the stuff correctly so it can build and run)? I've been trying for a week now (I thought maybe Configurations gets me there but it either does not or I'm not doing it right).
My Gradle scripts:
root level build.gradle:
def standalone_distribution = new File(rootProject.projectDir, "standalone-distribution")
def jars_dir = new File(rootProject.projectDir, "jars")
def lib_dir = new File(rootProject.projectDir, "jars/lib")
def lib_client = new File(rootProject.projectDir, "jars/lib_worldwind")
def lib_server = new File(rootProject.projectDir, "jars/lib_jackson")
ant.importBuild 'build.xml'
buildscript {
repositories {
maven { url 'http://mylocalartifactory'}
}
dependencies {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6'
}
}
//irrelevant sonarqube settings
allprojects {
version = 'x'
}
subprojects {
repositories {
maven { url 'http://mylocalartifactory'}
flatDir { //I have to do this since I don't have some of these old libraries in my local artifactory but instead are sitting in a lib folder of specific sub projects
dirs "${projectDir}/lib"
}
}
apply plugin: 'maven'
apply plugin: 'java'
apply plugin: 'eclipse'
sourceSets {
main.java.srcDirs = ['src']
main.resources.srcDirs = ['conf']
test.java.srcDirs = ['test']
test.resources.srcDirs = ['testConf']
}
compileJava {
options.encoding = 'UTF-8'
options.compilerArgs << "-Xilint:all"
}
javadoc.options.encoding = 'UTF-8'
configurations.all {
exclude group: 'javax.media', module: 'jai-core'
exclude group: 'com.sun.media', module: 'jai_imageio'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
exclude group: 'com.sun.jmx', module: 'jmxri'
exclude group: 'ch.qos.logback', module: 'logback-classic'
}
jar { archiveName = project.name + ".jar" }
group = 'client'
group = 'server'
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:-deprecation'
options.compilerArgs << '-Xlint:-unchecked'
options.compilerArgs << '-Xlint:-rawtypes'
options.compilerArgs << '-Xlint:-varargs'
options.compilerArgs << '-Xling:-dep-ann'
}
//unit test stuff
task copyJar (type: Copy) {
from jar
into "$jars_dir"
}
task copyDeps (type: Copy) {
from configurations.runtime
into "$lib_dir"
}
task copyJarsandDeps (type: Copy, dependsOn: [copyJar, copyDeps])
}
The ant script build.xml sets up folder structure for deployment to a folder that would house this, in other words
standalone-distribution
- the primary project.name.jar jars that are my actual project + the scripts that start them
- lib
- lib_worldwind
- lib_jackson
- other folders like Resources, Docs, etc..
Then individual projects have gradle that looks like:
client build.gradle:
jar {
from('src') {
include 'resourcefolder'
}
manifest {
attributes 'Implementation-Title': 'Client', 'Implementation-Version': version
}
}
dependencies {
compile project (':some-common-code-project')
compile name: 'jogl-1.1.1a'
compile name: 'worldwind-1.5.1'
//a handful more like this name: because they are old and I don't have them in localartifactory
compile 'org.apache.commons:commons-configurations:1.10'
//a handful more that I do have
}
Then, similarly in server build.gradle:
jar {
manifest {
attributes 'Implementation-Title': 'Server', 'Implementation-Version': version
}
}
dependencies {
compile project (':some-common-code-project')
compile 'thirdpartylibrary' //not used in client, thirdpartylibrary depends on jackson-core, jackson-annotations, and jackso-databind 2.8.7 which are not compatible with WorldWind so I want them in a different directory
//a handful more that I do have in local library
}
Any idea on how to do this "split"?
edit: just inspected that old worldwind-1.5.1.jar and it contains a set of jackson packages in there! So that's probably part of the problem.
edit2: got a (previously uninvolved) coworker to look at this and he suggested trying to exclude jackson from the client build.gradle and that solved it!
We are starting a new Project with gradle (all of my previous projects are on Maven) and this is my first experience on using gradle, below is my build.gradle file and am trying to compile the java and groovy sources using the task compile
buildscript {
ext {
springBootVersion = '1.5.2.RELEASE'
springVersion = '4.3.7.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'groovy'
apply plugin: 'org.springframework.boot'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
task compile(type: GroovyCompile) {
//source = fileTree(dir: 'src', include: '**/*.java')
sourceSets {
main {
java { srcDirs = [] } // no source dirs for the java compiler
groovy { srcDir "src" } // compile everything in src/ with groovy
}
}
destinationDir = file('build/classes/main')
classpath = files('build/classes/main')
}
dependencies {
compile "org.codehaus.groovy:groovy-all:2.4.10"
compile('org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}')
compile('org.springframework.boot:spring-boot-actuator-docs:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-groovy-templates:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-jdbc:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-jersey:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-security:${springBootVersion}')
compile('org.springframework.boot:spring-boot-starter-web:${springBootVersion}')
compile('org.springframework:spring-webmvc:${springVersion}')
compile "com.microsoft:sqljdbc4:4.0"
testCompile('org.springframework.boot:spring-boot-starter-test:${springBootVersion}')
}
And when I run the gradle compile command am seeing :compile NO-SOURCE and no compiled classes in build\classes\main
can someone please help me with gradle task to compile both java and groovy sources?
The Gradle docs of the Groovy plugin describe the default layout like follows. If it is an option to stick to that, there is no need for a custom compile task.
src/main/java Production Java source
src/main/resources Production resources
src/main/groovy Production Groovy sources. May also contain Java sources for joint compilation.
src/test/java Test Java source
src/test/resources Test resources
src/test/groovy Test Groovy sources. May also contain Java sources for joint compilation.
```
I am working on gradle script where I have two separate list of cognos and other dependencies .
list 1:
cognos:a:10.1.1
cognos:b:10.1.1
cognos:c:10.1.1
cognos:d:10.1.1
com:axis:2.0.3
com:webroot:5.0.3
and List 2:
cognos:a:10.2.2
cognos:b:10.2.2
cognos:c:10.2.2
cognos:d:10.2.2
traven:nt:10.5.0
traven:txtx:5.2.1
I need to compile my source code first with list 1 dependenciesand then list 2 dependencies and publish the artifact with below name in artifactory.
Artifact with list 1 and list 2 dependencies
abc-1.0.0-cognos10.1.1
abc-1.0.0-cognos10.2.2
I can do it with build.gradle but I can do it in two separate build.gradle scripts.I am not sure how we can achieve this goal in signle build.gradle script.Can someone have any idea how to achieve it in single build.gradle
apply plugin: 'java'
version = '1.0'
sourceCompatibility = 1.7
targetCompatibility = 1.7
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'com.mkyong.DateUtils'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
//Get dependencies from Maven central repository
repositories {
mavenCentral()
}
//Project dependencies
dependencies {
compile 'cognos:a:10.1.1
compile 'cognos:b:10.1.1'
compile 'cognos:c:10.1.1'
compile 'cognos:d:10.1.1'
compile 'traven:nt:10.5.0'
compile 'traven:txtx:5.2.1'
}
In your build.gradle, replace cognos and app version with a parameter:
version = "1.0.0-cognos${cognosVersion}"
sourceCompatibility = 1.7
targetCompatibility = 1.7
...
dependencies {
compile "cognos:a:${cognosVersion}"
compile "cognos:b:${cognosVersion}"
compile "cognos:c:${cognosVersion}"
compile "cognos:d:${cognosVersion}"
}
Then you can manually run this a few times:
gradle build -PcognosVersion=xxxx
If you want to automate that as well, you can write a second gradle driver script release.gradle:
defaultTasks 'performRelease'
task performRelease() << {
['10.1.1','10.2.2'].each{
def tempTask = tasks.create(name: "execute_$it", type: GradleBuild)
tempTask.buildFile='build.gradle'
tempTask.tasks = ['build']
tempTask.startParameter.projectProperties = [cognosVersion: it]
tempTask.execute()
}
}
which you can executes as: gradle -b release.gradle
I'm pretty new to gradle and java at all..
I have a project which uses sqlite and it runs fine through intellij idea but I can't run it from the terminal, it throws an exception:
java.lang.ClassNotFoundException: org.sqlite.JDBC
I've tried to get process which intellij idea spawns when it runs the project:
/usr/lib/jvm/java-7-openjdk-amd64/bin/java -agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=42986 -Dfile.encoding=UTF-8 -cp /home/user/my_project/target/classes/main:/home/user/my_project/target/resources/main:/home/user/.gradle/caches/modules-2/files-2.1/org.xerial/sqlite-jdbc/3.7.2/7a3d67f00508d3881650579f7f228c61bfc1b196/sqlite-jdbc-3.7.2.jar Main
As I see here idea specifies classpath which is the solution but how can I run my .jar file of the project without specifying classpath? I mean can gradle generate manifest automatically (because it retrieves sqlite-jdbc from maven org.xerial repository successfully) and put valid classpath there?
I want to run it successffully from the terminal.
UPD: I can't it run from the terminal only by gradle run command but I can't run the project by java -jar myproject.jar.
Here is my build.gradle:
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'application'
group = 'myproject'
version = '0.3'
description = """my project description"""
buildDir = "target"
mainClassName = "Main"
repositories {
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
testCompile group: 'junit', name: 'junit', version:'3.8.1'
compile 'org.xerial:sqlite-jdbc:3.7.2'
}
jar {
manifest.attributes("Main-Class": "Main")
}
/* Overwriting distribution tasks: */
task distZip(type:Zip, overwrite:true) {
archiveName = "$project.name-$version" + '.zip'
from "target/libs"
}
task distTar(type:Tar, overwrite:true) {
archiveName = "$project.name-$version" + '.tar'
from "target/libs"
}
Java source code which throws an exception:
try {
Class.forName("org.sqlite.JDBC");
this.connection = DriverManager.getConnection(databaseName);
} catch (Exception e) {
e.printStackTrace();
}
I've fixed this issue by adding sqlite in the classpath of distribution jar file of the project by modifying my jar section by this:
task copyDependenciesToTarget(type: Copy) {
println 'Copying dependencies to target...'
configurations.compile.collect().each { compileDependency ->
copy {
with from (compileDependency.getPath()) {
include '*'
}
into 'target/libs/libs'
}
}
}
build.dependsOn(copyDependenciesToTarget)
jar {
manifest.attributes(
"Main-Class": "Main",
"Class-Path": configurations.compile.collect { 'libs/' + it.getName()}.join(' ')
)
}
Now gradle downloads dependencies and copies them to libs/ directory.