Various improvements and code cleanup.

This commit is contained in:
Norberto Lopez
2013-04-03 21:00:10 +00:00
parent 15338b17df
commit 7b95c304b7
6 changed files with 304 additions and 119 deletions

View File

@@ -38,12 +38,13 @@ def buildRelease(args, buildPath):
tmpPath = tempfile.mkdtemp(dir=buildPath)
# Build the contents of the distribution folder
buildDistTree(tmpPath, args, isStaticRelease)
buildDistTree(buildPath, tmpPath, args, isStaticRelease)
# Create the DMG image via genisoimage
dmgFile = os.path.join(buildPath, distName + '.dmg')
# genisoimage -o Echo.6.dmg -V Echo -max-iso9660-filenames -hfs-unlock -uid 501 -guid 80 -r -apple ../test/tmp8eGdme/
cmd = ['genisoimage', '-o', dmgFile, '-quiet', '-V', appName, '-max-iso9660-filenames', '-hfs-unlock', '-uid', '501', '-gid', '80', '-r', '-D', '-apple', tmpPath]
# cmd = ['genisoimage', '-o', dmgFile, '-quiet', '-V', appName, '-max-iso9660-filenames', '-hfs-unlock', '-uid', '501', '-gid', '80', '-r', '-D', '-apple', tmpPath]
cmd = ['genisoimage', '-o', dmgFile, '-quiet', '-V', appName, '-max-iso9660-filenames', '-hfs-unlock', '-D', '-r', '-apple', tmpPath]
subprocess.call(cmd, stderr=subprocess.STDOUT)
# Perform cleanup: Remove the tmp folder
@@ -108,14 +109,12 @@ def buildRelease(args, buildPath):
# os.rmdir(tmpPath)
def buildDistTree(rootPath, args, isStaticRelease):
def buildDistTree(buildPath, rootPath, args, isStaticRelease):
# Retrieve vars of interest
appInstallRoot = miscUtils.getInstallRoot()
appInstallRoot = os.path.dirname(appInstallRoot)
appTemplatePath = os.path.join(appInstallRoot, 'template')
appName = args.name
dataCodeList = args.dataCode
javaCodePath = args.javaCode
bgFile = args.bgFile
icnsFile = args.icnsFile
@@ -152,24 +151,25 @@ def buildDistTree(rootPath, args, isStaticRelease):
srcPath = os.path.join(appTemplatePath, 'apple', 'PkgInfo')
dstPath = os.path.join(rootPath, appName + '.app', 'Contents')
shutil.copy(srcPath, dstPath)
# Determine the payloadPath for where to store the appLauncher
payloadPath = os.path.join(rootPath, appName + '.app', 'Contents')
if isStaticRelease == False:
payloadPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources')
# Form the app contents folder
srcPath = os.path.join(buildPath, "delta")
dstPath = os.path.join(payloadPath, 'app')
shutil.copytree(srcPath, dstPath, symlinks=True)
# Setup the launcher contents
exePath = os.path.join(payloadPath, 'Java')
srcPath = os.path.join(appInstallRoot, "template/appLauncher.jar")
os.makedirs(exePath)
shutil.copy(srcPath, exePath);
# Copy the dataCode to the proper location
for aPath in dataCodeList:
srcPath = aPath
dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources')
dstPath = os.path.join(dstPath, os.path.basename(aPath))
shutil.copytree(srcPath, dstPath, symlinks=True)
# Build the java component of the distribution
if javaCodePath != None:
# Copy the javaCode to the proper location
srcPath = javaCodePath
if isStaticRelease == True:
dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Java')
else:
dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Resources', 'Java')
shutil.copytree(srcPath, dstPath, symlinks=True)
if args.javaCode != None:
# Form the Info.plist file
dstPath = os.path.join(rootPath, appName + '.app', 'Contents', 'Info.plist')
if isStaticRelease == True:
@@ -255,17 +255,19 @@ def buildPListInfoShared(destFile, args):
if args.icnsFile != None:
icnsStr = os.path.basename(args.icnsFile)
classPathStr = ''
for aStr in args.classPath:
classPathStr += '$JAVAROOT/' + aStr + ':'
if len(classPathStr) > 0:
classPathStr = classPathStr[0:-1]
classPathStr = '$JAVAROOT/appLauncher.jar'
# classPathStr = ''
# for aStr in args.classPath:
# classPathStr += '$JAVAROOT/' + aStr + ':'
# if len(classPathStr) > 0:
# classPathStr = classPathStr[0:-1]
jvmArgsStr = ''
for aStr in args.jvmArgs:
if len(aStr) > 2 and aStr[0:1] == '\\':
aStr = aStr[1:]
jvmArgsStr += aStr + ' '
jvmArgsStr += '-Djava.system.class.loader=appLauncher.RootClassLoader'
f = open(destFile, 'wb')
writeln(f, 0, '<?xml version="1.0" encoding="UTF-8" standalone="no"?>')
@@ -295,13 +297,11 @@ def buildPListInfoShared(destFile, args):
tupList = []
tupList.append(('JVMVersion', '1.6+'))
tupList.append(('MainClass', args.mainClass))
tupList.append(('MainClass', 'appLauncher.AppLauncher'))
tupList.append(('WorkingDirectory', '$APP_PACKAGE/Contents/Resources/Java'))
tupList.append(('ClassPath', classPathStr))
tupList.append(('VMOptions', jvmArgsStr))
for (key,val) in tupList:
writeln(f, 3, '<key>' + key + '</key>')
writeln(f, 3, '<string>' + str(val) + '</string>')
@@ -309,8 +309,8 @@ def buildPListInfoShared(destFile, args):
writeln(f, 3, '<key>Arguments</key>')
writeln(f, 3, '<array>')
for aStr in args.appArgs:
writeln(f, 4, '<string>' + aStr + '</string>')
# for aStr in args.appArgs:
# writeln(f, 4, '<string>' + aStr + '</string>')
writeln(f, 3, '</array>')
writeln(f, 2, '</dict>')
writeln(f, 1, '</dict>')
@@ -324,18 +324,13 @@ def buildPListInfoStatic(destFile, args):
if args.icnsFile != None:
icnsStr = os.path.basename(args.icnsFile)
classPathStr = ''
for aStr in args.classPath:
classPathStr += '$JAVAROOT/' + aStr + ':'
if len(classPathStr) > 0:
classPathStr = classPathStr[0:-1]
classPathStr = '$JAVAROOT/appLauncher.jar'
# classPathStr = ''
# for aStr in args.classPath:
# classPathStr += '$JAVAROOT/' + aStr + ':'
# if len(classPathStr) > 0:
# classPathStr = classPathStr[0:-1]
jvmArgsStr = ''
for aStr in args.jvmArgs:
if len(aStr) > 2 and aStr[0:1] == '\\':
aStr = aStr[1:]
jvmArgsStr += aStr + ' '
f = open(destFile, 'wb')
writeln(f, 0, '<?xml version="1.0" ?>')
writeln(f, 0, '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">')
@@ -357,14 +352,33 @@ def buildPListInfoStatic(destFile, args):
tupList.append(('NSHumanReadableCopyright', ''))
tupList.append(('JVMRuntime', jreRelease))
tupList.append(('JVMMainClassName', args.mainClass))
tupList.append(('JVMMainClassName', 'appLauncher.AppLauncher'))
# Application configuration
for (key,val) in tupList:
writeln(f, 2, '<key>' + key + '</key>')
writeln(f, 2, '<string>' + str(val) + '</string>')
# JVM options
writeln(f, 2, '<key>JVMOptions</key>')
writeln(f, 3, '<array>')
for aStr in args.jvmArgs:
writeln(f, 4, '<string>' + aStr + '</string>')
writeln(f, 4, '<string>-Dapple.laf.useScreenMenuBar=true</string>')
writeln(f, 4, '<string>-Dcom.apple.macos.use-file-dialog-packages=true</string>')
writeln(f, 4, '<string>-Dcom.apple.macos.useScreenMenuBar=true</string>')
writeln(f, 4, '<string>-Djava.system.class.loader=appLauncher.RootClassLoader</string>')
writeln(f, 3, '</array>')
# # App arguments
# writeln(f, 2, '<key>JVMArguments</key>')
# writeln(f, 3, '<array>')
# for aStr in args.appArgs:
# writeln(f, 4, '<string>' + args + '</string>')
# writeln(f, 3, '</array>')
# JVM configuration
writeln(f, 2, '<key>Java</key>')
writeln(f, 2, '<dict>')
@@ -374,20 +388,11 @@ def buildPListInfoStatic(destFile, args):
# tupList.append(('MainClass', args.mainClass))
# tupList.append(('WorkingDirectory', '$APP_PACKAGE/Contents/Resources/Java'))
tupList.append(('ClassPath', classPathStr))
tupList.append(('JVMOptions', jvmArgsStr))
for (key,val) in tupList:
writeln(f, 3, '<key>' + key + '</key>')
writeln(f, 3, '<string>' + str(val) + '</string>')
writeln(f, 3, '<key>Arguments</key>')
writeln(f, 3, '<array>')
for aStr in args.appArgs:
writeln(f, 4, '<string>' + aStr + '</string>')
writeln(f, 3, '</array>')
writeln(f, 2, '</dict>')
writeln(f, 1, '</dict>')
writeln(f, 0, '</plist>')

View File

@@ -135,10 +135,9 @@ if __name__ == "__main__":
# Build the Delta (diffs) contents
deltaCodePath = os.path.join(buildPath, "delta/code")
deltaDataPath = os.path.join(buildPath, "delta/data")
os.makedirs(deltaCodePath)
os.makedirs(deltaDataPath)
# Copy the dataCode to the delta location
os.makedirs(deltaDataPath)
for aPath in args.dataCode:
srcPath = aPath
dstPath = os.path.join(deltaDataPath, os.path.basename(aPath))
@@ -148,11 +147,16 @@ if __name__ == "__main__":
if args.javaCode != None:
# Copy the javaCode to the proper location
srcPath = args.javaCode
dstPath = os.path.join(deltaCodePath, 'java')
dstPath = deltaCodePath;
# dstPath = os.path.join(deltaCodePath, 'java')
shutil.copytree(srcPath, dstPath, symlinks=True)
# Form the app.cfg file
dstPath = os.path.join(buildPath, "delta/app.cfg")
miscUtils.buildAppLauncherConfig(dstPath, args)
# Build the delta catalog
destPath = os.path.join(buildPath, "delta")
# Build the delta catalog md5sum
# dstPath = os.path.join(buildPath, "delta/md5sum.txt")
# buildCatalog.buildCatalog(destPath)
# Build the Apple release
@@ -164,3 +168,7 @@ if __name__ == "__main__":
# Build the Windows release
windowsUtils.buildRelease(args, buildPath)
# Copy over the deploy script
srcPath = os.path.join(miscUtils.getInstallRoot(), "deployDist.py")
shutil.copy(srcPath, buildPath)

148
script/deployDist.py Executable file
View File

@@ -0,0 +1,148 @@
#! /usr/bin/env python
import argparse
import datetime
import getpass
import math
import os
import shutil
import signal
import subprocess
import sys
def getDistInfo(distPath):
appName = None
version = None
cfgFile = os.path.join(distPath, 'delta', 'app.cfg')
if os.path.isfile(cfgFile) == False:
print('Distribution corresponding to the folder: ' + distPath + ' does not appear to be valid!')
print('Release will not be deployed...')
exit()
isNameMode = isVerMode = False
f = open(cfgFile, 'r')
for line in f:
line = line[:-1]
if line == '-name':
isNameMode = True
isVerMode = False
elif line == '-version':
isNameMode = False
isVerMode = True
elif line.startswith('-') == True:
isNameMode = False
isVerMode = False
elif isNameMode == True and len(line) > 0:
appName = line
elif isVerMode == True and len(line) > 0:
version = line
f.close()
if appName == None or version == None:
print('Distribution corresponding to the folder: ' + distPath + ' does not appear to be valid!')
print('The configuration file, ' + cfgFile+ ', is not valid.')
print('Release will not be made for app ' + appName)
exit()
return (appName, version)
def handleSignal(signal, frame):
"""Signal handler, typically used to capture ctrl-c."""
print('User aborted processing!')
sys.exit(0)
def updateVersionInfo(installPath, appName, version):
verFile = os.path.join(installPath, 'versionInfo.txt')
versionInfo = []
# Read the file
if os.path.isfile(verFile) == True:
f = open(verFile, 'r')
for line in f:
tokens = line[:-1].split(',', 1);
if len(tokens) == 2 and tokens[0] != 'name':
versionInfo.append((tokens[0], tokens[1]))
f.close()
# Record the new version
exeDate = datetime.date.today()
dateStamp = exeDate.strftime('%Y%b%d')
versionInfo.append((dateStamp, version))
# Write the updated file
f = open(verFile, 'w')
f.write('name' + ',' + appName + '\n')
for verTup in versionInfo:
f.write(verTup[0] + ',' + verTup[1] + '\n')
f.close()
if __name__ == "__main__":
argv = sys.argv;
argc = len(argv);
# Logic to capture Ctrl-C and bail
signal.signal(signal.SIGINT, handleSignal)
# Retrive the location of the scriptPath
scriptPath = os.path.realpath(__file__)
scriptPath = os.path.dirname(scriptPath)
# Set up the argument parser
parser = argparse.ArgumentParser(prefix_chars='-', add_help=False, fromfile_prefix_chars='@')
parser.add_argument('-help', '-h', help='Show this help message and exit.', action='help')
parser.add_argument('rootLoc', help='Root location to deploy the specified distribution.')
parser.add_argument('distLoc', nargs='?', default=scriptPath, help='The location of the distribution to deploy.')
# Intercept any request for a help message and bail
for aArg in argv:
if aArg == '-h' or aArg == '-help':
parser.print_help()
exit()
# Parse the args
parser.formatter_class.max_help_position = 50
args = parser.parse_args()
distPath = args.distLoc
rootPath = args.rootLoc
# Retrieve the distPath and ensure that it exists
if os.path.isdir(distPath) == False:
print('Distribution corresponding to the folder: ' + distPath + ' does not exist!')
print('Release will not be deployed...')
exit()
# Determine the appName and version of the distribution
(appName, version) = getDistInfo(distPath)
# Check to see if the deployed location already exists
installPath = os.path.join(rootPath, appName)
if os.path.isdir(installPath) == False:
print('Application ' + appName + ' has never been deployed to the root location: ' + args.rootLoc)
print('Create a new release of the application at the specified location?')
input = raw_input('--> ').upper()
if input != 'Y' and input != 'YES':
print('Release will not be made for app ' + appName)
exit()
# Build the deployed location
os.makedirs(installPath)
# Check to see if the deploy version already exists
versionPath = os.path.join(installPath, version)
if os.path.isdir(versionPath) == True:
print('Application ' + appName + ' with version, ' + version + ', has already been deployed.')
print('Release will not be made for app ' + appName)
exit()
# Copy over the contents of the release folder to the deploy location
shutil.copytree(distPath, versionPath, symlinks=True)
# Update the version info
updateVersionInfo(installPath, appName, version)

View File

@@ -42,7 +42,7 @@ def buildRelease(args, buildPath):
os.mkdir(dstPath)
# Build the contents of the distribution folder
buildDistTree(dstPath, args, isStaticRelease)
buildDistTree(buildPath, dstPath, args, isStaticRelease)
# Create the tar.gz archive
tarFile = os.path.join(buildPath, distName + '.tar.gz')
@@ -55,56 +55,43 @@ def buildRelease(args, buildPath):
shutil.rmtree(tmpPath)
def buildDistTree(rootPath, args, isStaticRelease):
def buildDistTree(buildPath, rootPath, args, isStaticRelease):
# Retrieve vars of interest
appInstallRoot = miscUtils.getInstallRoot()
appInstallRoot = os.path.dirname(appInstallRoot)
appName = args.name
dataCodeList = args.dataCode
javaCodePath = args.javaCode
# Copy the dataCode to the proper location
for aPath in dataCodeList:
srcPath = aPath
dstPath = os.path.join(rootPath, os.path.basename(aPath))
shutil.copytree(srcPath, dstPath, symlinks=True)
# Form the app contents folder
srcPath = os.path.join(buildPath, "delta")
dstPath = os.path.join(rootPath, "app")
shutil.copytree(srcPath, dstPath, symlinks=True)
# Setup the launcher contents
exePath = os.path.join(rootPath, "launcher")
srcPath = os.path.join(appInstallRoot, "template/appLauncher.jar")
os.makedirs(exePath)
shutil.copy(srcPath, exePath);
# Build the java component of the distribution
if javaCodePath != None:
# Copy the javaCode to the proper location
srcPath = javaCodePath
dstPath = os.path.join(rootPath, 'java')
shutil.copytree(srcPath, dstPath, symlinks=True)
if args.javaCode != None:
# Copy over the jre
if isStaticRelease == True:
srcPath = os.path.join(appInstallRoot, 'jre', 'linux', jreRelease)
dstPath = os.path.join(rootPath, os.path.basename(srcPath))
shutil.copytree(srcPath, dstPath, symlinks=True)
# Form the executable bash script
dstPath = os.path.join(rootPath, 'run' + appName)
buildBashScript(dstPath, args, isStaticRelease)
def buildBashScript(destFile, args, isStaticRelease):
classPathStr = ''
for aStr in args.classPath:
classPathStr += 'java/' + aStr + ':'
if len(classPathStr) > 0:
classPathStr = classPathStr[0:-1]
jvmArgsStr = ''
for aStr in args.jvmArgs:
if len(aStr) > 2 and aStr[0:1] == '\\':
aStr = aStr[1:]
jvmArgsStr += aStr + ' '
appArgsStr = ''
for aStr in args.appArgs:
appArgsStr += ' ' + aStr
f = open(destFile, 'wb')
f.write('# Get the instalation path\n')
f.write('installPath=$(readlink -f "$BASH_SOURCE")\n')
@@ -113,9 +100,10 @@ def buildBashScript(destFile, args, isStaticRelease):
f.write('# Change the working directory to the installation path\n')
f.write('cd "$installPath"\n\n')
exeCmd = 'java ' + jvmArgsStr + ' -cp ' + classPathStr + ' ' + args.mainClass + appArgsStr
exeCmd = 'java ' + jvmArgsStr
if isStaticRelease == True:
exeCmd = jreRelease + '/bin/java ' + jvmArgsStr + ' -cp ' + classPathStr + ' ' + args.mainClass + appArgsStr
exeCmd = jreRelease + '/bin/java ' + jvmArgsStr
exeCmd = exeCmd + ' -Djava.system.class.loader=appLauncher.RootClassLoader -cp launcher/appLauncher.jar appLauncher.AppLauncher app/app.cfg'
f.write('# Run the application\n')
f.write(exeCmd + '\n')

View File

@@ -55,3 +55,52 @@ def isJreAvailable(systemName, jreRelease):
srcPath = os.path.join(appInstallRoot, 'jre', systemName, jreRelease)
return os.path.isdir(srcPath)
def buildAppLauncherConfig(destFile, args):
classPathStr = ''
for aStr in args.classPath:
classPathStr += 'java/' + aStr + ':'
if len(classPathStr) > 0:
classPathStr = classPathStr[0:-1]
jvmArgsStr = ''
for aStr in args.jvmArgs:
if len(aStr) > 2 and aStr[0:1] == '\\':
aStr = aStr[1:]
jvmArgsStr += aStr + ' '
appArgsStr = ''
for aStr in args.appArgs:
appArgsStr += ' ' + aStr
f = open(destFile, 'wb')
# App name section
f.write('-name\n')
f.write(args.name + '\n')
f.write('\n')
# Version section
f.write('-version\n')
f.write(args.version + '\n')
f.write('\n')
# MainClass section
f.write('-mainClass\n')
f.write(args.mainClass + '\n')
f.write('\n')
# ClassPath section
f.write('-classPath\n')
for aStr in args.classPath:
f.write(aStr + '\n')
f.write('\n')
# Application args section
f.write('-appArgs\n')
for aStr in args.appArgs:
f.write(aStr + '\n')
f.write('\n')
f.close()

View File

@@ -42,7 +42,7 @@ def buildRelease(args, buildPath):
os.mkdir(dstPath)
# Build the contents of the distribution folder
buildDistTree(dstPath, args, isStaticRelease)
buildDistTree(buildPath, dstPath, args, isStaticRelease)
# Create the zip file
zipFile = os.path.join(buildPath, distName + ".zip")
@@ -52,33 +52,31 @@ def buildRelease(args, buildPath):
shutil.rmtree(tmpPath)
def buildDistTree(rootPath, args, isStaticRelease):
def buildDistTree(buildPath, rootPath, args, isStaticRelease):
# Retrieve vars of interest
appInstallRoot = miscUtils.getInstallRoot()
appInstallRoot = os.path.dirname(appInstallRoot)
appName = args.name
dataCodeList = args.dataCode
javaCodePath = args.javaCode
# Copy the dataCode to the proper location
for aPath in dataCodeList:
srcPath = aPath
dstPath = os.path.join(rootPath, os.path.basename(aPath))
shutil.copytree(srcPath, dstPath, symlinks=True)
# Form the app contents folder
srcPath = os.path.join(buildPath, "delta")
dstPath = os.path.join(rootPath, "app")
shutil.copytree(srcPath, dstPath, symlinks=True)
# Setup the launcher contents
exePath = os.path.join(rootPath, "launcher")
srcPath = os.path.join(appInstallRoot, "template/appLauncher.jar")
os.makedirs(exePath)
shutil.copy(srcPath, exePath);
# Build the java component of the distribution
if javaCodePath != None:
# Copy the javaCode to the proper location
srcPath = javaCodePath
dstPath = os.path.join(rootPath, 'java')
shutil.copytree(srcPath, dstPath, symlinks=True)
if args.javaCode != None:
# Copy over the jre
if isStaticRelease == True:
srcPath = os.path.join(appInstallRoot, 'jre', 'windows', jreRelease)
dstPath = os.path.join(rootPath, os.path.basename(srcPath))
shutil.copytree(srcPath, dstPath, symlinks=True)
# Generate the iconFile
winIconFile = None
origIconFile = args.iconFile
@@ -98,7 +96,7 @@ def buildDistTree(rootPath, args, isStaticRelease):
# Build the windows executable
launch4jExe = os.path.join(appInstallRoot, "launch4j", "launch4j")
subprocess.check_call([launch4jExe, configFile], stderr=subprocess.STDOUT)
print(launch4jExe + ' ' + configFile)
# print(launch4jExe + ' ' + configFile)
# Perform cleanup
os.remove(configFile)
@@ -106,16 +104,6 @@ def buildDistTree(rootPath, args, isStaticRelease):
os.remove(winIconFile)
def buildLaunch4JConfig(destFile, args, isStaticRelease, iconFile):
classPathStr = ''
for aStr in args.classPath:
classPathStr += 'java/' + aStr + ':'
if len(classPathStr) > 0:
classPathStr = classPathStr[0:-1]
appArgsStr = ''
for aStr in args.appArgs:
appArgsStr += ' ' + aStr
f = open(destFile, 'wb')
writeln(f, 0, "<launch4jConfig>")
@@ -127,8 +115,7 @@ def buildLaunch4JConfig(destFile, args, isStaticRelease, iconFile):
writeln(f, 1, "<downloadUrl>http://java.com/download</downloadUrl>");
# writeln(f, 1, "<supportUrl>url</supportUrl>");
if len(appArgsStr) > 0:
writeln(f, 1, "<cmdLine>" + appArgsStr + "</cmdLine>");
writeln(f, 1, "<cmdLine>app/app.cfg</cmdLine>");
writeln(f, 1, "<chdir>.</chdir>");
writeln(f, 1, "<priority>normal</priority>");
writeln(f, 1, "<customProcName>true</customProcName>");
@@ -137,9 +124,8 @@ def buildLaunch4JConfig(destFile, args, isStaticRelease, iconFile):
writeln(f, 1, "<icon>" + iconFile + "</icon>");
writeln(f, 1, "<classPath>");
writeln(f, 2, "<mainClass>" + args.mainClass + "</mainClass>");
for aClassPath in args.classPath:
writeln(f, 2, "<cp>" + 'java/' + aClassPath + "</cp>");
writeln(f, 2, "<mainClass>appLauncher.AppLauncher</mainClass>");
writeln(f, 2, "<cp>launcher/appLauncher.jar</cp>");
writeln(f, 1, "</classPath>");
if args.forceSingleInstance != False:
@@ -159,6 +145,7 @@ def buildLaunch4JConfig(destFile, args, isStaticRelease, iconFile):
writeln(f, 2, "<jdkPreference>preferJre</jdkPreference>");
for aJvmArg in args.jvmArgs:
writeln(f, 2, "<opt>" + aJvmArg + "</opt>");
writeln(f, 2, "<opt>-Djava.system.class.loader=appLauncher.RootClassLoader</opt>");
writeln(f, 1, "</jre>");
writeln(f, 0, "");