JAL-1929 JAL-3224 java 8 and java 11 specific getdown jre sets
[jalview.git] / build.gradle
1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3
4 buildscript {
5   dependencies {
6         classpath 'org.openclover:clover:4.3.1'
7         classpath 'org.apache.commons:commons-compress:1.18'
8   }
9 }
10
11 plugins {
12   id 'java'
13   id 'application'
14   id 'com.github.johnrengelman.shadow' version '4.0.3'
15   id 'com.install4j.gradle' version '7.0.9'
16 }
17
18 repositories {
19   jcenter()
20   mavenCentral()
21   mavenLocal()
22   flatDir {
23     dirs gradlePluginsDir
24   }
25 }
26
27 mainClassName = launcherClass
28 def cloverInstrDir = file("$buildDir/$cloverSourcesInstrDir")
29 def classes = "$jalviewDir/$classesDir"
30 if (clover.equals("true")) {
31   use_clover = true
32   classes = "$buildDir/$cloverClassesDir"
33 } else {
34   use_clover = false
35   classes = "$jalviewDir/$classesDir"
36 }
37
38 // configure classpath/args for j8/j11 compilation
39
40 def libDir
41 def libDistDir
42 def compile_source_compatibility
43 def compile_target_compatibility
44 def additional_compiler_args = []
45 // these are getdown.txt properties defined dependent on the JAVA_VERSION 
46 def getdown_alt_java_min_version
47 // this property is assigned below and expanded to multiple lines in the getdown task
48 def getdown_alt_multi_java_location
49 if (JAVA_VERSION.equals("1.8")) {
50   libDir = j11libDir
51   libDistDir = j8libDir
52   compile_source_compatibility = 1.8
53   compile_target_compatibility = 1.8
54   getdown_alt_java_min_version = getdown_alt_java8_min_version
55   getdown_alt_multi_java_location = getdown_alt_java8_txt_multi_java_location
56 } else if (JAVA_VERSION.equals("11")) {
57   libDir = j11libDir
58   libDistDir = j11libDir
59   compile_source_compatibility = 11
60   compile_target_compatibility = 11
61   getdown_alt_java_min_version = getdown_alt_java11_min_version
62   getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
63   additional_compiler_args += [
64     '--module-path', file("$jalviewDir/$j11modDir").getAbsolutePath(),
65     '--add-modules', j11modules
66   ]
67 } else {
68   throw new GradleException("JAVA_VERSION=$JAVA_VERSION not currently supported by Jalview")
69 }
70
71 sourceSets {
72
73   main {
74     java {
75       srcDirs "$jalviewDir/$sourceDir"
76       outputDir = file("$classes")
77     }
78
79     resources {
80       srcDirs "$jalviewDir/$resourceDir"
81       srcDirs "$jalviewDir/$libDistDir"
82     }
83
84     jar.destinationDir = file("$jalviewDir/$packageDir")
85
86     compileClasspath = files(sourceSets.main.java.outputDir)
87     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
88
89     runtimeClasspath = compileClasspath
90   }
91   
92   clover {
93     java {
94         srcDirs = [ cloverInstrDir ]
95         outputDir = file("${buildDir}/${cloverClassesDir}")
96     }
97     
98     resources {
99       srcDirs = sourceSets.main.resources.srcDirs
100     }
101     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
102     compileClasspath += fileTree(dir: "$jalviewDir/$utilsDir", include: ["**/*.jar"])
103     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
104
105     runtimeClasspath = compileClasspath
106   }
107   
108   test {
109     java {
110       srcDirs "$jalviewDir/$testSourceDir"
111       outputDir = file("$jalviewDir/$testOutputDir")
112     }
113
114     resources {
115       srcDirs = sourceSets.main.resources.srcDirs
116     }
117
118     compileClasspath = files( sourceSets.test.java.outputDir ) 
119     if (use_clover) {
120       compileClasspath += sourceSets.clover.compileClasspath
121     } else {
122       compileClasspath += sourceSets.main.compileClasspath
123       compileClasspath += files(sourceSets.main.java.outputDir)
124     }
125     compileClasspath += files( sourceSets.main.resources.srcDirs)
126     compileClasspath += fileTree(dir: "$jalviewDir/$utilsDir", include: ["**/*.jar"])
127     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
128
129     runtimeClasspath = compileClasspath
130   }
131 }
132
133 // clover bits
134 dependencies {
135   if (use_clover) {
136     cloverCompile 'org.openclover:clover:4.3.1'
137     testCompile 'org.openclover:clover:4.3.1'
138   }
139 }
140
141 configurations {
142     cloverRuntime
143     cloverRuntime.extendsFrom cloverCompile
144 }
145  
146 task cloverInstr() {
147   // only instrument source, we build test classes as normal
148     inputs.files files (sourceSets.main.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
149     outputs.dir cloverInstrDir
150
151     doFirst {
152         delete cloverInstrDir
153         def argsList = ["--initstring", "${buildDir}/clover/clover.db",
154                         "-d", "${buildDir}/${cloverSourcesInstrDir}"]
155         argsList.addAll(inputs.files.files.collect({ file ->
156             file.absolutePath
157         }))
158         String[] args = argsList.toArray()
159         println("About to instrument "+args.length +" files")
160         com.atlassian.clover.CloverInstr.mainImpl(args)
161     }
162 }
163
164  
165 task cloverReport {
166     inputs.dir "${buildDir}/clover"
167     outputs.dir "${reportsDir}/clover"
168     onlyIf {
169         file("${buildDir}/clover/clover.db").exists()
170     }
171     doFirst {
172         def argsList = ["--initstring", "${buildDir}/clover/clover.db",
173                         "-o", "${reportsDir}/clover"]
174         String[] args = argsList.toArray()
175         com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
176         
177         // and generate ${reportsDir}/clover/clover.xml
178         args = ["--initstring", "${buildDir}/clover/clover.db",
179                         "-o", "${reportsDir}/clover/clover.xml"].toArray()
180         com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
181     }
182 }
183
184 // end clover bits
185
186
187 compileJava {
188
189   doFirst {
190     sourceCompatibility = compile_source_compatibility
191     targetCompatibility = compile_target_compatibility
192     options.compilerArgs = additional_compiler_args
193     print ("Setting target compatibility to "+targetCompatibility+"\n")
194   }
195
196 }
197
198 compileTestJava {
199
200   if (use_clover) {
201     dependsOn compileCloverJava
202     classpath += configurations.cloverRuntime
203   } else {
204     classpath += sourceSets.main.runtimeClasspath
205   }
206   doFirst {
207     sourceCompatibility = compile_source_compatibility
208     targetCompatibility = compile_target_compatibility
209     options.compilerArgs = additional_compiler_args
210     print ("Setting target compatibility to "+targetCompatibility+"\n")
211   }
212 }
213
214
215 compileCloverJava {
216
217   doFirst {
218     sourceCompatibility = compile_source_compatibility
219     targetCompatibility = compile_target_compatibility
220     options.compilerArgs += additional_compiler_args
221     print ("Setting target compatibility to "+targetCompatibility+"\n")
222   }
223   classpath += configurations.cloverRuntime
224 }
225
226 clean {
227   delete sourceSets.main.java.outputDir
228 }
229
230 cleanTest {
231   delete sourceSets.test.java.outputDir
232   delete cloverInstrDir
233 }
234
235 def getDate(format) {
236   def date = new Date()
237   //return date.format("dd MMMM yyyy")
238   return date.format(format)
239 }
240
241 def getGitHash() {
242   def stdout = new ByteArrayOutputStream()
243   exec {
244     commandLine "git", "rev-parse", "--short", "HEAD"
245     standardOutput = stdout
246     workingDir = jalviewDir
247   }
248   return stdout.toString().trim()
249 }
250
251 def getGitBranch() {
252   def stdout = new ByteArrayOutputStream()
253   exec {
254     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
255     standardOutput = stdout
256     workingDir = jalviewDir
257   }
258   return stdout.toString().trim()
259 }
260
261 task createBuildProperties(type: WriteProperties) {
262   inputs.dir("$jalviewDir/$sourceDir")
263   inputs.dir("$jalviewDir/$resourceDir")
264   outputFile "$classes/$buildPropertiesFile"
265   /* taking time/date specific comment out to allow better incremental builds */
266   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
267   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
268   property "BUILD_DATE", getDate("dd MMMM yyyy")
269   property "VERSION", JALVIEW_VERSION
270   property "INSTALLATION", INSTALLATION+" git-commit:"+getGitHash()+" ["+getGitBranch()+"]"
271   outputs.file(outputFile)
272   outputs.dir("$classes")
273 }
274
275 task syncDocs(type: Sync) {
276   def syncDir = "$classes/$docDir"
277   from fileTree("$jalviewDir/$docDir")
278   into syncDir
279
280 }
281
282 def helpFile = "$classes/$helpDir/help.jhm"
283 task syncHelp(type: Sync) {
284   inputs.files("$jalviewDir/$helpDir")
285   outputs.files(helpFile)
286
287   def syncDir = "$classes/$helpDir"
288   from fileTree("$jalviewDir/$helpDir")
289   into syncDir
290 }
291
292 task copyHelp(type: Copy) {
293   def inputDir = "$jalviewDir/$helpDir"
294   def outputDir = "$classes/$helpDir"
295   from inputDir
296   into outputDir
297   filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': "USING_FILTER"])
298   inputs.dir(inputDir)
299   outputs.files(helpFile)
300   outputs.dir(outputDir)
301 }
302
303 task syncLib(type: Sync) {
304   def syncDir = "$classes/$libDistDir"
305   from fileTree("$jalviewDir/$libDistDir")
306   into syncDir
307 }
308
309 task syncResources(type: Sync) {
310   from "$jalviewDir/$resourceDir"
311   include "**/*.*"
312   exclude "install4j"
313   into "$classes"
314   preserve {
315     include "**"
316   }
317 }
318
319 task prepare {
320   dependsOn syncResources
321   dependsOn syncDocs
322   dependsOn copyHelp
323 }
324
325
326 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
327 test {
328   dependsOn prepare
329   dependsOn compileJava
330   if (use_clover) {
331     dependsOn cloverInstr
332   }
333   print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n") 
334   
335   useTestNG() {
336     includeGroups testngGroups
337     preserveOrder true
338     useDefaultListeners=true
339   }
340   
341   workingDir = jalviewDir
342   //systemProperties 'clover.jar' System.properties.clover.jar
343   sourceCompatibility = compile_source_compatibility
344   targetCompatibility = compile_target_compatibility
345   jvmArgs += additional_compiler_args
346   print ("Setting target compatibility to "+targetCompatibility+"\n")
347 }
348
349 task buildIndices(type: JavaExec) {
350   dependsOn copyHelp
351   classpath = sourceSets.main.compileClasspath
352   main = "com.sun.java.help.search.Indexer"
353   workingDir = "$classes/$helpDir"
354   def argDir = "html"
355   args = [ argDir ]
356   inputs.dir("$workingDir/$argDir")
357
358   outputs.dir("$classes/doc")
359   outputs.dir("$classes/help")
360   outputs.file("$workingDir/JavaHelpSearch/DOCS")
361   outputs.file("$workingDir/JavaHelpSearch/DOCS.TAB")
362   outputs.file("$workingDir/JavaHelpSearch/OFFSETS")
363   outputs.file("$workingDir/JavaHelpSearch/POSITIONS")
364   outputs.file("$workingDir/JavaHelpSearch/SCHEMA")
365   outputs.file("$workingDir/JavaHelpSearch/TMAP")
366 }
367
368 task compileLinkCheck(type: JavaCompile) {
369   options.fork = true
370   classpath = files("$jalviewDir/$utilsDir")
371   destinationDir = file("$jalviewDir/$utilsDir")
372   source = fileTree(dir: "$jalviewDir/$utilsDir", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
373
374   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.class")
375   outputs.file("$jalviewDir/$utilsDir/BufferedLineReader.class")
376 }
377
378 task linkCheck(type: JavaExec) {
379   dependsOn prepare, compileLinkCheck
380   classpath = files("$jalviewDir/$utilsDir")
381   main = "HelpLinksChecker"
382   workingDir = jalviewDir
383   def help = "$classes/$helpDir"
384   args = [ "$classes/$helpDir", "-nointernet" ]
385   //args = [ "$classesDir/$helpDir", "-nointernet" ]
386
387   doFirst {
388     standardOutput new FileOutputStream("$jalviewDir/$utilsDir/HelpLinksChecker.out")
389   }
390
391   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.out")
392 }
393
394 task cleanPackageDir(type: Delete) {
395   delete fileTree("$jalviewDir/$packageDir").include("*.jar")
396 }
397
398 jar {
399   dependsOn linkCheck
400   dependsOn buildIndices
401   dependsOn createBuildProperties
402
403   manifest {
404     attributes "Main-Class": mainClass,
405     "Permissions": "all-permissions",
406     "Application-Name": "Jalview Desktop",
407     "Codebase": application_codebase
408   }
409
410   destinationDir = file("$jalviewDir/$packageDir")
411   archiveName = rootProject.name+".jar"
412
413   exclude "cache*/**"
414   exclude "*.jar"
415   exclude "*.jar.*"
416   exclude "**/*.jar"
417   exclude "**/*.jar.*"
418
419   inputs.dir("$classes")
420   outputs.file("$jalviewDir/$packageDir/$archiveName")
421 }
422
423 task copyJars(type: Copy) {
424   from fileTree("$classes").include("**/*.jar").include("*.jar").files
425   into "$jalviewDir/$packageDir"
426 }
427
428 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
429 task syncJars(type: Sync) {
430   from fileTree("$jalviewDir/$libDistDir").include("**/*.jar").include("*.jar").files
431   into "$jalviewDir/$packageDir"
432   preserve {
433     include jar.archiveName
434   }
435 }
436
437 task makeDist {
438   // order of "cleanPackageDir", "copyJars", "jar" important!
439   jar.mustRunAfter cleanPackageDir
440   syncJars.mustRunAfter cleanPackageDir
441   dependsOn cleanPackageDir
442   dependsOn syncJars
443   dependsOn jar
444   outputs.dir("$jalviewDir/$packageDir")
445 }
446
447 task cleanDist {
448   dependsOn cleanPackageDir
449   dependsOn cleanTest
450   dependsOn clean
451 }
452
453 shadowJar {
454   dependsOn makeDist
455   from ("$jalviewDir/$libDistDir") {
456       include("*.jar")
457   }
458   mainClassName = shadowJarMainClass
459   mergeServiceFiles()
460   classifier = "all-"+JAVA_VERSION
461   minimize()
462 }
463
464 ext {
465   // where the getdown channel will be built. 
466   // TODO: consider allowing this expression to  be overrriden by -P arg
467   getdownWebsiteDir = jalviewDir + '/' + getdown_website_dir + '/' + JAVA_VERSION + '/'
468   getdownAppDir = getdownWebsiteDir + '/' + getdown_app_dir
469   getdownJ11libDir = getdownWebsiteDir + '/' + getdown_j11lib_dir
470   getdownResourceDir = getdownWebsiteDir + '/' + getdown_resource_dir
471   getdownLauncher = jalviewDir + '/' + getdown_launcher
472   getdownFilesDir = jalviewDir + '/' + getdown_files_dir
473   getdownLib1 = jalviewDir + '/' + getdown_lib1
474   def getdownChannel = getdown_channel_name
475   if (getdown_channel_name.equals("COMMIT")) {
476     getdownChannel = getGitHash()
477   }
478   getdown_app_base = getdown_channel_base+"/"+getdownChannel+"/"+JAVA_VERSION+"/"
479 }
480
481 task getdownWebsite() {
482   dependsOn makeDist
483   def getdownWebsiteResourceFilenames = []
484   def getdownTextString = ""
485   def getdownResourceDir = project.ext.getdownResourceDir
486   def getdownAppDir = project.ext.getdownAppDir
487   def getdownResourceFilenames = []
488   doFirst {
489     // go through properties looking for getdown_txt_...
490     def props = project.properties.sort { it.key }
491     props.put("getdown_txt_java_min_version", getdown_alt_java_min_version)
492     props.put("getdown_txt_multi_java_location", getdown_alt_multi_java_location)
493     
494     props.put("getdown_txt_appbase", getdown_app_base)
495     props.each{ prop, val ->
496       if (prop.startsWith("getdown_txt_") && val != null) {
497         if (prop.startsWith("getdown_txt_multi_")) {
498           def key = prop.substring(18)
499           val.split(",").each{ v ->
500             def line = key + " = " + v + "\n"
501             getdownTextString += line
502           }
503         } else {
504           // file values rationalised
505           if (val.indexOf('/') > -1) {
506             def r = null
507             if (val.indexOf('/') == 0) {
508               // absolute path
509               r = file(val)
510             } else if (val.indexOf('/') > 0) {
511               // relative path (relative to jalviewDir)
512               r = file( jalviewDir + '/' + val )
513             }
514             if (r.exists()) {
515               val = getdown_resource_dir + '/' + r.getName()
516               getdownWebsiteResourceFilenames += val
517               getdownResourceFilenames += r.getPath()
518             }
519           }
520           def line = prop.substring(12) + " = " + val + "\n"
521           getdownTextString += line
522         }
523       }
524     }
525
526     getdownWebsiteResourceFilenames.each{ filename ->
527       getdownTextString += "resource = "+filename+"\n"
528     }
529     getdownResourceFilenames.each{ filename ->
530       copy {
531         from filename
532         into project.ext.getdownResourceDir
533       }
534     }
535
536     def codeFiles = []
537     makeDist.outputs.files.each{ f ->
538       if (f.isDirectory()) {
539         def files = fileTree(dir: f, include: ["*"]).getFiles()
540         codeFiles += files
541       } else if (f.exists()) {
542         codeFiles += f
543       }
544     }
545     codeFiles.sort().each{f ->
546       def line = "code = " + getdown_app_dir + '/' + f.getName() + "\n"
547       getdownTextString += line
548       copy {
549         from f.getPath()
550         into project.ext.getdownAppDir
551       }
552     }
553
554     if (JAVA_VERSION.equals("11")) {
555       def j11libFiles = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"]).getFiles()
556       j11libFiles.sort().each{f ->
557         def line = "code = " + getdown_j11lib_dir + '/' + f.getName() + "\n"
558         getdownTextString += line
559         copy {
560           from f.getPath()
561           into project.ext.getdownJ11libDir
562         }
563       }
564     }
565
566     getdownTextString += "code = " + file(getdownLauncher).getName() + "\n"
567     getdownTextString += "class = " + mainClass + "\n"
568
569     def getdown_txt = file(project.ext.getdownWebsiteDir + "/getdown.txt")
570     getdown_txt.write(getdownTextString)
571
572     copy {
573       from getdown_txt
574       into project.ext.getdownFilesDir
575     }
576
577     copy {
578       from getdownLauncher
579       into project.ext.getdownWebsiteDir
580     }
581
582     copy {
583       from getdownLauncher
584       into project.ext.getdownFilesDir
585     }
586
587     copy {
588       from getdownLib1
589       into project.ext.getdownFilesDir
590     }
591
592     copy {
593       from getdownLib1
594       into project.ext.getdownWebsiteDir
595     }
596
597     copy {
598       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.background_image')
599       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.error_background')
600       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.progress_image')
601       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.icon')
602       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.mac_dock_icon')
603       into project.ext.getdownFilesDir + '/' + getdown_resource_dir 
604     }
605   }
606
607   inputs.dir(jalviewDir + '/' + packageDir)
608   outputs.dir(project.ext.getdownWebsiteDir)
609   outputs.dir(project.ext.getdownFilesDir)
610 }
611
612 task getdownDigest(type: JavaExec) {
613   dependsOn getdownWebsite
614   classpath = files(jalviewDir + '/' + getdown_core)
615   classpath file(jalviewDir + '/' + getdown_lib1)
616   main = "com.threerings.getdown.tools.Digester"
617   args project.ext.getdownWebsiteDir
618   outputs.file(project.ext.getdownWebsiteDir + '/' + "digest2.txt")
619 }
620
621 task getdown() {
622   dependsOn getdownDigest
623 }
624
625 clean {
626   delete project.ext.getdownWebsiteDir
627   delete project.ext.getdownFilesDir
628 }
629
630 install4j {
631   def install4jHomeDir = "/opt/install4j"
632   def hostname = "hostname".execute().text.trim()
633   if (hostname.equals("jv-bamboo")) {
634     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
635   } else if (OperatingSystem.current().isMacOsX()) {
636     install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
637     if (! file(install4jHomeDir).exists()) {
638       install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
639     }
640   } else if (OperatingSystem.current().isLinux()) {
641     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
642   }
643   installDir = file(install4jHomeDir)
644   mediaTypes = Arrays.asList(install4jMediaTypes.split(","))
645 }
646
647 def install4jConf
648 def macosJavaVMDir
649 def windowsJavaVMDir
650 def install4jDir = "$jalviewDir/$install4jResourceDir"
651 def install4jConfFile = "jalview-installers-java"+JAVA_VERSION+".install4j"
652 install4jConf = "$install4jDir/$install4jConfFile"
653   
654 task copyInstall4jTemplate(type: Copy) {
655   macosJavaVMDir = System.env.HOME+"/buildtools/jre/openjdk-java_vm/macos-jre"+JAVA_VERSION+"/java_vm"
656   windowsJavaVMDir = System.env.HOME+"/buildtools/jre/openjdk-java_vm/windows-jre"+JAVA_VERSION+"/java_vm"
657   from (install4jDir) {
658     include install4jTemplate
659     rename (install4jTemplate, install4jConfFile)
660     filter(ReplaceTokens, beginToken: '', endToken: '', tokens: ['9999999999': JAVA_VERSION])
661     filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['VERSION': JALVIEW_VERSION, 'MACOS_JAVA_VM_DIR': macosJavaVMDir, 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir])
662   }
663   into install4jDir
664   inputs.files("$install4jDir/$install4jTemplate")
665   outputs.files(install4jConf)
666 }
667
668 task installers(type: com.install4j.gradle.Install4jTask) {
669   dependsOn getdown
670   dependsOn copyInstall4jTemplate
671   projectFile = file(install4jConf)
672   println("Using projectFile "+projectFile)
673   variables = [majorVersion: version.substring(2, 11), build: 001]
674   destination = "$jalviewDir/$install4jBuildDir/$JAVA_VERSION"
675   buildSelected = true
676   inputs.dir(project.ext.getdownWebsiteDir)
677   inputs.file(install4jConf)
678   inputs.dir(macosJavaVMDir)
679   inputs.dir(windowsJavaVMDir)
680   outputs.dir("$jalviewDir/$install4jBuildDir/$JAVA_VERSION")
681 }
682
683 clean {
684   delete install4jConf
685 }