mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-21 12:20:29 +00:00
8381968: Extend cds/appcds/aotCode/AOTCodeFlags.java to run test with different flags in assembly and prod run
Reviewed-by: kvn, adinn
This commit is contained in:
parent
a06f3cd469
commit
974596775b
@ -587,7 +587,8 @@ hotspot_metaspace = \
|
||||
tier1_runtime_appcds = \
|
||||
runtime/cds/appcds/aotCache/HelloAOTCache.java \
|
||||
runtime/cds/appcds/aotCode \
|
||||
runtime/cds/appcds/HelloTest.java
|
||||
runtime/cds/appcds/HelloTest.java \
|
||||
-runtime/cds/appcds/aotCode/AOTCodeFlags.java
|
||||
|
||||
tier1_runtime_appcds_exclude = \
|
||||
runtime/cds/appcds/ \
|
||||
|
||||
@ -31,13 +31,9 @@
|
||||
* @comment The test verifies AOT checks during VM startup and not code generation.
|
||||
* No need to run it with -Xcomp.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeCPUFeatureIncompatibilityTest JavacBenchApp
|
||||
* @build AOTCodeCPUFeatureIncompatibilityTest HelloWorld
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloWorld
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AOTCodeCPUFeatureIncompatibilityTest
|
||||
*/
|
||||
|
||||
@ -98,9 +94,7 @@ public class AOTCodeCPUFeatureIncompatibilityTest {
|
||||
}
|
||||
@Override
|
||||
public String[] appCommandLine(RunMode runMode) {
|
||||
return new String[] {
|
||||
"JavacBenchApp", "10"
|
||||
};
|
||||
return new String[] { "HelloWorld" };
|
||||
}
|
||||
}.runAOTWorkflow("--two-step-training");
|
||||
}
|
||||
|
||||
@ -33,12 +33,8 @@
|
||||
* No need to run it with -Xcomp. It takes a lot of time to complete all
|
||||
* subtests with this flag.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeCompressedOopsTest JavacBenchApp
|
||||
* @run driver/timeout=480 jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @build AOTCodeCompressedOopsTest HelloWorld
|
||||
* @run driver/timeout=480 jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloWorld
|
||||
* @run driver/timeout=480 AOTCodeCompressedOopsTest
|
||||
*/
|
||||
|
||||
@ -149,9 +145,7 @@ public class AOTCodeCompressedOopsTest {
|
||||
|
||||
@Override
|
||||
public String[] appCommandLine(RunMode runMode) {
|
||||
return new String[] {
|
||||
"JavacBenchApp", "10"
|
||||
};
|
||||
return new String[] { "HelloWorld" };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -109,39 +109,44 @@ public class AOTCodeFlags {
|
||||
private static String gcName = null;
|
||||
public static void main(String... args) throws Exception {
|
||||
Tester t = new Tester(args.length == 0 ? null : args[0]);
|
||||
// Run only 2 modes (0 - no AOT code, 1 - AOT adapters) until JDK-8357398 is fixed
|
||||
for (int mode = 0; mode < 4; mode++) {
|
||||
t.setTestMode(mode);
|
||||
t.run(new String[] {"AOT", "--two-step-training"});
|
||||
// mode bits 0 and 1 encode AOTAdapterCaching and AOTStubCaching settings
|
||||
// aMode is used for assembly run, pMode for production run
|
||||
for (int aMode = 0; aMode < 4; aMode++) {
|
||||
for (int pMode = 0; pMode < 4; pMode++) {
|
||||
t.setTestMode(aMode, pMode);
|
||||
t.run(new String[] {"AOT", "--two-step-training"});
|
||||
}
|
||||
}
|
||||
}
|
||||
static class Tester extends CDSAppTester {
|
||||
private int testMode;
|
||||
private int aMode, pMode;
|
||||
private String gcName;
|
||||
|
||||
public Tester(String name) {
|
||||
super("AOTCodeFlags");
|
||||
testMode = 0;
|
||||
aMode = 0;
|
||||
pMode = 0;
|
||||
gcName = name;
|
||||
}
|
||||
|
||||
boolean isAdapterCachingOn() {
|
||||
return (testMode & 0x1) != 0;
|
||||
boolean isAdapterCachingOn(int mode) {
|
||||
return (mode & 0x1) != 0;
|
||||
}
|
||||
|
||||
boolean isStubCachingOn() {
|
||||
return (testMode & 0x2) != 0;
|
||||
boolean isStubCachingOn(int mode) {
|
||||
return (mode & 0x2) != 0;
|
||||
}
|
||||
|
||||
public void setTestMode(int mode) {
|
||||
testMode = mode;
|
||||
public void setTestMode(int aMode, int pMode) {
|
||||
this.aMode = aMode;
|
||||
this.pMode = pMode;
|
||||
}
|
||||
|
||||
public List<String> getVMArgsForTestMode() {
|
||||
public List<String> getVMArgsForTestMode(int mode) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("-XX:+UnlockDiagnosticVMOptions");
|
||||
list.add(isAdapterCachingOn() ? "-XX:+AOTAdapterCaching" : "-XX:-AOTAdapterCaching");
|
||||
list.add(isStubCachingOn() ? "-XX:+AOTStubCaching" : "-XX:-AOTStubCaching");
|
||||
list.add(isAdapterCachingOn(mode) ? "-XX:+AOTAdapterCaching" : "-XX:-AOTAdapterCaching");
|
||||
list.add(isStubCachingOn(mode) ? "-XX:+AOTStubCaching" : "-XX:-AOTStubCaching");
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -170,79 +175,91 @@ public class AOTCodeFlags {
|
||||
|
||||
@Override
|
||||
public String[] vmArgs(RunMode runMode) {
|
||||
List<String> args = getGCArgs();
|
||||
args.addAll(List.of("-Xlog:aot+codecache+init=debug",
|
||||
"-Xlog:aot+codecache+exit=debug",
|
||||
"-Xlog:aot+codecache+stubs=debug"));
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION: {
|
||||
List<String> args = getVMArgsForTestMode();
|
||||
args.addAll(List.of("-Xlog:aot+codecache+init=debug",
|
||||
"-Xlog:aot+codecache+exit=debug"));
|
||||
args.addAll(getGCArgs());
|
||||
return args.toArray(new String[0]);
|
||||
}
|
||||
args.addAll(getVMArgsForTestMode(aMode));
|
||||
break;
|
||||
case RunMode.PRODUCTION:
|
||||
args.addAll(getVMArgsForTestMode(pMode));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
List<String> args = getGCArgs();
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] appCommandLine(RunMode runMode) {
|
||||
return new String[] {
|
||||
"JavacBenchApp", "10"
|
||||
};
|
||||
return new String[] { "JavacBenchApp", "10" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
|
||||
if (!isAdapterCachingOn() && !isStubCachingOn()) { // this is equivalent to completely disable AOT code cache
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION:
|
||||
if (runMode == RunMode.ASSEMBLY) {
|
||||
if (!isAdapterCachingOn(aMode) && !isStubCachingOn(aMode)) { // this is equivalent to completely disable AOT code cache
|
||||
out.shouldNotMatch("Adapters:\\s+total");
|
||||
out.shouldNotMatch("Shared Blobs:\\s+total");
|
||||
out.shouldNotMatch("C1 Blobs:\\s+total");
|
||||
out.shouldNotMatch("C2 Blobs:\\s+total");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (isAdapterCachingOn()) {
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION:
|
||||
// AOTAdapterCaching is on, non-zero adapters should be stored/loaded
|
||||
out.shouldMatch("Adapters:\\s+total=[1-9][0-9]+");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION:
|
||||
// AOTAdapterCaching is off, no adapters should be stored/loaded
|
||||
if (isAdapterCachingOn(aMode)) {
|
||||
// AOTAdapterCaching is on, non-zero adapters should be stored
|
||||
out.shouldMatch("Adapters:\\s+total=[1-9][0-9]+");
|
||||
} else {
|
||||
// AOTAdapterCaching is off, no adapters should be stored
|
||||
out.shouldMatch("Adapters:\\s+total=0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isStubCachingOn()) {
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION:
|
||||
// AOTStubCaching is on, non-zero stubs should be stored/loaded
|
||||
if (isStubCachingOn(aMode)) {
|
||||
// AOTStubCaching is on, non-zero stubs should be stored
|
||||
out.shouldMatch("Shared Blobs:\\s+total=[1-9][0-9]+");
|
||||
out.shouldMatch("C1 Blobs:\\s+total=[1-9][0-9]+");
|
||||
// we do not currently load or store C2 stubs
|
||||
// because we are seeing weird memory errors
|
||||
// when loading them -- see JDK-8357593
|
||||
out.shouldMatch("C2 Blobs:\\s+total=0");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (runMode) {
|
||||
case RunMode.ASSEMBLY:
|
||||
case RunMode.PRODUCTION:
|
||||
// AOTStubCaching is off, no stubs should be stored/loaded
|
||||
} else {
|
||||
// AOTStubCaching is off, no stubs should be stored
|
||||
out.shouldMatch("Shared Blobs:\\s+total=0");
|
||||
out.shouldMatch("C1 Blobs:\\s+total=0");
|
||||
out.shouldMatch("C2 Blobs:\\s+total=0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (runMode == RunMode.PRODUCTION) {
|
||||
// Irrespective of assembly run mode, if both adapter and stub caching is disabled
|
||||
// in production run, then it is equivalent to completely disabling AOT code cache
|
||||
if (!isAdapterCachingOn(pMode) && !isStubCachingOn(pMode)) {
|
||||
out.shouldNotMatch("Adapters:\\s+total");
|
||||
out.shouldNotMatch("Shared Blobs:\\s+total");
|
||||
out.shouldNotMatch("C1 Blobs:\\s+total");
|
||||
out.shouldNotMatch("C2 Blobs:\\s+total");
|
||||
} else {
|
||||
// If AOT code cache is effectively disabled in the assembly run, then production run
|
||||
// would emit empty code cache message.
|
||||
if (!isAdapterCachingOn(aMode) && !isStubCachingOn(aMode)) {
|
||||
if (isAdapterCachingOn(pMode) || isStubCachingOn(pMode)) {
|
||||
out.shouldMatch("AOT Code Cache is empty");
|
||||
}
|
||||
} else {
|
||||
if (isAdapterCachingOn(aMode)) {
|
||||
if (isAdapterCachingOn(pMode)) {
|
||||
out.shouldMatch("Read blob.*kind=Adapter.*");
|
||||
} else {
|
||||
out.shouldNotMatch("Read blob.*kind=Adapter.*");
|
||||
}
|
||||
}
|
||||
if (isStubCachingOn(aMode)) {
|
||||
if (isStubCachingOn(pMode)) {
|
||||
out.shouldMatch("Read blob.*kind=SharedBlob.*");
|
||||
out.shouldMatch("Read blob.*kind=C1Blob.*");
|
||||
} else {
|
||||
out.shouldNotMatch("Read blob.*kind=SharedBlob.*");
|
||||
out.shouldNotMatch("Read blob.*kind=C1Blob.*");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
196
test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeTest.java
Normal file
196
test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeTest.java
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test id=g1
|
||||
* @requires vm.gc.G1
|
||||
* @summary Sanity test of AOTCodeCache
|
||||
* @requires vm.cds.supports.aot.code.caching
|
||||
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
||||
* @comment Both C1 and C2 JIT compilers are required because the test verifies
|
||||
* compiler's runtime blobs generation.
|
||||
* @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
|
||||
* @comment VerifyOops flag switch off AOT code generation. Skip it.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeTest JavacBenchApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver/timeout=1500 AOTCodeTest G1
|
||||
*/
|
||||
/**
|
||||
* @test id=parallel
|
||||
* @requires vm.gc.Parallel
|
||||
* @summary Sanity test of AOTCodeCache
|
||||
* @requires vm.cds.supports.aot.code.caching
|
||||
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
||||
* @comment Both C1 and C2 JIT compilers are required because the test verifies
|
||||
* compiler's runtime blobs generation.
|
||||
* @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
|
||||
* @comment VerifyOops flag switch off AOT code generation. Skip it.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeTest JavacBenchApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver/timeout=1500 AOTCodeTest Parallel
|
||||
*/
|
||||
/**
|
||||
* @test id=serial
|
||||
* @requires vm.gc.Serial
|
||||
* @summary Sanity test of AOTCodeCache
|
||||
* @requires vm.cds.supports.aot.code.caching
|
||||
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
||||
* @comment Both C1 and C2 JIT compilers are required because the test verifies
|
||||
* compiler's runtime blobs generation.
|
||||
* @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
|
||||
* @comment VerifyOops flag switch off AOT code generation. Skip it.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeTest JavacBenchApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver/timeout=1500 AOTCodeTest Serial
|
||||
*/
|
||||
/**
|
||||
* @test id=shenandoah
|
||||
* @requires vm.gc.Shenandoah
|
||||
* @summary Sanity test of AOTCodeCache
|
||||
* @requires vm.cds.supports.aot.code.caching
|
||||
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
||||
* @comment Both C1 and C2 JIT compilers are required because the test verifies
|
||||
* compiler's runtime blobs generation.
|
||||
* @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
|
||||
* @comment VerifyOops flag switch off AOT code generation. Skip it.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeTest JavacBenchApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver/timeout=1500 AOTCodeTest Shenandoah
|
||||
*/
|
||||
/**
|
||||
* @test id=Z
|
||||
* @requires vm.gc.Z
|
||||
* @summary Sanity test of AOTCodeCache
|
||||
* @requires vm.cds.supports.aot.code.caching
|
||||
* @requires vm.compiler1.enabled & vm.compiler2.enabled
|
||||
* @comment Both C1 and C2 JIT compilers are required because the test verifies
|
||||
* compiler's runtime blobs generation.
|
||||
* @requires vm.opt.VerifyOops == null | vm.opt.VerifyOops == false
|
||||
* @comment VerifyOops flag switch off AOT code generation. Skip it.
|
||||
* @library /test/lib /test/setup_aot
|
||||
* @build AOTCodeTest JavacBenchApp
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar
|
||||
* JavacBenchApp
|
||||
* JavacBenchApp$ClassFile
|
||||
* JavacBenchApp$FileManager
|
||||
* JavacBenchApp$SourceFile
|
||||
* @run driver/timeout=1500 AOTCodeTest Z
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.test.lib.cds.CDSAppTester;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class AOTCodeTest {
|
||||
private static String gcName = null;
|
||||
public static void main(String... args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
throw new RuntimeException("Expected GC name");
|
||||
}
|
||||
Tester t = new Tester(args[0]);
|
||||
t.run(new String[] {"AOT", "--two-step-training"});
|
||||
}
|
||||
|
||||
static class Tester extends CDSAppTester {
|
||||
private String gcName;
|
||||
|
||||
public Tester(String name) {
|
||||
super("AOTCodeTest");
|
||||
gcName = name;
|
||||
}
|
||||
|
||||
public List<String> getGCArgs() {
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.add("-Xmx100M");
|
||||
switch (gcName) {
|
||||
case "G1":
|
||||
case "Parallel":
|
||||
case "Serial":
|
||||
case "Shenandoah":
|
||||
case "Z":
|
||||
args.add("-XX:+Use" + gcName + "GC");
|
||||
return args;
|
||||
default:
|
||||
throw new RuntimeException("Unexpected GC name " + gcName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String classpath(RunMode runMode) {
|
||||
return "app.jar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] vmArgs(RunMode runMode) {
|
||||
List<String> args = getGCArgs();
|
||||
// Add flags for logs
|
||||
args.addAll(List.of("-Xlog:aot+codecache+init=debug",
|
||||
"-Xlog:aot+codecache+exit=debug",
|
||||
"-Xlog:aot+codecache+stubs=debug"));
|
||||
// Add diagnostic flags
|
||||
args.addAll(List.of("-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+AbortVMOnAOTCodeFailure"));
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] appCommandLine(RunMode runMode) {
|
||||
return new String[] { "JavacBenchApp", "10" };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
|
||||
if (runMode == RunMode.ASSEMBLY) {
|
||||
out.shouldMatch("aot,codecache,exit.*\\s+AOT code cache size: [1-9]\\d+ bytes");
|
||||
} else if (runMode == RunMode.PRODUCTION) {
|
||||
out.shouldMatch("aot,codecache,init.*\\s+Loaded [1-9]\\d+ AOT code entries from AOT Code Cache");
|
||||
out.shouldMatch("aot,codecache,stubs.*\\s+Read blob.*kind=Adapter.*");
|
||||
out.shouldMatch("aot,codecache,stubs.*\\s+Read blob.*kind=SharedBlob.*");
|
||||
out.shouldMatch("aot,codecache,stubs.*\\s+Read blob.*kind=C1Blob.*");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
test/setup_aot/HelloWorld.java
Normal file
29
test/setup_aot/HelloWorld.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
public class HelloWorld {
|
||||
public static void main(String args[]) {
|
||||
System.out.println("HelloWorld");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user