36

I need to add default JVM options to my jar, when build with Gradle. From the documentation I got that I have to set:

applicationDefaultJvmArgs = ["-Djavafx.embed.singleThread=true"]

I have not much experience with Gradle and the developer that wrote the build.gradle file wrote it different from what most websites give as examples.

Here is the build.gradle:

apply plugin: 'java'
apply plugin: 'eclipse'

version = '0.1'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.+'
    compile 'placeholder'
}

task release(type: Jar) {
    manifest {
        attributes("Implementation-Title": "placeholder",
                "Implementation-Version": version,
                'Main-Class': 'placeholder.Application')
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }

    with jar
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.2.1'
}

I don't know where to put the arguments. I tried putting them in different locations, but I always get:

A problem occurred evaluating root project 'placeholder'.
> No such property: applicationDefaultJvmArgs for class: org.gradle.api.tasks.bundling.Jar_Decorated

Much Thanks, Jhonny

Jhonny007
  • 1,698
  • 1
  • 13
  • 33
  • When do you need to add the JVM parameter? Could you just set the system variable in the static of initialization of your main class? – Ethan Feb 06 '16 at 22:54
  • I need to add the parameter at compile time, so the user doesn't have to add it manual when he is starting his .jar – Jhonny007 Feb 06 '16 at 23:23
  • You can do something like `System.setproperty("javafx.embed.singleThread", "true") ` in code but you will to make sure that this statement gets executed before the system property gets accessed somewhere. – KKishore Feb 07 '16 at 03:39

5 Answers5

42

From the top of my head I can think of 2 options:

Option1: Do what @Ethan said, it'll likely work:

package placeholder;

//your imports

public class Application{
  static {
      System.getProperties().set("javafx.embed.singleThread", "true");  
  }
  // your code
  public static void main(String... args){
    //your code
  }
}

Option 2: Use the application plugin + default jvm values

build.gradle:

apply plugin: 'application'
//your code
applicationDefaultJvmArgs = ["-Djavafx.embed.singleThread=true"]

Now you can run your code 2 ways:

From gradle

$gradle run

From distribution(script). from the generated script that the application plugin will provide:

$gradle clean build distZip

Then gradle will generate a zip file somewhere under ${your.projectdir}/build. Find the zip then unzip it and under /bin you'll find a ${yourproject}.bat and ${yourproject} executables. One is for Linux/mac/unix (${yourproject}) the other one is for windows (${yourproject.bat})

Option 3 (Android Developer): Use gradle.properties to set jvm argument

# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 

# You can setup or customize it according to your needs and combined with the above default value.
org.gradle.jvmargs=-Djavafx.embed.singleThread=true

For more info on how to use gradle build environment on docs.gradle.org

mochadwi
  • 1,190
  • 9
  • 32
  • 87
portenez
  • 1,189
  • 1
  • 10
  • 19
  • Thank you, the second option worked. The first option looked like it worked, but only in IntelliJ. The jar seems to have a different execution order, so it didn't work there. – Jhonny007 Feb 07 '16 at 23:06
  • 5
    @portenez, I think option 3 is for the JVM that is running gradle – kaushik Jan 24 '20 at 02:39
4

applicationDefaultJvmArgs is provided by the Application plugin. So if you apply that plugin, the error would probably go away, and you should be able to execute the program by issuing gradle run once you set the mainClassName property to the fully qualified class name, the main method of which you want to invoke.

KKishore
  • 452
  • 5
  • 12
  • 3
    Ok, after looking deeper into this, the Application plugin only enables the jvm parameters to be executed with gradle run. But I need them to be executed by the .jar, when the consumer wants to start the application. – Jhonny007 Feb 06 '16 at 23:24
2

Using a local gradlew is the easiest. Just append to DEFAULT_JVM_OPTS.

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m" "-XX:+AllowRedefinitionToAddDeleteMethods"'
Ali Ben Zarrouk
  • 1,891
  • 16
  • 24
1

you can use command-line with gradle task:

class AppRun extends JavaExec {
    private boolean withDebug

    @Option(option = "with-debug", description = "enable debug for the process. ")
    public void setDebugMode(boolean debug) {
        this.withDebug = debug
    }

    public boolean getDebugMode() {
        return this.withDebug
    }
}

task run(type: AppRun) {
}

then run task with options

gradle run --with-debug

jiahut
  • 1,451
  • 15
  • 14
-2

set this to Your java main Class.

static {
    System.setProperty("nashorn.args", "--no-deprecation-warning");
}
Gayan Chinthaka
  • 521
  • 6
  • 5