Path: blob/master/test/jdk/tools/launcher/UnicodeTest.java
41144 views
/*1* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 503026526* @modules jdk.compiler27* jdk.zipfs28* @compile -XDignore.symbol.file UnicodeTest.java29* @run main/othervm UnicodeTest30* @summary Verify that the J2RE can handle all legal Unicode characters31* in class names unless limited by the file system encoding32* or the encoding used for command line arguments.33* @author Norbert Lindenberg, ksrini34*/3536/*37* This class creates Java source files using Unicode characters38* that test the limits of what's possible39* - in situations where the platform encoding imposes limits40* (command line arguments, non-Unicode file system)41* - in situations where full Unicode is supported42* (file system access in UTF-8 locales and on Windows 2000++,43* jar file contents)44*45* This test needs to be run in othervm as the locale is reset.46*/4748import java.io.File;49import java.io.FileOutputStream;50import java.io.OutputStreamWriter;51import java.nio.charset.Charset;52import java.util.Locale;5354public class UnicodeTest extends TestHelper {55static final File UnicodeTestSrc = new File("UnicodeTest-src");56static final File UnicodeTestClasses = new File("UnicodeTest-classes");57static final String UnicodeTestJarName = "UnicodeTest" + JAR_FILE_EXT;58static final File UnicodeTestJar = new File(UnicodeTestJarName);59static final File SolarisUnicodeTestJar = new File(TEST_SOURCES_DIR,60UnicodeTestJarName);6162/*63* the main method is a port of the shell based test to a java, this64* eliminates the need for MKS on windows, thus we can rely on consistent65* results regardless of the shell being used.66*/67public static void main(String... args) throws Exception {68System.out.println("creating test source files");69UnicodeTestSrc.mkdirs();70UnicodeTestClasses.mkdirs();71String classname = generateSources();72File javaFile = new File(UnicodeTestSrc, classname + JAVA_FILE_EXT);73System.out.println("building test apps");74compile("-encoding", "UTF-8",75"-sourcepath", UnicodeTestSrc.getAbsolutePath(),76"-d", UnicodeTestClasses.getAbsolutePath(),77javaFile.getAbsolutePath());7879createJar("-cvfm", UnicodeTestJar.getAbsolutePath(),80new File(UnicodeTestSrc, "MANIFEST.MF").getAbsolutePath(),81"-C", UnicodeTestClasses.getAbsolutePath(), ".");8283if (!UnicodeTestJar.exists()) {84throw new Error("failed to create " + UnicodeTestJar.getAbsolutePath());85}8687System.out.println("running test app using class file");88TestResult tr = doExec(javaCmd,89"-cp", UnicodeTestClasses.getAbsolutePath(), classname);90if (!tr.isOK()) {91System.out.println(tr);92throw new RuntimeException("test fails");93}9495System.out.println("delete generated files with non-ASCII names");96recursiveDelete(UnicodeTestSrc);97recursiveDelete(UnicodeTestClasses);9899/*100* test in whatever the default locale is101*/102runJarTests();103104/*105* if the Japanese locale is available, test in that locale as well106*/107if (setLocale(Locale.JAPANESE)) {108runJarTests();109}110111/*112* if we can switch to a C locale, then test whether jar files with113* non-ASCII characters in the manifest still work in this crippled114* environment115*/116if (setLocale(Locale.ENGLISH)) {117runJarTests();118}119// thats it we are outta here120}121122static void runJarTests() {123System.out.println("running test app using newly built jar file in " +124Locale.getDefault());125runTest(UnicodeTestJar);126127System.out.println("running test app using jar file " +128"(built with Solaris UTF-8 locale) in " + Locale.getDefault());129runTest(SolarisUnicodeTestJar);130}131132static void runTest(File testJar) {133TestResult tr = doExec(javaCmd, "-jar", testJar.getAbsolutePath());134if (!tr.isOK()) {135System.out.println(tr);136throw new RuntimeException("test fails");137}138}139140static boolean setLocale(Locale desired) {141if (Locale.getDefault().equals(desired)) {142return true; // already set nothing more143}144for (Locale l : Locale.getAvailableLocales()) {145if (l == desired) {146Locale.setDefault(l);147return true;148}149}150return false;151}152153static String generateSources() throws Exception {154String commandLineClassNameSuffix = commandLineClassNameSuffix();155String commandLineClassName = "ClassA" + commandLineClassNameSuffix;156String manifestClassName = "ClassB" +157(hasUnicodeFileSystem() ? unicode : commandLineClassNameSuffix);158159generateSource(commandLineClassName, manifestClassName);160generateSource(manifestClassName, commandLineClassName);161generateManifest(manifestClassName);162return commandLineClassName;163}164165private static final String defaultEncoding = Charset.defaultCharset().name();166167// language names taken from java.util.Locale.getDisplayLanguage for the respective language168private static final String arabic = "\u0627\u0644\u0639\u0631\u0628\u064a\u0629";169private static final String s_chinese = "\u4e2d\u6587";170private static final String t_chinese = "\u4e2d\u6587";171private static final String russian = "\u0440\u0443\u0441\u0441\u043A\u0438\u0439";172private static final String hindi = "\u0939\u093f\u0902\u0926\u0940";173private static final String greek = "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac";174private static final String hebrew = "\u05e2\u05d1\u05e8\u05d9\u05ea";175private static final String japanese = "\u65e5\u672c\u8a9e";176private static final String korean = "\ud55c\uad6d\uc5b4";177private static final String lithuanian = "Lietuvi\u0173";178private static final String czech = "\u010de\u0161tina";179private static final String turkish = "T\u00fcrk\u00e7e";180private static final String spanish = "espa\u00f1ol";181private static final String thai = "\u0e44\u0e17\u0e22";182private static final String unicode = arabic + s_chinese + t_chinese183+ russian + hindi + greek + hebrew + japanese + korean184+ lithuanian + czech + turkish + spanish + thai;185186private static String commandLineClassNameSuffix() {187188// Mapping from main platform encodings to language names189// for Unix and Windows, respectively. Use empty suffix190// for Windows encodings where OEM encoding differs.191// Use null if encoding isn't used.192String[][] names = {193{ "UTF-8", unicode, "" },194{ "windows-1256", null, "" },195{ "iso-8859-6", arabic, null },196{ "GBK", s_chinese, s_chinese },197{ "GB18030", s_chinese, s_chinese },198{ "GB2312", s_chinese, null },199{ "x-windows-950", null, t_chinese },200{ "x-MS950-HKSCS", null, t_chinese },201{ "x-euc-tw", t_chinese, null },202{ "Big5", t_chinese, null },203{ "Big5-HKSCS", t_chinese, null },204{ "windows-1251", null, "" },205{ "iso-8859-5", russian, null },206{ "koi8-r", russian, null },207{ "windows-1253", null, "" },208{ "iso-8859-7", greek, null },209{ "windows-1255", null, "" },210{ "iso8859-8", hebrew, null },211{ "windows-31j", null, japanese },212{ "x-eucJP-Open", japanese, null },213{ "x-EUC-JP-LINUX", japanese, null },214{ "x-pck", japanese, null },215{ "x-windows-949", null, korean },216{ "euc-kr", korean, null },217{ "windows-1257", null, "" },218{ "iso-8859-13", lithuanian, null },219{ "windows-1250", null, "" },220{ "iso-8859-2", czech, null },221{ "windows-1254", null, "" },222{ "iso-8859-9", turkish, null },223{ "windows-1252", null, "" },224{ "iso-8859-1", spanish, null },225{ "iso-8859-15", spanish, null },226{ "x-windows-874", null, thai },227{ "tis-620", thai, null },228};229230int column = isWindows ? 2 : 1;231for (int i = 0; i < names.length; i++) {232if (names[i][0].equalsIgnoreCase(defaultEncoding)) {233return names[i][column];234}235}236return "";237}238239private static boolean hasUnicodeFileSystem() {240return (isWindows) ? true : defaultEncoding.equalsIgnoreCase("UTF-8");241}242243private static void generateSource(String thisClass, String otherClass) throws Exception {244File file = new File(UnicodeTestSrc, thisClass + JAVA_FILE_EXT);245OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");246out.write("public class " + thisClass + " {\n");247out.write(" public static void main(String[] args) {\n");248out.write(" if (!" + otherClass + "." + otherClass.toLowerCase() + "().equals(\"" + otherClass + "\")) {\n");249out.write(" throw new RuntimeException();\n");250out.write(" }\n");251out.write(" }\n");252out.write(" public static String " + thisClass.toLowerCase() + "() {\n");253out.write(" return \"" + thisClass + "\";\n");254out.write(" }\n");255out.write("}\n");256out.close();257}258259private static void generateManifest(String mainClass) throws Exception {260File file = new File(UnicodeTestSrc, "MANIFEST.MF");261FileOutputStream out = new FileOutputStream(file);262out.write("Manifest-Version: 1.0\n".getBytes("UTF-8"));263// Header lines are limited to 72 bytes.264// The manifest spec doesn't say we have to break at character boundaries,265// so we rudely break at byte boundaries.266byte[] headerBytes = ("Main-Class: " + mainClass + "\n").getBytes("UTF-8");267if (headerBytes.length <= 72) {268out.write(headerBytes);269} else {270out.write(headerBytes, 0, 72);271int start = 72;272while (headerBytes.length > start) {273out.write((byte) '\n');274out.write((byte) ' ');275int count = Math.min(71, headerBytes.length - start);276out.write(headerBytes, start, count);277start += count;278}279}280out.close();281}282}283284285