sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Offer mechanism to build a distributable with bundled JRE when using Gradle

Open tonihele opened this issue 1 year ago • 4 comments

Offer mechanism to build a distributable with bundled JRE when using Gradle. Ant has this, in the SDK. But not with Gradle. I always kinda figured that Gradle users can figure this one out themselves as one is supposed to anyway tweak around with gradle.build manually. This could be a good feature offered by the SDK.

If there is a good single solution to rule them all, that would be super. The jME initialization wizard currently does includes one solution in its generated script. That would be the easiest solution to just copy that. If there is no single solution, I guess we would need to ask this in the Gradle wizard that what kind of release one is trying to do and figure out which one to use.

One challenge after that is to have the user understand how to trigger this release build. I'm sure it shouldn't happen on every run.

Reference (and options): https://hub.jmonkeyengine.org/t/how-to-deploy-a-jme-project-as-executable-with-the-integrated-jvm-using-jme-3-6-and-above/47182/

tonihele avatar Oct 19 '23 05:10 tonihele

I've written this for my own project. Maybe it could be leveraged.

neph1 avatar Oct 19 '23 08:10 neph1

Here's what I could find. It's been a while, so I'm not sure if everything is is used. It doesn't download jre's by itself. Those I downloaded manually. There are also some hardcoded paths in there:

task jre_win_x64 {
    
    doLast {
        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/win_x64/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from zipTree(project.properties["jre_file_win_x64"])
            into "$projectDir/build/distributions/win_x64/" 
        }
    }
}

task jre_win_x86 {
    
    doLast {
        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/win_x86/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from zipTree(project.properties["jre_file_win_x86"])
            into "$projectDir/build/distributions/win_x86/" 
        }
    }
}

task jre_linux_x64 {
    doLast {
        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/linux_x64/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from zipTree(project.properties["jre_file_linux_x64"])
            into "$projectDir/build/distributions/linux_x64/" 
        }
    }
}

createAllExecutables.dependsOn jre_win_x64
createAllExecutables.dependsOn jre_win_x86

task createExe_x64(type: edu.sc.seis.launch4j.tasks.Launch4jLibraryTask) {
    bundledJrePath = project.properties["jre_name"]
    bundledJre64Bit = true
    jar = "${application.applicationName}.jar"
    outfile = '${application.applicationName}.exe'
    icon = "${projectDir}/icon.ico"
    companyName = ""
    outputDir = "distributions/win_x64"
}

task createExe_x86(type: edu.sc.seis.launch4j.tasks.Launch4jLibraryTask) {
    bundledJrePath = project.properties["jre_name"]
    jar = "lib/${application.applicationName}.jar"
    outfile = '${application.applicationName}.exe'
    icon = "${projectDir}/icon.ico"
    companyName = ''
    outputDir = "distributions/win_x86"
}

task createLinuxDist() {
    String distName = 'linux_x64';
    doLast {
        copy {
            from tarTree(file("${projectDir}/build/distributions/${application.applicationName}-${version}.tar"))
            include "${application.applicationName}-${version}/**"
            into "$projectDir/build/distributions/${distName}/" 
        }

        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/${distName}/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from tarTree(project.properties["jre_file_linux_x64"])
            into "$projectDir/build/distributions/${distName}/" 
        }
        
        copy {
            from fileTree("${projectDir}/src/main/resources/")
            into "$projectDir/build/distributions/${distName}/${application.applicationName}-${version}/bin/" 
        }
    }
}

task createMacDist() {
    String distName = 'mac_x64';
    doLast {
        copy {
            from zipTree(file("${projectDir}/build/distributions/${application.applicationName}-${version}.zip"))
            include "${application.applicationName}-${version}/**"
            into "$projectDir/build/distributions/${distName}/" 
        }

        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/${distName}/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from tarTree(project.properties["jre_file_${distName}"])
            into "$projectDir/build/distributions/${distName}/" 
        }
        
        copy {
            from fileTree("${projectDir}/src/main/resources/")
            into "$projectDir/build/distributions/${distName}/${application.applicationName}-${version}/bin/" 
        }
        
        def exec = file("$projectDir/build/distributions/${distName}/${application.applicationName}-$version/bin/${application.applicationName}");
        def replaced = exec.text.replace('DEFAULT_JVM_OPTS=""', 'DEFAULT_JVM_OPTS="-XstartOnFirstThread"')
        exec.write(replaced, "UTF-8")
    
    }
}

task createWindowsDistx64() {
    String distName = 'win_x64';
    doLast {
        
        copy {
            from zipTree(file("${projectDir}/build/distributions/${application.applicationName}-${version}.zip"))
            include "${application.applicationName}-${version}/**"
            into "$projectDir/build/distributions/${distName}/" 
        }

        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/${distName}/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from zipTree(project.properties["jre_file_${distName}"])
            into "$projectDir/build/distributions/${distName}/" 
        }
        
        copy {
            from fileTree("${projectDir}/src/main/resources/")
            into "$projectDir/build/distributions/${distName}/${application.applicationName}-${version}/bin/" 
        }
    }
}


task createWindowsDistx86() {
    String distName = 'win_x86';
    doLast {
        copy {
            from fileTree("${projectDir}/openVr/")
            include "**"
            into "$projectDir/build/distributions/${distName}/marbles-${version}/bin/openVr/" 
        }
        
        copy {
            from zipTree(file("${projectDir}/build/distributions/${application.applicationName}-${version}.zip"))
            include "${application.applicationName}-${version}/**"
            into "$projectDir/build/distributions/${distName}/" 
        }

        String jre_folder = project.properties["jre_name"]
        project.delete(fileTree("$projectDir/build/distributions/${distName}/$jre_folder"))
        copy {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            from zipTree(project.properties["jre_file_${distName}"])
            into "$projectDir/build/distributions/${distName}/" 
        }
        
        copy {
            from fileTree("${projectDir}/src/main/resources/")
            include "vr.properties"
            into "$projectDir/build/distributions/${distName}/${application.applicationName}-${version}/bin/" 
        }
    }
}

neph1 avatar Nov 04 '23 12:11 neph1

I guess we need to start by finding a concept, because just out of my head I can remember a few different solutions:

  • jlink
  • launch4j
  • install4j?
  • hand rolled solution as outlined by neph1

And they also vastly differ by the environment required (standalone, steam, ...), configuring jvm properties, keeping them updated, download bundle size (e.g. if it's always included in every patch versus a slim executable searching system jvms or downloading on demand)

MeFisto94 avatar Nov 04 '23 22:11 MeFisto94

Its actually using launch4j. I believe I opted for not bundling the jre in the exe though

neph1 avatar Nov 05 '23 10:11 neph1