--- a/jdk/src/java.base/share/classes/java/lang/Class.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Mon Jul 18 13:33:23 2016 -0700
@@ -238,15 +238,11 @@
TypeVariable<?>[] typeparms = component.getTypeParameters();
if (typeparms.length > 0) {
- boolean first = true;
- sb.append('<');
+ StringJoiner sj = new StringJoiner(",", "<", ">");
for(TypeVariable<?> typeparm: typeparms) {
- if (!first)
- sb.append(',');
- sb.append(typeparm.getTypeName());
- first = false;
+ sj.add(typeparm.getTypeName());
}
- sb.append('>');
+ sb.append(sj.toString());
}
for (int i = 0; i < arrayDepth; i++)
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -28,6 +28,7 @@
import java.lang.annotation.*;
import java.util.Map;
import java.util.Objects;
+import java.util.StringJoiner;
import jdk.internal.misc.SharedSecrets;
import sun.reflect.annotation.AnnotationParser;
@@ -86,15 +87,6 @@
getDeclaringClass());
}
- void separateWithCommas(Class<?>[] types, StringBuilder sb) {
- for (int j = 0; j < types.length; j++) {
- sb.append(types[j].getTypeName());
- if (j < (types.length - 1))
- sb.append(",");
- }
-
- }
-
void printModifiersIfNonzero(StringBuilder sb, int mask, boolean isDefault) {
int mod = getModifiers() & mask;
@@ -121,13 +113,20 @@
printModifiersIfNonzero(sb, modifierMask, isDefault);
specificToStringHeader(sb);
-
sb.append('(');
- separateWithCommas(parameterTypes, sb);
+ StringJoiner sj = new StringJoiner(",");
+ for (Class<?> parameterType : parameterTypes) {
+ sj.add(parameterType.getTypeName());
+ }
+ sb.append(sj.toString());
sb.append(')');
+
if (exceptionTypes.length > 0) {
- sb.append(" throws ");
- separateWithCommas(exceptionTypes, sb);
+ StringJoiner joiner = new StringJoiner(",", "throws ", "");
+ for (Class<?> exceptionType : exceptionTypes) {
+ joiner.add(exceptionType.getTypeName());
+ }
+ sb.append(joiner.toString());
}
return sb.toString();
} catch (Exception e) {
@@ -149,42 +148,34 @@
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
- boolean first = true;
- sb.append('<');
+ StringJoiner sj = new StringJoiner(",", "<", "> ");
for(TypeVariable<?> typeparm: typeparms) {
- if (!first)
- sb.append(',');
- // Class objects can't occur here; no need to test
- // and call Class.getName().
- sb.append(typeparm.toString());
- first = false;
+ sj.add(typeparm.getTypeName());
}
- sb.append("> ");
+ sb.append(sj.toString());
}
specificToGenericStringHeader(sb);
sb.append('(');
+ StringJoiner sj = new StringJoiner(",");
Type[] params = getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = params[j].getTypeName();
if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
- sb.append(param);
- if (j < (params.length - 1))
- sb.append(',');
+ sj.add(param);
}
+ sb.append(sj.toString());
sb.append(')');
- Type[] exceptions = getGenericExceptionTypes();
- if (exceptions.length > 0) {
- sb.append(" throws ");
- for (int k = 0; k < exceptions.length; k++) {
- sb.append((exceptions[k] instanceof Class)?
- ((Class)exceptions[k]).getName():
- exceptions[k].toString());
- if (k < (exceptions.length - 1))
- sb.append(',');
+
+ Type[] exceptionTypes = getGenericExceptionTypes();
+ if (exceptionTypes.length > 0) {
+ StringJoiner joiner = new StringJoiner(",", " throws ", "");
+ for (Type exceptionType : exceptionTypes) {
+ joiner.add(exceptionType.getTypeName());
}
+ sb.append(joiner.toString());
}
return sb.toString();
} catch (Exception e) {
--- a/jdk/src/java.base/share/classes/module-info.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java Mon Jul 18 13:33:23 2016 -0700
@@ -282,15 +282,18 @@
jdk.security.auth;
exports sun.text.resources to
jdk.localedata;
- exports sun.util.resources to
- jdk.localedata;
+ exports sun.util.cldr to
+ jdk.jlink;
exports sun.util.locale.provider to
java.desktop,
+ jdk.jlink,
jdk.localedata;
exports sun.util.logging to
java.desktop,
java.logging,
java.prefs;
+ exports sun.util.resources to
+ jdk.localedata;
// JDK-internal service types
uses jdk.internal.logger.DefaultLoggerFinder;
--- a/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, 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
@@ -1707,7 +1707,7 @@
*/
public InputStream nameList(String path) throws sun.net.ftp.FtpProtocolException, IOException {
Socket s;
- s = openDataConnection("NLST " + path);
+ s = openDataConnection(path == null ? "NLST" : "NLST " + path);
if (s != null) {
return createInputStream(s.getInputStream());
}
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -65,15 +65,7 @@
}
public String toString() {
- Type componentType = getGenericComponentType();
- StringBuilder sb = new StringBuilder();
-
- if (componentType instanceof Class)
- sb.append(((Class)componentType).getName() );
- else
- sb.append(componentType.toString());
- sb.append("[]");
- return sb.toString();
+ return getGenericComponentType().getTypeName() + "[]";
}
@Override
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -33,6 +33,7 @@
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
+import java.util.StringJoiner;
import java.util.Objects;
/** Implementing class for ParameterizedType interface. */
@@ -207,12 +208,9 @@
StringBuilder sb = new StringBuilder();
if (ownerType != null) {
- if (ownerType instanceof Class)
- sb.append(((Class)ownerType).getName());
- else
- sb.append(ownerType.toString());
+ sb.append(ownerType.getTypeName());
- sb.append(".");
+ sb.append("$");
if (ownerType instanceof ParameterizedTypeImpl) {
// Find simple name of nested type by removing the
@@ -220,21 +218,17 @@
sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
""));
} else
- sb.append(rawType.getName());
+ sb.append(rawType.getSimpleName());
} else
sb.append(rawType.getName());
- if (actualTypeArguments != null &&
- actualTypeArguments.length > 0) {
- sb.append("<");
- boolean first = true;
+ if (actualTypeArguments != null) {
+ StringJoiner sj = new StringJoiner(", ", "<", ">");
+ sj.setEmptyValue("");
for(Type t: actualTypeArguments) {
- if (!first)
- sb.append(", ");
- sb.append(t.getTypeName());
- first = false;
+ sj.add(t.getTypeName());
}
- sb.append(">");
+ sb.append(sj.toString());
}
return sb.toString();
--- a/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -32,6 +32,7 @@
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
import java.util.Arrays;
+import java.util.StringJoiner;
/**
@@ -156,14 +157,12 @@
assert bounds.length > 0;
- boolean first = true;
+ StringJoiner sj = new StringJoiner(" & ");
for(Type bound: bounds) {
- if (!first)
- sb.append(" & ");
+ sj.add(bound.getTypeName());
+ }
+ sb.append(sj.toString());
- first = false;
- sb.append(bound.getTypeName());
- }
return sb.toString();
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Mon Jul 18 13:33:23 2016 -0700
@@ -24,6 +24,7 @@
*/
package jdk.tools.jlink.internal.plugins;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.IllformedLocaleException;
@@ -31,6 +32,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import static java.util.ResourceBundle.Control;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
@@ -45,6 +47,10 @@
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.Plugin;
+import sun.util.cldr.CLDRBaseLocaleDataMetaInfo;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleProviderAdapter.Type;
+import sun.util.locale.provider.ResourceBundleBasedAdapter;
/**
* Plugin to explicitly specify the locale data included in jdk.localedata
@@ -95,6 +101,42 @@
private List<Locale> available;
private List<String> filtered;
+ private static final ResourceBundleBasedAdapter CLDR_ADAPTER =
+ (ResourceBundleBasedAdapter)LocaleProviderAdapter.forType(Type.CLDR);
+ private static final Map<Locale, String[]> CLDR_PARENT_LOCALES =
+ new CLDRBaseLocaleDataMetaInfo().parentLocales();
+
+ // Equivalent map
+ private static final Map<String, List<String>> EQUIV_MAP =
+ Stream.concat(
+ // COMPAT equivalence
+ Map.of(
+ "zh-Hans", List.of("zh-Hans", "zh-CN", "zh-SG"),
+ "zh-Hant", List.of("zh-Hant", "zh-HK", "zh-MO", "zh-TW"))
+ .entrySet()
+ .stream(),
+
+ // CLDR parent locales
+ CLDR_PARENT_LOCALES.entrySet().stream()
+ .map(entry -> {
+ String parent = entry.getKey().toLanguageTag();
+ List<String> children = new ArrayList<>();
+ children.add(parent);
+
+ Arrays.stream(entry.getValue())
+ .filter(child -> !child.isEmpty())
+ .flatMap(child ->
+ Stream.concat(
+ Arrays.stream(CLDR_PARENT_LOCALES.getOrDefault(
+ Locale.forLanguageTag(child), new String[0]))
+ .filter(grandchild -> !grandchild.isEmpty()),
+ List.of(child).stream()))
+ .distinct()
+ .forEach(children::add);
+ return new AbstractMap.SimpleEntry<String, List<String>>(parent, children);
+ })
+ ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
// Special COMPAT provider locales
private static final String jaJPJPTag = "ja-JP-JP";
private static final String noNONYTag = "no-NO-NY";
@@ -152,16 +194,14 @@
@Override
public void configure(Map<String, String> config) {
userParam = config.get(NAME);
- priorityList = Arrays.stream(userParam.split(","))
- .map(s -> {
- try {
- return new Locale.LanguageRange(s);
- } catch (IllegalArgumentException iae) {
- throw new IllegalArgumentException(String.format(
- PluginsResourceBundle.getMessage(NAME + ".invalidtag"), s));
- }
- })
- .collect(Collectors.toList());
+
+ try {
+ priorityList = Locale.LanguageRange.parse(userParam, EQUIV_MAP);
+ } catch (IllegalArgumentException iae) {
+ throw new IllegalArgumentException(String.format(
+ PluginsResourceBundle.getMessage(NAME + ".invalidtag"),
+ iae.getMessage().replaceFirst("^range=", "")));
+ }
}
@Override
@@ -193,6 +233,7 @@
// jdk.localedata is not added.
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".localedatanotfound"));
}
+
filtered = filterLocales(available);
if (filtered.isEmpty()) {
@@ -205,56 +246,26 @@
filtered.stream().flatMap(s -> includeLocaleFilePatterns(s).stream()))
.map(s -> "regex:" + s)
.collect(Collectors.toList());
+
predicate = ResourceFilter.includeFilter(value);
}
private List<String> includeLocaleFilePatterns(String tag) {
- List<String> files = new ArrayList<>();
- String pTag = tag.replaceAll("-", "_");
- int lastDelimiter = tag.length();
- String isoSpecial = pTag.matches("^(he|yi|id).*") ?
- pTag.replaceFirst("he", "iw")
- .replaceFirst("yi", "ji")
- .replaceFirst("id", "in") : "";
-
- // Add tag patterns including parents
- while (true) {
- pTag = pTag.substring(0, lastDelimiter);
- files.addAll(includeLocaleFiles(pTag));
-
- if (!isoSpecial.isEmpty()) {
- isoSpecial = isoSpecial.substring(0, lastDelimiter);
- files.addAll(includeLocaleFiles(isoSpecial));
- }
-
- lastDelimiter = pTag.lastIndexOf('_');
- if (lastDelimiter == -1) {
- break;
- }
+ // Ignore extension variations
+ if (tag.matches(".+-[a-z]-.+")) {
+ return List.of();
}
- final String lang = pTag;
-
- // Add possible special locales of the COMPAT provider
- Set.of(jaJPJPTag, noNONYTag, thTHTHTag).stream()
- .filter(stag -> lang.equals(stag.substring(0,2)))
- .map(t -> includeLocaleFiles(t.replaceAll("-", "_")))
- .forEach(files::addAll);
-
- // Add possible UN.M49 files (unconditional for now) for each language
- files.addAll(includeLocaleFiles(lang + "_[0-9]{3}"));
- if (!isoSpecial.isEmpty()) {
- files.addAll(includeLocaleFiles(isoSpecial + "_[0-9]{3}"));
- }
+ List<String> files = new ArrayList<>(includeLocaleFiles(tag.replaceAll("-", "_")));
// Add Thai BreakIterator related data files
- if (lang.equals("th")) {
+ if (tag.equals("th")) {
files.add(".+sun/text/resources/thai_dict");
files.add(".+sun/text/resources/[^_]+BreakIteratorData_th");
}
// Add Taiwan resource bundles for Hong Kong
- if (tag.startsWith("zh-HK")) {
+ if (tag.equals("zh-HK")) {
files.addAll(includeLocaleFiles("zh_TW"));
}
@@ -306,6 +317,11 @@
byte[] filteredBytes = filterLocales(locales).stream()
.collect(Collectors.joining(" "))
.getBytes();
+
+ if (filteredBytes.length > b.length) {
+ throw new InternalError("Size of filtered locales is bigger than the original one");
+ }
+
System.arraycopy(filteredBytes, 0, b, 0, filteredBytes.length);
Arrays.fill(b, filteredBytes.length, b.length, (byte)' ');
return true;
@@ -314,6 +330,9 @@
private List<String> filterLocales(List<Locale> locales) {
List<String> ret =
Locale.filter(priorityList, locales, Locale.FilteringMode.EXTENDED_FILTERING).stream()
+ .flatMap(loc -> Stream.concat(Control.getNoFallbackControl(Control.FORMAT_DEFAULT)
+ .getCandidateLocales("", loc).stream(),
+ CLDR_ADAPTER.getCandidateLocales("", loc).stream()))
.map(loc ->
// Locale.filter() does not preserve the case, which is
// significant for "variant" equality. Retrieve the original
@@ -321,15 +340,12 @@
locales.stream()
.filter(l -> l.toString().equalsIgnoreCase(loc.toString()))
.findAny()
- .orElse(Locale.ROOT)
- .toLanguageTag())
+ .orElse(Locale.ROOT))
+ .filter(loc -> !loc.equals(Locale.ROOT))
+ .flatMap(IncludeLocalesPlugin::localeToTags)
+ .distinct()
.collect(Collectors.toList());
- // no-NO-NY.toLanguageTag() returns "nn-NO", so specially handle it here
- if (ret.contains("no-NO")) {
- ret.add(noNONYTag);
- }
-
return ret;
}
@@ -338,6 +354,7 @@
// ISO3166 compatibility
tag = tag.replaceFirst("^iw", "he").replaceFirst("^ji", "yi").replaceFirst("^in", "id");
+ // Special COMPAT provider locales
switch (tag) {
case jaJPJPTag:
return jaJPJP;
@@ -351,4 +368,42 @@
return LOCALE_BUILDER.build();
}
}
+
+ private static Stream<String> localeToTags(Locale loc) {
+ String tag = loc.toLanguageTag();
+ Stream<String> ret = null;
+
+ switch (loc.getLanguage()) {
+ // ISO3166 compatibility
+ case "iw":
+ ret = List.of(tag, tag.replaceFirst("^he", "iw")).stream();
+ break;
+ case "in":
+ ret = List.of(tag, tag.replaceFirst("^id", "in")).stream();
+ break;
+ case "ji":
+ ret = List.of(tag, tag.replaceFirst("^yi", "ji")).stream();
+ break;
+
+ // Special COMPAT provider locales
+ case "ja":
+ if (loc.getCountry() == "JP") {
+ ret = List.of(tag, jaJPJPTag).stream();
+ }
+ break;
+ case "no":
+ case "nn":
+ if (loc.getCountry() == "NO") {
+ ret = List.of(tag, noNONYTag).stream();
+ }
+ break;
+ case "th":
+ if (loc.getCountry() == "TH") {
+ ret = List.of(tag, thTHTHTag).stream();
+ }
+ break;
+ }
+
+ return ret == null ? List.of(tag).stream() : ret;
+ }
}
--- a/jdk/test/java/lang/Class/GenericStringTest.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/test/java/lang/Class/GenericStringTest.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6298888 6992705
+ * @bug 6298888 6992705 8161500
* @summary Check Class.toGenericString()
* @author Joseph D. Darcy
*/
@@ -58,15 +58,11 @@
f = GenericStringTest.class.getDeclaredField("mixed2");
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[][]");
- Class<?>[] types = {
- GenericStringTest.class,
- AnInterface.class,
- LocalMap.class,
- AnEnum.class,
- AnotherEnum.class,
- };
-
- for(Class<?> clazz : types) {
+ for(Class<?> clazz : List.of(GenericStringTest.class,
+ AnInterface.class,
+ LocalMap.class,
+ AnEnum.class,
+ AnotherEnum.class)) {
failures += checkToGenericString(clazz, clazz.getAnnotation(ExpectedGenericString.class).value());
}
--- a/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/test/java/lang/reflect/Constructor/GenericStringTest.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 5033583 6316717 6470106
+ * @bug 5033583 6316717 6470106 8161500
* @summary Check toGenericString() and toString() methods
* @author Joseph D. Darcy
*/
@@ -35,12 +35,8 @@
public class GenericStringTest {
public static void main(String argv[]) throws Exception{
int failures = 0;
- List<Class<?>> classList = new LinkedList<Class<?>>();
- classList.add(TestClass1.class);
- classList.add(TestClass2.class);
-
- for(Class<?> clazz: classList)
+ for(Class<?> clazz: List.of(TestClass1.class, TestClass2.class))
for(Constructor<?> ctor: clazz.getDeclaredConstructors()) {
ExpectedGenericString egs = ctor.getAnnotation(ExpectedGenericString.class);
String actual = ctor.toGenericString();
--- a/jdk/test/java/lang/reflect/Field/GenericStringTest.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/test/java/lang/reflect/Field/GenericStringTest.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 5033583
+ * @bug 5033583 8161500
* @summary Check toGenericString() method
* @author Joseph D. Darcy
*/
@@ -35,12 +35,8 @@
public class GenericStringTest {
public static void main(String argv[]) throws Exception {
int failures = 0;
- List<Class> classList = new LinkedList<Class>();
- classList.add(TestClass1.class);
- classList.add(TestClass2.class);
-
- for(Class clazz: classList)
+ for(Class clazz: List.of(TestClass1.class, TestClass2.class))
for(Field field: clazz.getDeclaredFields()) {
ExpectedString es = field.getAnnotation(ExpectedString.class);
String genericString = field.toGenericString();
@@ -61,15 +57,15 @@
class TestClass1 {
@ExpectedString("int TestClass1.field1")
- int field1;
+ int field1;
@ExpectedString("private static java.lang.String TestClass1.field2")
- private static String field2;
+ private static String field2;
}
class TestClass2<E> {
@ExpectedString("public E TestClass2.field1")
- public E field1;
+ public E field1;
}
@Retention(RetentionPolicy.RUNTIME)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Generics/TestGenericReturnTypeToString.java Mon Jul 18 13:33:23 2016 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/*
+ * @test
+ * @bug 8054213
+ * @summary Check that toString method works properly for generic return type
+ * obtained via reflection
+ * @run main TestGenericReturnTypeToString
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class TestGenericReturnTypeToString {
+
+ public static void main(String[] args) {
+ boolean hasFailures = false;
+ for (Method method : TestGenericReturnTypeToString.class.getMethods()) {
+ if (method.isAnnotationPresent(ExpectedGenericString.class)) {
+ ExpectedGenericString es = method.getAnnotation
+ (ExpectedGenericString.class);
+ String result = method.getGenericReturnType().toString();
+ if (!es.value().equals(result)) {
+ hasFailures = true;
+ System.err.println("Unexpected result of " +
+ "getGenericReturnType().toString() " +
+ " for " + method.getName()
+ + " expected: " + es.value() + " actual: " + result);
+ }
+ }
+ if (hasFailures) {
+ throw new RuntimeException("Test failed");
+ }
+ }
+ }
+
+ @ExpectedGenericString("TestGenericReturnTypeToString$" +
+ "FirstInnerClassGeneric<Dummy>$SecondInnerClassGeneric<Dummy>")
+ public FirstInnerClassGeneric<Dummy>.SecondInnerClassGeneric<Dummy> foo1() {
+ return null;
+ }
+
+ @ExpectedGenericString("TestGenericReturnTypeToString$" +
+ "FirstInnerClassGeneric<Dummy>$SecondInnerClass")
+ public FirstInnerClassGeneric<Dummy>.SecondInnerClass foo2() {
+ return null;
+ }
+
+ @ExpectedGenericString("TestGenericReturnTypeToString$" +
+ "FirstInnerClass$SecondInnerClassGeneric<Dummy>")
+ public FirstInnerClass.SecondInnerClassGeneric<Dummy> foo3() {
+ return null;
+ }
+
+ @ExpectedGenericString("class TestGenericReturnTypeToString$" +
+ "FirstInnerClass$SecondInnerClass")
+ public FirstInnerClass.SecondInnerClass foo4() {
+ return null;
+ }
+
+ @ExpectedGenericString(
+ "java.util.List<java.lang.String>")
+ public java.util.List<java.lang.String> foo5() {
+ return null;
+ }
+
+ @ExpectedGenericString("interface TestGenericReturnTypeToString$" +
+ "FirstInnerClass$Interface")
+ public FirstInnerClass.Interface foo6() {
+ return null;
+ }
+
+ @ExpectedGenericString("TestGenericReturnTypeToString$" +
+ "FirstInnerClass$InterfaceGeneric<Dummy>")
+ public FirstInnerClass.InterfaceGeneric<Dummy> foo7() {
+ return null;
+ }
+
+ public static class FirstInnerClass {
+
+ public class SecondInnerClassGeneric<T> {
+ }
+
+ public class SecondInnerClass {
+ }
+
+ interface Interface {
+ }
+
+ interface InterfaceGeneric<T> {
+ }
+ }
+
+ public class FirstInnerClassGeneric<T> {
+
+ public class SecondInnerClassGeneric<T> {
+ }
+
+ public class SecondInnerClass {
+ }
+ }
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface ExpectedGenericString {
+ String value();
+}
+
+class Dummy {
+}
--- a/jdk/test/java/lang/reflect/Method/GenericStringTest.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/test/java/lang/reflect/Method/GenericStringTest.java Mon Jul 18 13:33:23 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 5033583 6316717 6470106 8004979
+ * @bug 5033583 6316717 6470106 8004979 8161500
* @summary Check toGenericString() and toString() methods
* @author Joseph D. Darcy
*/
@@ -35,14 +35,9 @@
public class GenericStringTest {
public static void main(String argv[]) throws Exception {
int failures = 0;
- List<Class<?>> classList = new LinkedList<Class<?>>();
- classList.add(TestClass1.class);
- classList.add(TestClass2.class);
- classList.add(Roebling.class);
- classList.add(TestInterface1.class);
-
- for(Class<?> clazz: classList)
+ for(Class<?> clazz: List.of(TestClass1.class, TestClass2.class,
+ Roebling.class, TestInterface1.class))
for(Method method: clazz.getDeclaredMethods()) {
ExpectedGenericString egs = method.getAnnotation(ExpectedGenericString.class);
if (egs != null) {
@@ -121,6 +116,30 @@
@ExpectedGenericString(
"public void TestClass2.method2() throws F")
public void method2() throws F {return;}
+
+ @ExpectedGenericString(
+ "public E[] TestClass2.method3()")
+ public E[] method3() {return null;}
+
+ @ExpectedGenericString(
+ "public E[][] TestClass2.method4()")
+ public E[][] method4() {return null;}
+
+ @ExpectedGenericString(
+ "public java.util.List<E[]> TestClass2.method5()")
+ public List<E[]> method5() {return null;}
+
+ @ExpectedGenericString(
+ "public java.util.List<?> TestClass2.method6()")
+ public List<?> method6() {return null;}
+
+ @ExpectedGenericString(
+ "public java.util.List<?>[] TestClass2.method7()")
+ public List<?>[] method7() {return null;}
+
+ @ExpectedGenericString(
+ "public <K,V> java.util.Map<K, V> TestClass2.method8()")
+ public <K, V> Map<K, V> method8() {return null;}
}
class Roebling implements Comparable<Roebling> {
@@ -157,7 +176,6 @@
@ExpectedGenericString(
"public default strictfp double TestInterface1.quux()")
strictfp default double quux(){return 1.0;}
-
}
@Retention(RetentionPolicy.RUNTIME)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/ftp/TestFtpClientNameListWithNull.java Mon Jul 18 13:33:23 2016 -0700
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2016, 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
+ * @bug 8022580
+ * @summary "null" should be treated as "current directory" in nameList()
+ * method of FtpClient
+ * @modules java.base/sun.net.ftp
+ * @run main TestFtpClientNameListWithNull
+*/
+
+
+import sun.net.ftp.FtpClient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+
+
+public class TestFtpClientNameListWithNull {
+
+ private static volatile boolean commandHasArgs;
+
+ public static void main(String[] args) throws Exception {
+ try (FtpServer server = new FtpServer();
+ FtpClient client = FtpClient.create()) {
+ (new Thread(server)).start();
+ int port = server.getPort();
+ client.connect(new InetSocketAddress("localhost", port));
+ client.nameList(null);
+ } finally {
+ if (commandHasArgs) {
+ throw new RuntimeException("Test failed. NLST shouldn't have " +
+ "args if nameList parameter is null");
+ }
+ }
+ }
+
+ private static class FtpServer implements AutoCloseable, Runnable {
+ private final ServerSocket serverSocket;
+
+ FtpServer() throws IOException {
+ serverSocket = new ServerSocket(0);
+ }
+
+ public void handleClient(Socket client) throws IOException {
+ boolean done = false;
+ String str;
+
+ client.setSoTimeout(2000);
+ BufferedReader in = new BufferedReader(new InputStreamReader(client.
+ getInputStream()));
+ PrintWriter out = new PrintWriter(client.getOutputStream(), true);
+ out.println("220 FTP serverSocket is ready.");
+ while (!done) {
+ try {
+ str = in.readLine();
+ } catch (SocketException e) {
+ done = true;
+ continue;
+ }
+ String cmd = str.substring(0, str.indexOf(" ") > 0 ?
+ str.indexOf(" ") : str.length());
+ String args = (cmd.equals(str)) ?
+ "" : str.substring(str.indexOf(" "));
+ switch (cmd) {
+ case "QUIT":
+ out.println("221 Goodbye.");
+ out.flush();
+ done = true;
+ break;
+ case "EPSV":
+ if ("all".equalsIgnoreCase(args)) {
+ out.println("200 EPSV ALL command successful.");
+ continue;
+ }
+ out.println("229 Entering Extended Passive Mode " +
+ "(|||" + getPort() + "|)");
+ break;
+ case "NLST":
+ if (args.trim().length() != 0) {
+ commandHasArgs = true;
+ }
+ out.println("200 Command okay.");
+ break;
+ default:
+ out.println("500 unsupported command: " + str);
+ }
+ }
+ }
+
+ public int getPort() {
+ if (serverSocket != null) {
+ return serverSocket.getLocalPort();
+ }
+ return 0;
+ }
+
+ public void close() throws IOException {
+ if (serverSocket != null && !serverSocket.isClosed()) {
+ serverSocket.close();
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ try (Socket client = serverSocket.accept()) {
+ handleClient(client);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Problem in test execution", e);
+ }
+ }
+ }
+}
--- a/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java Mon Jul 18 09:38:08 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java Mon Jul 18 13:33:23 2016 -0700
@@ -90,6 +90,71 @@
"",
},
+ // Asterisk works exactly the same as above
+ {
+ "*",
+ "jdk.localedata",
+ List.of(
+ "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_zh.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
+ List.of(),
+ Arrays.stream(Locale.getAvailableLocales())
+ // "(root)" for Locale.ROOT rather than ""
+ .map(loc -> loc.equals(Locale.ROOT) ? "(root)" : loc.toString())
+ .collect(Collectors.toList()),
+ "",
+ },
+
+ // World English/Spanish in Latin America
+ {
+ "--include-locales=en-001,es-419",
+ "jdk.localedata",
+ List.of(
+ "/jdk.localedata/sun/text/resources/ext/FormatData_en_AU.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_es.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_es_AR.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_419.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_es_AR.class"),
+ List.of(
+ "/jdk.localedata/sun/text/resources/LineBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/thai_dict",
+ "/jdk.localedata/sun/text/resources/WordBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorRules_th.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
+ List.of(
+ "(root)", "en", "en_US", "en_US_POSIX", "en_001", "en_150", "en_AG", "en_AI",
+ "en_AT", "en_AU", "en_BB", "en_BE", "en_BM", "en_BS", "en_BW", "en_BZ",
+ "en_CA", "en_CC", "en_CH", "en_CK", "en_CM", "en_CX", "en_CY", "en_DE",
+ "en_DG", "en_DK", "en_DM", "en_ER", "en_FI", "en_FJ", "en_FK", "en_FM",
+ "en_GB", "en_GD", "en_GG", "en_GH", "en_GI", "en_GM", "en_GY", "en_HK",
+ "en_IE", "en_IL", "en_IM", "en_IN", "en_IO", "en_JE", "en_JM", "en_KE",
+ "en_KI", "en_KN", "en_KY", "en_LC", "en_LR", "en_LS", "en_MG", "en_MO",
+ "en_MS", "en_MT", "en_MU", "en_MW", "en_MY", "en_NA", "en_NF", "en_NG",
+ "en_NL", "en_NR", "en_NU", "en_NZ", "en_PG", "en_PH", "en_PK", "en_PN",
+ "en_PW", "en_RW", "en_SB", "en_SC", "en_SD", "en_SE", "en_SG", "en_SH",
+ "en_SI", "en_SL", "en_SS", "en_SX", "en_SZ", "en_TC", "en_TK", "en_TO",
+ "en_TT", "en_TV", "en_TZ", "en_UG", "en_VC", "en_VG", "en_VU", "en_WS",
+ "en_ZA", "en_ZM", "en_ZW", "es", "es_419", "es_AR", "es_BO", "es_BR",
+ "es_CL", "es_CO", "es_CR", "es_CU", "es_DO", "es_EC", "es_GT", "es_HN",
+ "es_MX", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US",
+ "es_UY", "es_VE"),
+ "",
+ },
+
// All English and Japanese locales
{
"--include-locales=en,ja",
@@ -128,6 +193,35 @@
"",
},
+ // All locales in Austria
+ {
+ "--include-locales=*-AT",
+ "jdk.localedata",
+ List.of(
+ "/jdk.localedata/sun/text/resources/ext/FormatData_de.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_de_AT.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_de_AT.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_150.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_AT.class"),
+ List.of(
+ "/jdk.localedata/sun/text/resources/LineBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/thai_dict",
+ "/jdk.localedata/sun/text/resources/WordBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorRules_th.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
+ List.of(
+ "(root)", "en", "en_US", "en_US_POSIX", "en_001", "en_150", "en_AT",
+ "de", "de_AT"),
+ "",
+ },
+
// All locales in India
{
"--include-locales=*-IN",
@@ -154,10 +248,11 @@
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
List.of(
- "(root)", "as_IN", "bn_IN", "bo_IN", "brx_IN", "en", /* "en_001", */
- "en_IN", "en_US", "en_US_POSIX", "gu_IN", "hi_IN", "kn_IN", "kok_IN",
- "ks_IN", "ml_IN", "mr_IN", "ne_IN", "or_IN", "pa_IN", "pa_IN_#Guru",
- "ta_IN", "te_IN", "ur_IN"),
+ "(root)", "as_IN", "as", "bn_IN", "bn", "bo_IN", "bo", "brx_IN", "brx",
+ "en", "en_001", "en_IN", "en_US", "en_US_POSIX", "gu_IN", "gu", "hi_IN",
+ "hi", "kn_IN", "kn", "kok_IN", "kok", "ks_IN", "ks", "ml_IN", "ml",
+ "mr_IN", "mr", "ne_IN", "ne", "or_IN", "or", "pa_IN", "pa", "pa_IN_#Guru",
+ "pa__#Guru", "ta_IN", "ta", "te_IN", "te", "ur_IN", "ur"),
"",
},
@@ -203,12 +298,40 @@
"/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
"/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_zh_CN.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
List.of(
- "(root)", "en", "en_US", "en_US_POSIX", "zh_HK", "zh_HK_#Hans",
- "zh_HK_#Hant"),
+ "(root)", "en", "en_US", "en_US_POSIX", "zh", "zh__#Hans", "zh__#Hant",
+ "zh_HK", "zh_HK_#Hans", "zh_HK_#Hant"),
+ "",
+ },
+
+ // Simplified Chinese
+ {
+ "--include-locales=zh-Hans",
+ "jdk.localedata",
+ List.of(
+ "/jdk.localedata/sun/text/resources/ext/FormatData_zh.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_zh_CN.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_zh_SG.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
+ List.of(
+ "/jdk.localedata/sun/text/resources/LineBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/thai_dict",
+ "/jdk.localedata/sun/text/resources/WordBreakIteratorData_th",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class",
+ "/jdk.localedata/sun/text/resources/ext/BreakIteratorRules_th.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_en_001.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
+ "/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
+ List.of(
+ "(root)", "en", "en_US", "en_US_POSIX", "zh", "zh__#Hans", "zh_CN",
+ "zh_CN_#Hans", "zh_HK_#Hans", "zh_MO_#Hans", "zh_SG", "zh_SG_#Hans"),
"",
},
@@ -290,7 +413,7 @@
null,
null,
new PluginException(String.format(
- PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_HK"))
+ PluginsResourceBundle.getMessage("include-locales.invalidtag"), "zh_hk"))
.getMessage(),
},