Running a Gradle compiled Java application with dependencies via the java command -
i’m trying compile code example 3 this article explaining swing application framework (jsr 296) gradle , run command line java
command.
my directory layout looks this:
├── build.gradle └── src/ └── main/ └── java/ └── demo/ └── basicsingleframeapp.java
the build.gradle
file defines dependency appframework
:
apply plugin: 'java' repositories { mavencentral() } dependencies { compile 'org.jdesktop:appframework:1.0.3' }
and basicsingleframeapp.java
file, copy of example of article mentioned above, enhanced package declaration:
package demo; import org.jdesktop.application.*; import javax.swing.*; import java.awt.*; public class basicsingleframeapp extends singleframeapplication { jlabel label; @override protected void startup() { getmainframe().settitle("basicsingleframeapp"); label = new jlabel("hello, world!"); label.setfont(new font("sansserif", font.plain, 22)); show(label); } public static void main(string[] args) { application.launch(basicsingleframeapp.class, args); } }
compiling gradle build
works fine , without errors.
but when try run basicsingleframeapp
with
$ java -cp build/classes/main/ demo.basicsingleframeapp
i error message:
error: not find or load main class demo.basicsingleframeapp
when replace basicsingleframeapp
class simple “hello, world!” printing class without dependencies, works fine.
i’m confused, because in understanding correctly set classpath , don’t understand why main
method (which has right signature) cannot found.
this java version:
java version "1.8.0_20" java(tm) se runtime environment (build 1.8.0_20-b26) java hotspot(tm) 64-bit server vm (build 25.20-b23, mixed mode)
which running mac os x yosemite 10.10.2.
ok, @chuchikaeschtli helped me core of problem, namely gradle manages dependencies compiling , reports runtime, more manual tasks required make these dependencies available during runtime.
what still confuses me unintuitive error message got:
error: not find or load main class demo.basicsingleframeapp
i have expected problem has missing dependencies @ runtime report error like
error: package org.jdesktop.application not exist
which kind of error when these dependencies missing @ compile time.
and gradle gave me following report runtime dependencies (by running gradle dependencies
) thought gradle somehow manages these:
compile - compile classpath source set 'main'. \--- org.jdesktop:appframework:1.0.3 \--- org.jdesktop:swing-worker:1.1 … runtime - runtime classpath source set 'main'. \--- org.jdesktop:appframework:1.0.3 \--- org.jdesktop:swing-worker:1.1 …
in end, after knowing problem of missing runtime dependencies found several ways provide them, share.
first solution: linking cache
as stated in this stackoverflow answer gradle caches dependencies in $home/.gradle
, actual path them tricky. answer describes small gradle task outputs full path of each dependency in cache (in example compile
configuration, need):
task showmecache << { configurations.compile.each { println } }
in case gradle showmecache
reports:
$home/.gradle/caches/modules-2/files-2.1/org.jdesktop/appframework/1.0.3/338045feff6e61df237aafd11b6f3fe1a3b4e60e/appframework-1.0.3.jar $home/.gradle/caches/modules-2/files-2.1/org.jdesktop/swing-worker/1.1/dc9f8d6f7236087924aad28fbec794a087dd1b3d/swing-worker-1.1.jar
these long , nasty file paths, i’m able construct java
command works in style @chuchikaeschtli suggested:
java \ -cp build/classes/main/\ :$home/.gradle/caches/modules-2/files-2.1/org.jdesktop/appframework/1.0.3/338045feff6e61df237aafd11b6f3fe1a3b4e60e/appframework-1.0.3.jar\ :$home/.gradle/caches/modules-2/files-2.1/org.jdesktop/swing-worker/1.1/dc9f8d6f7236087924aad28fbec794a087dd1b3d/swing-worker-1.1.jar \ demo.basicsingleframeapp
this works, of course not feel “right”. helps understand problem: matter of missing dependency jars.
second solution: syncing dependencies build
directory
in section using sync task of gradle user guide explicitly uses example describes better solution problem @ hand:
here example maintains copy of project's runtime dependencies in build/libs directory.
task libs(type: sync) { configurations.runtime "$builddir/libs" }
after running task gradle libs
i’m able construct simpler working java
command:
java -cp build/classes/main/:build/libs/appframework-1.0.3.jar:build/libs/swing-worker-1.1.jar demo.basicsingleframeapp
remember: these dependencies haven’t been synced build
directory default!
third solution: using gradle run application
with application plugin gradle provides convenient solution running application. after adding these 2 lines build.gradle
apply plugin:'application' mainclassname = 'demo.basicsingleframeapp'
i able succesfully start application gradle run
. simplest solution far!
note application plugin delivers task named installdist
within build/install
creates runnable distribution of app , dependencies, complete start scripts unix , windows systems. has advantage gradle not needed execution of application.
also, if gradle run
task of application plugin concerned whether gradle available @ target system, have @ gradle wrapper.
fourth solution: creating one-jar, fat jar, or uber jar
there seem exist gradle-only ways , gradle plugins creation of these jars include of required dependencies application.
in case of gradle-one-jar-plugin application can started java
command like:
java -jar build/libs/your_app_name-standalone.jar
Comments
Post a Comment