# HG changeset patch # User kcr # Date 1524594671 25200 # Tue Apr 24 11:31:11 2018 -0700 # Node ID b2ebcd3e69008eeeafa187a4ac8182beddf55d13 # Parent 091e448a0417e835dc3daceb78a1ed83bca7adff 8198329: Support FX build / test using JDK that doesn't include javafx.* modules Reviewed-by: diff --git a/apps/samples/Ensemble8/build.xml b/apps/samples/Ensemble8/build.xml --- a/apps/samples/Ensemble8/build.xml +++ b/apps/samples/Ensemble8/build.xml @@ -124,7 +124,7 @@ - + @@ -178,25 +178,4 @@ - - - - - - - - - - - - - - - - - diff --git a/build.gradle b/build.gradle --- a/build.gradle +++ b/build.gradle @@ -346,29 +346,6 @@ loadProperties("$projectDir/build.properties") -// Look for stub runtime in either JDK or modular-sdk dir layout - -def String closedCacheStubRuntime = cygpath("$projectDir") + "/../caches/modular-sdk" - -def String jdkStubRuntime = cygpath("$JDK_HOME") - -defineProperty("STUB_RUNTIME", BUILD_CLOSED ? closedCacheStubRuntime : jdkStubRuntime) - -def cachedStub = STUB_RUNTIME.equals(closedCacheStubRuntime) - -if (cachedStub) { - def stubModulesLib = "$STUB_RUNTIME/modules_libs" - defineProperty("MEDIA_STUB", "$stubModulesLib/javafx.media") - defineProperty("WEB_STUB", "$stubModulesLib/javafx.web") -} else { - def libraryStub = IS_WINDOWS ? "$STUB_RUNTIME/bin" : "$STUB_RUNTIME/lib" - - defineProperty("MEDIA_STUB", libraryStub) - defineProperty("WEB_STUB", libraryStub) -} - -defineProperty("UPDATE_STUB_CACHE", (cachedStub ? 'true' : 'false')) - def supplementalPreBuildFile = file("$closedDir/closed-pre-build.gradle"); def supplementalBuildFile = file("$closedDir/closed-build.gradle"); @@ -596,6 +573,62 @@ gradle.taskGraph.useFilter({ task -> !task.name.equals("classes") && !task.name.equals("jar") }) } +// Make sure JDK_HOME/bin/java exists +if (!file(JAVA).exists()) throw new Exception("Missing or incorrect path to 'java': '$JAVA'. Perhaps bad JDK_HOME? $JDK_HOME") +if (!file(JAVAC).exists()) throw new Exception("Missing or incorrect path to 'javac': '$JAVAC'. Perhaps bad JDK_HOME? $JDK_HOME") +if (!file(JAVADOC).exists()) throw new Exception("Missing or incorrect path to 'javadoc': '$JAVADOC'. Perhaps bad JDK_HOME? $JDK_HOME") + +// Determine the verion of Java in JDK_HOME. It looks like this: +// +// $ java -version +// java version "1.7.0_45" +// Java(TM) SE Runtime Environment (build 1.7.0_45-b18) +// Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) +// +// We need to parse the second line +def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream())); +try { + String v = inStream.readLine().trim(); + if (v != null) { + int ib = v.indexOf("full version \""); + if (ib != -1) { + String str = v.substring(ib); + String ver = str.substring(str.indexOf("\"") + 1, str.size() - 1); + + defineProperty("jdkRuntimeVersion", ver) + def jdkVersionInfo = parseJavaVersion(ver) + defineProperty("jdkVersion", jdkVersionInfo[0]) + defineProperty("jdkBuildNumber", jdkVersionInfo[1]) + } + } +} finally { + inStream.close(); +} +if (!project.hasProperty("jdkRuntimeVersion")) throw new Exception("Unable to determine the version of Java in JDK_HOME at $JDK_HOME"); + + +// Determine whether the javafx.* modules are present in the JDK. To do this, +// we will execute "java --list-modules" and search for javafx.base +ext.HAS_JAVAFX_MODULES = false; +def inStream2 = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "--list-modules").start().getInputStream())); +try { + String v; + while ((v = inStream2.readLine()) != null) { + v = v.trim(); + if (v.startsWith("javafx.base")) ext.HAS_JAVAFX_MODULES = true; + } +} finally { + inStream2.close(); +} + +// The HAS_JAVAFX_MODULES flag will be used to determine the mode for building +// and running the applications and tests. +// If HAS_JAVAFX_MODULES is true, then we will build / test javafx modules +// for exporting to a JDK build. If HAS_JAVAFX_MODULES is false, then we will +// build / test a standalone sdk for running with a JDK that does not include +// the javafx modules. + + /** * Fetch/Check that external tools are present for the build. This method * will conditionally download the packages from project defined ivy repositories @@ -757,39 +790,95 @@ List computeLibraryPath(boolean working) { List lp = [] - List modsWithNative = [ 'graphics', 'media', 'web' ] - - // the build/modular-sdk area - def platformPrefix = "" - def modularSdkDirName = "${platformPrefix}modular-sdk" - def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}" - def modulesLibsDir = "${modularSdkDir}/modules_libs" - - modsWithNative.each() { m -> - lp << cygpath("${modulesLibsDir}/javafx.${m}") - } + + if (HAS_JAVAFX_MODULES) { + List modsWithNative = [ 'graphics', 'media', 'web' ] + + // the build/modular-sdk area + def platformPrefix = "" + def bundledSdkDirName = "${platformPrefix}modular-sdk" + def bundledSdkDir = "${rootProject.buildDir}/${bundledSdkDirName}" + def modulesLibsDir = "${bundledSdkDir}/modules_libs" + + modsWithNative.each() { m -> + lp << cygpath("${modulesLibsDir}/javafx.${m}") + } + } else { + def platformPrefix = "" + def standaloneSdkDirName = "${platformPrefix}sdk" + def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}" + def modulesLibName = IS_WINDOWS ? "bin" : "lib" + def modulesLibsDir = "${standaloneSdkDir}/${modulesLibName}" + lp << cygpath("${modulesLibsDir}") + } + return lp } -// Return list with the arguments needed for --patch-module for the provided projects -// used with Java executables ie. tests +// Return list with the arguments needed for --patch-module or --module-path +// for the provided projects. Used with Java executables ie. tests List computePatchModuleArgs(List deps, boolean test, boolean includeJLP) { - List pma = [] - - deps.each {String projname -> - def proj = project(projname) - if (proj.hasProperty("moduleName")) { - File dir; - if (test && proj.sourceSets.hasProperty('shims')) { - dir = file("${rootProject.buildDir}/shims") - } else { - dir = file("${rootProject.buildDir}/modular-sdk/modules") - } - String moduleName = proj.ext.moduleName - String dirpath = cygpath("${dir}/${moduleName}") - pma += "--patch-module=${moduleName}=${dirpath}" - } - } + List pma = [] + + if (HAS_JAVAFX_MODULES) { + deps.each { String projname -> + def proj = project(projname) + if (proj.hasProperty("moduleName")) { + File dir; + if (test && proj.sourceSets.hasProperty('shims')) { + dir = file("${rootProject.buildDir}/shims") + } else { + dir = file("${rootProject.buildDir}/modular-sdk/modules") + } + String moduleName = proj.ext.moduleName + String dirpath = cygpath("${dir}/${moduleName}") + pma += "--patch-module=${moduleName}=${dirpath}" + } + } + } else { + String mp = null + deps.each { String projname -> + def proj = project(projname) + if (proj.hasProperty("moduleName")) { + String moduleName = proj.ext.moduleName + File dir; + if (test && proj.sourceSets.hasProperty('shims')) { + dir = file("${rootProject.buildDir}/shims/${moduleName}") + } else { + dir = file("${rootProject.buildDir}/sdk/lib/${moduleName}.jar") + } + if (mp == null) { + mp = dir.path + } else { + mp = mp + File.pathSeparator + dir.path + } + } + } + + // in some cases like base we could end up with an empty + // path... make sure we don't pass one back + if (mp == null) { + return null + } + + pma += '--module-path' + pma += mp + + String addm = null + deps.each {String projname -> + def proj = project(projname) + if (proj.hasProperty("moduleName") && proj.buildModule) { + if (addm == null) { + addm = proj.moduleName + } else { + addm = addm + "," + proj.moduleName + } + } + } + if (addm != null) { + pma += "--add-modules=${addm}" + } + } if (includeJLP) { pma += "-Djava.library.path=" + computeLibraryPath(true).join(File.pathSeparator) @@ -798,45 +887,70 @@ return pma } -// Return a list containing the --upgrade-module-path +// Return a list containing the --upgrade-module-path or --module-path // used with Javac List computeModulePathArgs(String pname, List deps, boolean test) { - List mpa = [ '--upgrade-module-path' ] - String mp = null - deps.each {String projname -> - def proj = project(projname) - // for a non test set of args, we don't want the current module in the list - // for a test test, we do need it to update what we built - - if (proj.hasProperty("moduleName") && - proj.buildModule && - !(!test && proj.name.equals(pname))) { - File dir; - if (test && proj.sourceSets.hasProperty('shims')) { - dir = new File(proj.sourceSets.shims.java.outputDir, proj.ext.moduleName); - } else { - dir = new File(proj.sourceSets.main.java.outputDir, proj.ext.moduleName); - } - if (mp == null) { - mp = dir.path - } else { - mp = mp + File.pathSeparator + dir.path - } - } - } - - // in some cases like base we could end up with an empty - // path... make sure we don't pass one back - if (mp == null) { - return null - } - - mpa += mp - return mpa + List mpa = HAS_JAVAFX_MODULES ? [ '--upgrade-module-path' ] : [ '--module-path' ] + String mp = null + deps.each { String projname -> + def proj = project(projname) + // for a non test set of args, we don't want the current module in the list + // for a test test, we do need it to update what we built + + if (proj.hasProperty("moduleName") && + proj.buildModule && + !(!test && proj.name.equals(pname))) { + + File dir; + if (test && proj.sourceSets.hasProperty('shims')) { + dir = new File(proj.sourceSets.shims.java.outputDir, proj.ext.moduleName); + } else { + dir = new File(proj.sourceSets.main.java.outputDir, proj.ext.moduleName); + } + if (mp == null) { + mp = dir.path + } else { + mp = mp + File.pathSeparator + dir.path + } + } + } + + // in some cases like base we could end up with an empty + // path... make sure we don't pass one back + if (mp == null) { + return null + } + + mpa += mp + + if (!HAS_JAVAFX_MODULES) { + String addm = null + deps.each {String projname -> + def proj = project(projname) + // for a non test set of args, we don't want the current module in the list + // for a test test, we do need it to update what we built + + if (proj.hasProperty("moduleName") && + proj.buildModule && + !(!test && proj.name.equals(pname))) { + + if (addm == null) { + addm = proj.moduleName + } else { + addm = addm + "," + proj.moduleName + } + } + } + if (addm != null) { + mpa += "--add-modules=${addm}" + } + } + + return mpa } -void writeRunArgsFile(File dest, List libpath, List modpath) { +void writeRunArgsFile(File dest, List libpath, List modpath, List modules) { dest.delete() @@ -853,16 +967,60 @@ dest << " \"\n" } - modpath.each { e -> - dest << "--patch-module=\"" - dest << e - dest << "\"\n" + if (HAS_JAVAFX_MODULES) { + modpath.each { e -> + dest << "--patch-module=\"" + dest << e + dest << "\"\n" + } + } else { + if (modpath.size() == 1) { + dest << "--module-path=\"" + dest << modpath[0] + dest << "\"\n" + } else { + dest << "--module-path=\"\\\n" + modpath.each() { e-> + dest << " " + dest << e + dest << File.pathSeparator + dest << "\\\n" + } + dest << " \"\n" + } + } + + if (modules != null) { + dest << "--add-modules=" + dest << modules.join(",") + dest << "\n" + } +} + +void appendQualExports(File dest, List qualExports) { + qualExports.each { exp -> + dest << exp + dest << "\n" + } +} + +// TODO KCR: remove this before final webrev +void printArgs(String msg, List val) { + println "" + println msg + val.each { s -> + println " $s" } } // perform common project manipulation for modules void commonModuleSetup(Project p, List moduleChain) { + println "" + println "---------------------------------------------------" + println "$p" + println "" + p.ext.moduleChain = moduleChain if (p.hasProperty("moduleName")) { @@ -875,12 +1033,19 @@ def mpa = computeModulePathArgs(p.name, moduleChain, false) if (mpa != null) { p.ext.modulePathArgs = mpa + printArgs("modulePathArgs", p.ext.modulePathArgs); + } else { + println("modulePathArgs = null") } p.ext.testModulePathArgs = computePatchModuleArgs(moduleChain, true, false) p.ext.patchModuleArgs = computePatchModuleArgs(moduleChain ,false, true) p.ext.testPatchModuleArgs = computePatchModuleArgs(moduleChain, true, true) + printArgs("testModulePathArgs", p.ext.testModulePathArgs); + printArgs("patchModuleArgs", p.ext.patchModuleArgs); + printArgs("testPatchModuleArgs", p.ext.testPatchModuleArgs); + moduleChain.each() {e -> if (!e.equals(p.name)) { p.compileJava.dependsOn(project(e).classes) @@ -936,11 +1101,13 @@ rootProject.ext.EXTRA_ADDEXPORTS_ARGS = extraAddExportsList } - // use this variable, because it shows we have a non empty addition - if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { - p.ext.extraAddExports = EXTRA_ADDEXPORTS_ARGS.flatten() - if (p.hasProperty("testAddExports")) { - p.testAddExports += EXTRA_ADDEXPORTS_ARGS.flatten() + if (HAS_JAVAFX_MODULES) { + // use this variable, because it shows we have a non empty addition + if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { + p.ext.extraAddExports = EXTRA_ADDEXPORTS_ARGS.flatten() + if (p.hasProperty("testAddExports")) { + p.testAddExports += EXTRA_ADDEXPORTS_ARGS.flatten() + } } } } @@ -1007,7 +1174,7 @@ if (targetProperties.compileSwing) COMPILE_SWING = true if (targetProperties.compileSWT) COMPILE_SWT = true - if (IS_BUILD_FXPACKAGER && targetProperties.compileFXPackager) COMPILE_FXPACKAGER = true + if (IS_BUILD_FXPACKAGER && HAS_JAVAFX_MODULES && targetProperties.compileFXPackager) COMPILE_FXPACKAGER = true if (!targetProperties.containsKey('compileWebnodeNative')) { // unless specified otherwise, we will compile native Webnode if IS_COMPILE_WEBKIT @@ -1056,54 +1223,6 @@ throw new Exception("Unable to determine compilation platform, must specify valid COMPILE_TARGETS!") } -// Make sure JDK_HOME/bin/java exists -if (!file(JAVA).exists()) throw new Exception("Missing or incorrect path to 'java': '$JAVA'. Perhaps bad JDK_HOME? $JDK_HOME") -if (!file(JAVAC).exists()) throw new Exception("Missing or incorrect path to 'javac': '$JAVAC'. Perhaps bad JDK_HOME? $JDK_HOME") -if (!file(JAVADOC).exists()) throw new Exception("Missing or incorrect path to 'javadoc': '$JAVADOC'. Perhaps bad JDK_HOME? $JDK_HOME") - -// Determine the verion of Java in JDK_HOME. It looks like this: -// -// $ java -version -// java version "1.7.0_45" -// Java(TM) SE Runtime Environment (build 1.7.0_45-b18) -// Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) -// -// We need to parse the second line -def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream())); -try { - String v = inStream.readLine().trim(); - if (v != null) { - int ib = v.indexOf("full version \""); - if (ib != -1) { - String str = v.substring(ib); - String ver = str.substring(str.indexOf("\"") + 1, str.size() - 1); - - defineProperty("jdkRuntimeVersion", ver) - def jdkVersionInfo = parseJavaVersion(ver) - defineProperty("jdkVersion", jdkVersionInfo[0]) - defineProperty("jdkBuildNumber", jdkVersionInfo[1]) - } - } -} finally { - inStream.close(); -} -if (!project.hasProperty("jdkRuntimeVersion")) throw new Exception("Unable to determine the version of Java in JDK_HOME at $JDK_HOME"); - - -// Determine whether the javafx.* modules are present in the JDK. To do this, -// we will execute "java --list-modules" and search for javafx.base -ext.HAS_JAVAFX_MODULES = false; -def inStream2 = new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(JAVA, "--list-modules").start().getInputStream())); -try { - String v; - while ((v = inStream2.readLine()) != null) { - v = v.trim(); - if (v.startsWith("javafx.base")) ext.HAS_JAVAFX_MODULES = true; - } -} finally { - inStream2.close(); -} - // Verify that CONF is something useful if (CONF != "Release" && CONF != "Debug" && CONF != "DebugNative") { logger.warn("Unknown configuration CONF='$CONF'. Treating as 'Release'") @@ -1137,6 +1256,39 @@ logger.warn("*****************************************************************"); } +// Look for stub runtime in bundled sdk, standalone sdk, or boot JDK + +def String cachedBundledRuntime = cygpath("$projectDir") + "/../caches/modular-sdk" +def String cachedStandaloneRuntime = cygpath("$projectDir") + "/../caches/sdk" +def String jdkStubRuntime = cygpath("$JDK_HOME") + +def defaultStubRuntime = "" +if (file(cachedBundledRuntime).exists()) { + defaultStubRuntime = cachedBundledRuntime +} else if (file(cachedStandaloneRuntime).exists()) { + defaultStubRuntime = cachedStandaloneRuntime +} else if (BUILD_CLOSED) { + defaultStubRuntime = cachedBundledRuntime +} else { + defaultStubRuntime = jdkStubRuntime +} + +defineProperty("STUB_RUNTIME", defaultStubRuntime) + +if (STUB_RUNTIME.endsWith("/modular-sdk")) { + def stubModulesLib = "$STUB_RUNTIME/modules_libs" + defineProperty("MEDIA_STUB", "$stubModulesLib/javafx.media") + defineProperty("WEB_STUB", "$stubModulesLib/javafx.web") +} else { + def libraryStub = IS_WINDOWS ? "$STUB_RUNTIME/bin" : "$STUB_RUNTIME/lib" + + defineProperty("MEDIA_STUB", libraryStub) + defineProperty("WEB_STUB", libraryStub) +} + +ext.UPDATE_STUB_CACHE = (BUILD_CLOSED && STUB_RUNTIME != "" && !file(STUB_RUNTIME).isDirectory()) + + /****************************************************************************** * * * Logging of Properties and Settings * @@ -1174,10 +1326,7 @@ logger.quiet("RELEASE_VERSION_SHORT: $RELEASE_VERSION_SHORT") logger.quiet("RELEASE_VERSION_LONG: $RELEASE_VERSION_LONG") logger.quiet("RELEASE_VERSION_PADDED: $RELEASE_VERSION_PADDED") - -if (UPDATE_STUB_CACHE) { - logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE") -} +logger.quiet("UPDATE_STUB_CACHE: $UPDATE_STUB_CACHE") /****************************************************************************** * * @@ -2188,6 +2337,10 @@ test { enabled = IS_FULL_TEST && IS_AWT_TEST + + if (!HAS_JAVAFX_MODULES) { + jvmArgs += qualExportsSwing + } } compileJava.options.compilerArgs.addAll(qualExportsCore) @@ -2268,7 +2421,7 @@ project.ext.moduleSourcePath = defaultModuleSourcePath project.ext.moduleSourcePathShim = defaultModuleSourcePathShim - commonModuleSetup(project, [ 'base', 'graphics', 'swing', 'controls', 'fxml' ]) + commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'fxml' ]) dependencies { @@ -3747,7 +3900,8 @@ testCompile project(":swing").sourceSets.test.output } - commonModuleSetup(project, [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ]) + def dependentProjects = [ 'base', 'graphics', 'controls', 'media', 'web', 'swing', 'fxml' ] + commonModuleSetup(project, dependentProjects) File testJavaPolicyFile = new File(rootProject.buildDir, TESTJAVAPOLICYFILE); File testRunArgsFile = new File(rootProject.buildDir,TESTRUNARGSFILE); @@ -3786,6 +3940,13 @@ // Tasks to create standalone test applications for the launcher tests + if (project.hasProperty('testModulePathArgs')) { + compileTestapp1Java.options.compilerArgs.addAll(testModulePathArgs) + } + dependentProjects.each { e -> + compileTestapp1Java.dependsOn(rootProject.project(e).testClasses) + } + def testapp1JarName = "testapp1.jar" task createTestapp1Jar1(type: Jar) { dependsOn compileTestapp1Java @@ -3843,8 +4004,15 @@ testappCompileTasks.each { appCompileTask -> appCompileTask.options.compilerArgs.addAll([ '-implicit:none', - '--module-source-path', testAppSourceDirs.join(File.pathSeparator) + '--module-source-path', testAppSourceDirs.join(File.pathSeparator), ] ) + if (project.hasProperty('testModulePathArgs')) { + appCompileTask.options.compilerArgs.addAll(testModulePathArgs) + } + + dependentProjects.each { e -> + appCompileTask.dependsOn(rootProject.project(e).testClasses) + } copyTestAppTask.dependsOn(appCompileTask) } @@ -3858,6 +4026,18 @@ test { enabled = IS_FULL_TEST + // Parse testPatchModuleArgs looking for "--module-path". + // Save path if found so we can pass it to the module launcher tests + def pendingModulePath = false + testPatchModuleArgs.each { str -> + if (pendingModulePath) { + project.ext.launcherModulePath = str; + pendingModulePath = false + } else if (str == "--module-path") { + pendingModulePath = true + } + } + // Properties passed to launcher tests systemProperty "launchertest.testapp1.jar", "build/testapp1/$testapp1JarName" modtestapps.each { testapp -> @@ -3868,6 +4048,9 @@ // Properties passed to test.util.Util systemProperties 'worker.debug': IS_WORKER_DEBUG systemProperties 'worker.patchmodule.file': cygpath(stRunArgsFile.path) + if (project.hasProperty("launcherModulePath")) { + systemProperties 'worker.module.path': launcherModulePath + } systemProperties 'worker.patch.policy': cygpath(testJavaPolicyFile.path) systemProperties 'worker.java.cmd': JAVA @@ -3885,6 +4068,10 @@ exclude("**/com/sun/javafx/application/Swing*.*"); } + if (!HAS_JAVAFX_MODULES) { + jvmArgs += qualExportsSwing + } + forkEvery = 1 } } @@ -3958,7 +4145,9 @@ def copyGeneratedShimsTask = task("copyGeneratedShims", type: Copy, dependsOn: [compileShimsJava, processShimsResources]) { from project.sourceSets.shims.java.outputDir into "${rootProject.buildDir}/shims" - exclude("*/module-info.class") + if (HAS_JAVAFX_MODULES) { + exclude("*/module-info.class") + } } project.processShimsResources.dependsOn(project.processResources) @@ -4056,6 +4245,10 @@ mspFile << "--module-source-path\n" mspFile << defaultModuleSourcePath mspFile << "\n" + + if (!HAS_JAVAFX_MODULES) { + appendQualExports(mspFile, qualExportsSwing) + } } } @@ -4333,21 +4526,24 @@ def targetProperties = project.ext[t.upper] def platformPrefix = targetProperties.platformPrefix - def modularSdkDirName = "${platformPrefix}modular-sdk" - def modularSdkDir = "${rootProject.buildDir}/${modularSdkDirName}" - def modulesDir = "${modularSdkDir}/modules" - def modulesCmdsDir = "${modularSdkDir}/modules_cmds" - def modulesLibsDir = "${modularSdkDir}/modules_libs" - def modulesSrcDir = "${modularSdkDir}/modules_src" - def modulesConfDir = "${modularSdkDir}/modules_conf" - def modulesLegalDir = "${modularSdkDir}/modules_legal" - def modulesMakeDir = "${modularSdkDir}/make" + def bundledSdkDirName = "${platformPrefix}modular-sdk" + def bundledSdkDir = "${rootProject.buildDir}/${bundledSdkDirName}" + def modulesDir = "${bundledSdkDir}/modules" + def modulesCmdsDir = "${bundledSdkDir}/modules_cmds" + def modulesLibsDir = "${bundledSdkDir}/modules_libs" + def modulesSrcDir = "${bundledSdkDir}/modules_src" + def modulesConfDir = "${bundledSdkDir}/modules_conf" + def modulesLegalDir = "${bundledSdkDir}/modules_legal" + def modulesMakeDir = "${bundledSdkDir}/make" + final File runArgsFile = file("${rootProject.buildDir}/${RUNARGSFILE}") final File compileArgsFile = file("${rootProject.buildDir}/${COMPILEARGSFILE}") project.files(runArgsFile); def buildModulesTask = task("buildModules$t.capital", group: "Build") { + // BUNDLED SDK + // Copy dependencies/*/module-info.java.extra // merging as needed, removing duplicates // only lines with 'exports' will be copied @@ -4449,6 +4645,7 @@ } buildModules.dependsOn(buildModulesTask) + // BUNDLED SDK moduleProjList.each { project -> // Copy classes, bin, and lib directories @@ -4547,26 +4744,126 @@ copyLegalTask) } + // ============================================================ + + def standaloneSdkDirName = "${platformPrefix}sdk" + def standaloneSdkDir = "${rootProject.buildDir}/${standaloneSdkDirName}" + def standaloneLibDir = "${standaloneSdkDir}/lib" + def libDest=targetProperties.libDest + def standaloneNativeDir = "${standaloneSdkDir}/${libDest}" + def standaloneLegalDir = "${standaloneSdkDir}/legal" + def standaloneSrcZipName = "src.zip" + + // STANDALONE SDK + moduleProjList.each { project -> + // Copy classes, bin, and lib directories + + def moduleName = project.ext.moduleName + def buildDir = project.buildDir + + // Create modular jars + def srcClassesDir = "${buildDir}/${platformPrefix}module-classes" + def dstModularJarDir = "${standaloneLibDir}" + def modularJarName = "${moduleName}.jar" + def modularJarTask = project.task("modularJarStandalone$t.capital", type: Jar, dependsOn: project.assemble) { + destinationDir = file("${dstModularJarDir}") + archiveName = modularJarName + includeEmptyDirs = false + from srcClassesDir + } + + // Copy native libraries + def srcNativeDir = "${buildDir}/${platformPrefix}module-lib" + def dstNativeDir = "${standaloneNativeDir}" + def copyNativeFilesTask = project.task("copyNativeFilesStandalone$t.capital", type: Copy, dependsOn: modularJarTask) { + from srcNativeDir + into dstNativeDir + include("*.dll") + } + + // Copy other lib files + def srcLibsDir = "${buildDir}/${platformPrefix}module-lib" + def dstLibsDir = "${standaloneLibDir}" + def copyLibFilesTask = project.task("copyLibFilesStandalone$t.capital", type: Copy, dependsOn: copyNativeFilesTask) { + from srcLibsDir + into dstLibsDir + exclude("*.dll") + } + + // Copy legal files + def licenseFiles = [ "ADDITIONAL_LICENSE_INFO", "ASSEMBLY_EXCEPTION", "LICENSE" ] + def srcLegalDir = "${project.projectDir}/src/main/legal" + def dstLegalDir = "${standaloneLegalDir}/${moduleName}" + def copyLegalTask = project.task("copyLegalStandalone$t.capital", type: Copy, dependsOn: copyLibFilesTask) { + + def rtDir = rootProject.file('.') + licenseFiles.each { lFile -> + from "${rtDir}/${lFile}" + } + + from srcLegalDir + + into dstLegalDir + + // Exclude ANGLE since we (currently) do not use it + exclude("angle.md") + } + + buildModulesTask.dependsOn( + modularJarTask, + copyNativeFilesTask, + copyLibFilesTask, + copyLegalTask) + } + + // Zip module sources for standalone SDK + // + // NOTE: the input is taken from the modular-sdk/modules_src dir + // so that we don't have to duplicate the logic and create another + // temporary directory. This is somewhat inelegant, since the bundled sdk + // and the standalone sdk should be independent of one another, but seems + // better than the alternatives. + def zipSourceFilesTask = project.task("zipSourceFilesStandalone$t.capital", type: Zip, dependsOn: buildModulesTask) { + destinationDir = file("${standaloneLibDir}") + archiveName = standaloneSrcZipName + includeEmptyDirs = false + from modulesSrcDir + include "**/*.java" + } + buildModules.dependsOn(zipSourceFilesTask) + + // ============================================================ + def buildRunArgsTask = task("buildRunArgs$t.capital", group: "Build", dependsOn: buildModulesTask) { outputs.file(runArgsFile); inputs.file(EXTRAADDEXPORTS); doLast() { - Listlibpath = [] Listmodpath = [] + Listmodnames = [] moduleProjList.each { project -> def moduleName = project.ext.moduleName def dstModuleDir = cygpath("${modulesDir}/${moduleName}") - modpath << "${moduleName}=${dstModuleDir}" + if (HAS_JAVAFX_MODULES) { + modpath << "${moduleName}=${dstModuleDir}" + } else { + modnames << moduleName + } } - writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath) - writeRunArgsFile(compileArgsFile, null, modpath) - - if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { - runArgsFile << EXTRA_ADDEXPORTS_STRING - compileArgsFile << EXTRA_ADDEXPORTS_STRING + if (HAS_JAVAFX_MODULES) { + writeRunArgsFile(runArgsFile, computeLibraryPath(true), modpath, null) + writeRunArgsFile(compileArgsFile, null, modpath, null) + + if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { + runArgsFile << EXTRA_ADDEXPORTS_STRING + compileArgsFile << EXTRA_ADDEXPORTS_STRING + } + } else { + modpath = [ cygpath("${standaloneLibDir}") ] + writeRunArgsFile(runArgsFile, null, modpath, modnames) + writeRunArgsFile(compileArgsFile, null, modpath, modnames) } } } @@ -4894,7 +5191,7 @@ archiveName = jfxBundle destinationDir = file("${rootProject.buildDir}") includeEmptyDirs = false - from "${modularSdkDir}" + from "${bundledSdkDir}" } jdkZip.dependsOn(zipTask) @@ -4932,37 +5229,72 @@ List modpath = [] - moduleProjList.each { project -> - if (project.hasProperty("moduleName") && project.buildModule) { - File dir; - if (project.sourceSets.hasProperty('shims')) { - dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}") - } else { - dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") + if (HAS_JAVAFX_MODULES) { + moduleProjList.each { project -> + if (project.hasProperty("moduleName") && project.buildModule) { + File dir; + if (project.sourceSets.hasProperty('shims')) { + dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}") + } else { + dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") + } + + def dstModuleDir = cygpath(dir.path) + modpath << "${project.ext.moduleName}=${dstModuleDir}" + + String themod = dir.toURI() + testJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + + " permission java.security.AllPermission;\n" + + "};\n" + + dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") + themod = dir.toURI() + runJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + + " permission java.security.AllPermission;\n" + + "};\n" } - - def dstModuleDir = cygpath(dir.path) - modpath << "${project.ext.moduleName}=${dstModuleDir}" - - String themod = dir.toURI() - testJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + - " permission java.security.AllPermission;\n" + - "};\n" - - dir = new File(rootProject.buildDir, "modular-sdk/modules/${project.ext.moduleName}") - themod = dir.toURI() - runJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + - " permission java.security.AllPermission;\n" + - "};\n" } - } - - writeRunArgsFile(testCompileArgsFile, null, modpath) - writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath) - - if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { - testCompileArgsFile << EXTRA_ADDEXPORTS_STRING - testRunArgsFile << EXTRA_ADDEXPORTS_STRING + + writeRunArgsFile(testCompileArgsFile, null, modpath, null) + writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, null) + + if (rootProject.hasProperty("EXTRA_ADDEXPORTS_STRING")) { + testCompileArgsFile << EXTRA_ADDEXPORTS_STRING + testRunArgsFile << EXTRA_ADDEXPORTS_STRING + } + } else { + def modnames = [] + moduleProjList.each { project -> + if (project.hasProperty("moduleName") && project.buildModule) { + modnames << project.ext.moduleName + File dir; + if (project.sourceSets.hasProperty('shims')) { + dir = new File(rootProject.buildDir, "shims/${project.ext.moduleName}") + } else { + dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar") + } + + def dstModuleDir = cygpath(dir.path) + modpath << "${dstModuleDir}" + + String themod = dir.toURI() + testJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + + " permission java.security.AllPermission;\n" + + "};\n" + + dir = new File(rootProject.buildDir, "sdk/lib/${project.ext.moduleName}.jar") + themod = dir.toURI() + runJavaPolicyFile << "grant codeBase \"${themod}\" {\n" + + " permission java.security.AllPermission;\n" + + "};\n" + } + } + + writeRunArgsFile(testCompileArgsFile, null, modpath, modnames) + writeRunArgsFile(testRunArgsFile, computeLibraryPath(true), modpath, modnames) + + appendQualExports(testCompileArgsFile, qualExportsSwing) + appendQualExports(testRunArgsFile, qualExportsSwing) } } } diff --git a/buildSrc/addExports b/buildSrc/addExports --- a/buildSrc/addExports +++ b/buildSrc/addExports @@ -1,5 +1,9 @@ # buildSrc/addExports: temporary --add-exports and --add-reads # +# NOTE: this is only used for the bundled sdk build. It is needed only +# for changes that have been added to module-info.java and are not in +# the minimum required boot JDK. +# # After a promoted jdk build includes the module-info changes associated # with a particular fix, we might eventually remove the --add-exports or # --add-reads from this file for that fix, after bumping the minimum jdk diff --git a/modules/javafx.base/src/test/java/test/com/sun/javafx/runtime/ModuleTest.java b/modules/javafx.base/src/test/java/test/com/sun/javafx/runtime/ModuleTest.java new file mode 100644 --- /dev/null +++ b/modules/javafx.base/src/test/java/test/com/sun/javafx/runtime/ModuleTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package test.com.sun.javafx.runtime; + +import java.lang.module.ModuleDescriptor; +import javafx.beans.property.BooleanProperty; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Simple test to ensure that javafx.base is a named, non-automatic module + */ +public class ModuleTest { + + @Test + public void testIsModule() { + // Pick a class in javafx.base and check its module name and descriptor + Class clz = BooleanProperty.class; + Module mod = clz.getModule(); + assertTrue(mod.isNamed()); + assertEquals("javafx.base", mod.getName()); + ModuleDescriptor descriptor = mod.getDescriptor(); + assertNotNull(descriptor); + assertFalse(descriptor.isAutomatic()); + } + +} diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,6 +92,10 @@ private static String applicationType = ""; private static BooleanProperty accessibilityActive = new SimpleBooleanProperty(); + private static final boolean verbose + = AccessController.doPrivileged((PrivilegedAction) () -> + Boolean.getBoolean("javafx.verbose")); + private static final boolean DEBUG = AccessController.doPrivileged((PrivilegedAction) () -> Boolean.getBoolean("com.sun.javafx.application.debug")); @@ -217,6 +221,13 @@ s = System.getProperty("javafx.embed.singleThread"); if (s != null) { isThreadMerged = Boolean.valueOf(s); + if (isThreadMerged && !isSupported(ConditionalFeature.SWING)) { + isThreadMerged = false; + if (verbose) { + System.err.println( + "WARNING: javafx.embed.singleThread ignored (javafx.swing module not found)"); + } + } } return null; }); diff --git a/tests/README.txt b/tests/README.txt --- a/tests/README.txt +++ b/tests/README.txt @@ -1,2 +1,2 @@ This directory is for functional tests in rt that need the full -JavaFX runtime in ../build/modular-sdk +JavaFX runtime in ../build/modular-sdk or ../build/sdk diff --git a/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java b/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java --- a/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java +++ b/tests/system/src/test/java/test/launchertest/ModuleLauncherTest.java @@ -25,6 +25,7 @@ package test.launchertest; +import java.io.File; import java.util.ArrayList; import junit.framework.AssertionFailedError; import org.junit.Test; @@ -46,7 +47,14 @@ private final int testExitCode = ERROR_NONE; - private void doTestLaunchModule(String modulePath, String testAppName) throws Exception { + private void doTestLaunchModule(String appModulePath, String testAppName) throws Exception { + final String javafxModulePath = System.getProperty("worker.module.path"); + String modulePath; + if (javafxModulePath != null) { + modulePath = javafxModulePath + File.pathSeparator + appModulePath; + } else { + modulePath = appModulePath; + } assertNotNull(testAppName); System.err.println("The following Unknown module WARNING messages are expected:"); String mpArg = "--module-path=" + modulePath; diff --git a/tools/scripts/compareBuilds b/tools/scripts/compareBuilds --- a/tools/scripts/compareBuilds +++ b/tools/scripts/compareBuilds @@ -4,6 +4,7 @@ # # usage: compareBuilds full_path_to_top_one full_path_to_top_two +# TODO KCR: update this to also compare standalone sdk one="$1" two="$2" diff --git a/tools/scripts/make_runargs.sh b/tools/scripts/make_runargs.sh --- a/tools/scripts/make_runargs.sh +++ b/tools/scripts/make_runargs.sh @@ -5,6 +5,8 @@ # in place # +# TODO KCR: update this for standalone vs bundled sdk + TOP="$1" do_cygpath() diff --git a/tools/scripts/whatChanged b/tools/scripts/whatChanged --- a/tools/scripts/whatChanged +++ b/tools/scripts/whatChanged @@ -8,6 +8,8 @@ # and then the sums files will be updated. # +# TODO KCR: update this to also compare standalone sdk + TOP="$PWD" BLDTOP="${TOP}/build" HASHDIR="$BLDTOP/hashes"