8266036: class file for sun.misc.Contended not found

8258421: (jdeprscan) tools/jdeprscan/tests/jdk/jdeprscan/TestRelease.java failed with "error: cannot access jdk.internal.ValueBased"

Reviewed-by: darcy
This commit is contained in:
Jan Lahoda 2021-07-07 09:49:53 +00:00
parent a49b1dc704
commit 7fcd5ca025
15 changed files with 309 additions and 110 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2021, 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
@ -229,6 +229,7 @@ public class CreateSymbols {
: null,
Paths.get(ctDescriptionFile));
stripNonExistentAnnotations(data);
splitHeaders(data.classes);
Map<String, Map<Character, String>> package2Version2Module = new HashMap<>();
@ -301,6 +302,50 @@ public class CreateSymbols {
}
}
private static final String PREVIEW_FEATURE_ANNOTATION_OLD =
"Ljdk/internal/PreviewFeature;";
private static final String PREVIEW_FEATURE_ANNOTATION_NEW =
"Ljdk/internal/javac/PreviewFeature;";
private static final String PREVIEW_FEATURE_ANNOTATION_INTERNAL =
"Ljdk/internal/PreviewFeature+Annotation;";
private static final String VALUE_BASED_ANNOTATION =
"Ljdk/internal/ValueBased;";
private static final String VALUE_BASED_ANNOTATION_INTERNAL =
"Ljdk/internal/ValueBased+Annotation;";
public static final Set<String> HARDCODED_ANNOTATIONS = new HashSet<>(
List.of("Ljdk/Profile+Annotation;",
"Lsun/Proprietary+Annotation;",
PREVIEW_FEATURE_ANNOTATION_OLD,
PREVIEW_FEATURE_ANNOTATION_NEW,
VALUE_BASED_ANNOTATION));
private void stripNonExistentAnnotations(LoadDescriptions data) {
Set<String> allClasses = data.classes.name2Class.keySet();
data.modules.values().forEach(mod -> {
stripNonExistentAnnotations(allClasses, mod.header);
});
data.classes.classes.forEach(clazz -> {
stripNonExistentAnnotations(allClasses, clazz.header);
stripNonExistentAnnotations(allClasses, clazz.fields);
stripNonExistentAnnotations(allClasses, clazz.methods);
});
}
private void stripNonExistentAnnotations(Set<String> allClasses, Iterable<? extends FeatureDescription> descs) {
descs.forEach(d -> stripNonExistentAnnotations(allClasses, d));
}
private void stripNonExistentAnnotations(Set<String> allClasses, FeatureDescription d) {
stripNonExistentAnnotations(allClasses, d.classAnnotations);
stripNonExistentAnnotations(allClasses, d.runtimeAnnotations);
}
private void stripNonExistentAnnotations(Set<String> allClasses, List<AnnotationDescription> annotations) {
if (annotations != null)
annotations.removeIf(ann -> !HARDCODED_ANNOTATIONS.contains(ann.annotationType) &&
!allClasses.contains(ann.annotationType.substring(1, ann.annotationType.length() - 1)));
}
private ZipEntry createZipEntry(String name, long timestamp) {
ZipEntry ze = new ZipEntry(name);
@ -1140,17 +1185,16 @@ public class CreateSymbols {
values.put("reflective", essentialAPI != null && !essentialAPI);
}
if (VALUE_BASED_ANNOTATION.equals(annotationType)) {
//the non-public ValueBased annotation will not be available in ct.sym,
//replace with purely synthetic javac-internal annotation:
annotationType = VALUE_BASED_ANNOTATION_INTERNAL;
}
return new Annotation(null,
addString(constantPool, annotationType),
createElementPairs(constantPool, values));
}
//where:
private static final String PREVIEW_FEATURE_ANNOTATION_OLD =
"Ljdk/internal/PreviewFeature;";
private static final String PREVIEW_FEATURE_ANNOTATION_NEW =
"Ljdk/internal/javac/PreviewFeature;";
private static final String PREVIEW_FEATURE_ANNOTATION_INTERNAL =
"Ljdk/internal/PreviewFeature+Annotation;";
private element_value_pair[] createElementPairs(List<CPInfo> constantPool, Map<String, Object> annotationAttributes) {
element_value_pair[] pairs = new element_value_pair[annotationAttributes.size()];

View File

@ -35,6 +35,11 @@ import static java.lang.annotation.ElementType.TYPE;
* References to <a href="../lang/doc-files/ValueBased.html">value-based classes</a>
* should produce warnings about behavior that is inconsistent with value based semantics.
*
* Note this internal annotation is handled specially by the javac compiler.
* To work properly with {@code --release older-release}, it requires special
* handling in {@code make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java}
* and {@code src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java}.
*
* @since 16
*/
@Retention(RetentionPolicy.RUNTIME)

View File

@ -31,6 +31,12 @@ import java.lang.annotation.Target;
/**
* The element annotated with this annotation should not be marked as a preview element.
*
* Note this internal annotation is handled specially by the javac compiler.
* To work properly with {@code --release older-release}, it requires special
* handling in {@code make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java}
* and {@code src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java}.
*
*/
@Target({ElementType.METHOD,
ElementType.CONSTRUCTOR,

View File

@ -31,6 +31,12 @@ import java.lang.annotation.*;
* Indicates the API declaration in question is associated with a
* <em>preview feature</em>. See JEP 12: "Preview Language and VM
* Features" (http://openjdk.java.net/jeps/12).
*
* Note this internal annotation is handled specially by the javac compiler.
* To work properly with {@code --release older-release}, it requires special
* handling in {@code make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java}
* and {@code src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java}.
*
* @since 14
*/
// Match the meaningful targets of java.lang.Deprecated, omit local

View File

@ -311,7 +311,12 @@ public class Flags {
/**
* Flag to indicate the given ModuleSymbol is a system module.
*/
public static final long SYSTEM_MODULE = 1L<<53;
public static final long SYSTEM_MODULE = 1L<<53; //ModuleSymbols only
/**
* Flag to indicate the given ClassSymbol is a value based.
*/
public static final long VALUE_BASED = 1L<<53; //ClassSymbols only
/**
* Flag to indicate the given symbol has a @Deprecated annotation.

View File

@ -222,6 +222,7 @@ public class Symtab {
public final Type recordType;
public final Type switchBootstrapsType;
public final Type valueBasedType;
public final Type valueBasedInternalType;
/** The symbol representing the length field of an array.
*/
@ -588,6 +589,7 @@ public class Symtab {
recordType = enterClass("java.lang.Record");
switchBootstrapsType = enterClass("java.lang.runtime.SwitchBootstraps");
valueBasedType = enterClass("jdk.internal.ValueBased");
valueBasedInternalType = enterSyntheticAnnotation("jdk.internal.ValueBased+Annotation");
synthesizeEmptyInterfaceIfMissing(autoCloseableType);
synthesizeEmptyInterfaceIfMissing(cloneableType);

View File

@ -53,6 +53,7 @@ import static com.sun.tools.javac.code.Flags.SYNTHETIC;
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
import static com.sun.tools.javac.code.Kinds.Kind.PCK;
import static com.sun.tools.javac.code.Kinds.Kind.TYP;
import static com.sun.tools.javac.code.Kinds.Kind.VAR;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
@ -369,7 +370,6 @@ public class Annotate {
}
}
// Note: @Deprecated has no effect on local variables and parameters
if (!c.type.isErroneous()
&& types.isSameType(c.type, syms.previewFeatureType)) {
toAnnotate.flags_field |= Flags.PREVIEW_API;
@ -377,6 +377,12 @@ public class Annotate {
toAnnotate.flags_field |= Flags.PREVIEW_REFLECTIVE;
}
}
if (!c.type.isErroneous()
&& toAnnotate.kind == TYP
&& types.isSameType(c.type, syms.valueBasedType)) {
toAnnotate.flags_field |= Flags.VALUE_BASED;
}
}
List<T> buf = List.nil();

View File

@ -1871,14 +1871,7 @@ public class Attr extends JCTree.Visitor {
}
// where
private boolean isValueBased(Type t) {
if (t != null && t.tsym != null) {
for (Attribute.Compound a: t.tsym.getDeclarationAttributes()) {
if (a.type.tsym == syms.valueBasedType.tsym) {
return true;
}
}
}
return false;
return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0;
}

View File

@ -1446,6 +1446,9 @@ public class ClassReader {
} else if (proxy.type.tsym.flatName() == syms.previewFeatureInternalType.tsym.flatName()) {
sym.flags_field |= PREVIEW_API;
setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
} else if (proxy.type.tsym.flatName() == syms.valueBasedInternalType.tsym.flatName()) {
Assert.check(sym.kind == TYP);
sym.flags_field |= VALUE_BASED;
} else {
if (proxy.type.tsym == syms.annotationTargetType.tsym) {
target = proxy;
@ -1457,6 +1460,8 @@ public class ClassReader {
} else if (proxy.type.tsym == syms.previewFeatureType.tsym) {
sym.flags_field |= PREVIEW_API;
setFlagIfAttributeTrue(proxy, sym, names.reflective, PREVIEW_REFLECTIVE);
} else if (proxy.type.tsym == syms.valueBasedType.tsym && sym.kind == TYP) {
sym.flags_field |= VALUE_BASED;
}
proxies.append(proxy);
}

View File

@ -72,4 +72,3 @@ tools/sjavac/ClasspathDependencies.java
#
# jdeps
tools/jdeprscan/tests/jdk/jdeprscan/TestRelease.java 8258421 generic-all Deprecation vs JDK-private annotation class

View File

@ -1,10 +1,11 @@
/*
* @test /nodynamiccopyright/
* @bug 8254274
* @bug 8254274 8258421
* @summary lint should warn when an instance of a value based class is synchronized upon
* @compile/fail/ref=ExternalAbuseOfVbc.out -XDrawDiagnostics -Werror -Xlint ExternalAbuseOfVbc.java
* @compile/fail/ref=ExternalAbuseOfVbc.out -XDrawDiagnostics -Werror -Xlint:all ExternalAbuseOfVbc.java
* @compile/fail/ref=ExternalAbuseOfVbc.out -XDrawDiagnostics -Werror -Xlint:synchronization ExternalAbuseOfVbc.java
* @compile/fail/ref=ExternalAbuseOfVbc.out --release 16 -XDrawDiagnostics -Werror -Xlint:synchronization ExternalAbuseOfVbc.java
* @compile/ref=LintModeOffAbuseOfVbc.out -XDrawDiagnostics -Werror -Xlint:-synchronization ExternalAbuseOfVbc.java
*/

View File

@ -1,4 +1,4 @@
ExternalAbuseOfVbc.java:18:13: compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class
ExternalAbuseOfVbc.java:19:13: compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class
- compiler.err.warnings.and.werror
1 error
1 warning

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021, 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 8266036 8258421
* @summary Verify no error is reported for extended ForkJoinPool with --release 8.
* @modules jdk.compiler
* @build NonPublicAnnotations
* @compile -processor NonPublicAnnotations --release 8 NonPublicAnnotations.java
*/
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("*")
public class NonPublicAnnotations extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> roots, RoundEnvironment roundEnv) {
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}
class TestForkJoinPool extends ForkJoinPool {}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
@ -215,82 +215,88 @@ public class CreateSymbolsTestImpl {
@Test
void testAnnotations() throws Exception {
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"public @Visible @Invisible class T { public void extra() { } }" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"package t;" +
"import java.lang.annotation.*;" +
"public @Visible @Invisible class T { }" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"t.T",
"package t;\n\n" +
"@t.Invisible\n" +
"@t.Visible\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void extra();\n" +
"}\n",
"t.Visible",
"package t;\n\n" +
"@java.lang.annotation.Retention(RUNTIME)\n" +
"@interface Visible {\n" +
"}\n");
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"import java.util.*;" +
"public class T {" +
" public void test(int h, @Invisible int i, @Visible List<String> j, int k) { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"package t;" +
"import java.lang.annotation.*;" +
"import java.util.*;" +
"public class T {" +
" public void test(int h, @Invisible int i, @Visible List<String> j, int k) { }" +
" public void extra() { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void test(int arg0,\n" +
" @t.Invisible int arg1,\n" +
" @t.Visible java.util.List<java.lang.String> arg2,\n" +
" int arg3);\n" +
"}\n",
"t.Visible",
"package t;\n\n" +
"@java.lang.annotation.Retention(RUNTIME)\n" +
"@interface Visible {\n" +
"}\n");
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"public class T {" +
" public void test(@Ann(v=\"url\", dv=\"\\\"\\\"\") String str) { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Ann {" +
" public String v();" +
" public String dv();" +
"}",
"package t;" +
"public class T { }",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void test(@t.Ann(dv=\"\\\"\\\"\", v=\"url\") java.lang.String arg0);\n" +
"}\n",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n" +
"}\n");
Set<String> extraAnnotations = Set.of("Ljava/lang/annotation/Retention;");
CreateSymbols.HARDCODED_ANNOTATIONS.addAll(extraAnnotations);
try {
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"public @Visible @Invisible class T { public void extra() { } }" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"package t;" +
"import java.lang.annotation.*;" +
"public @Visible @Invisible class T { }" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"t.T",
"package t;\n\n" +
"@t.Invisible\n" +
"@t.Visible\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void extra();\n" +
"}\n",
"t.Visible",
"package t;\n\n" +
"@java.lang.annotation.Retention(RUNTIME)\n" +
"@interface Visible {\n" +
"}\n");
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"import java.util.*;" +
"public class T {" +
" public void test(int h, @Invisible int i, @Visible List<String> j, int k) { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"package t;" +
"import java.lang.annotation.*;" +
"import java.util.*;" +
"public class T {" +
" public void test(int h, @Invisible int i, @Visible List<String> j, int k) { }" +
" public void extra() { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Visible { }" +
"@Retention(RetentionPolicy.CLASS) @interface Invisible { }",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void test(int arg0,\n" +
" @t.Invisible int arg1,\n" +
" @t.Visible java.util.List<java.lang.String> arg2,\n" +
" int arg3);\n" +
"}\n",
"t.Visible",
"package t;\n\n" +
"@java.lang.annotation.Retention(RUNTIME)\n" +
"@interface Visible {\n" +
"}\n");
doPrintElementTest("package t;" +
"import java.lang.annotation.*;" +
"public class T {" +
" public void test(@Ann(v=\"url\", dv=\"\\\"\\\"\") String str) { }" +
"}" +
"@Retention(RetentionPolicy.RUNTIME) @interface Ann {" +
" public String v();" +
" public String dv();" +
"}",
"package t;" +
"public class T { }",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n\n" +
" public void test(@t.Ann(dv=\"\\\"\\\"\", v=\"url\") java.lang.String arg0);\n" +
"}\n",
"t.T",
"package t;\n\n" +
"public class T {\n\n" +
" public T();\n" +
"}\n");
} finally {
CreateSymbols.HARDCODED_ANNOTATIONS.removeAll(extraAnnotations);
}
}
@Test
@ -360,11 +366,70 @@ public class CreateSymbolsTestImpl {
Expect.SUCCESS);
}
@Test
void testClearMissingAnnotations() throws Exception {
doPrintElementTest(new String[] {
"""
package t;
import t.impl.HC;
import t.impl.HR;
@HC @HR public class T {
@HC @HR public static final int i = 0;
@HC @HR public void t() {}
}
""",
"""
package t.impl;
import java.lang.annotation.*;
@Retention(RetentionPolicy.CLASS)
public @interface HC {
}
""",
"""
package t.impl;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface HR {
}
"""
},
new String[] {
"""
package t;
public class T {
public static final int i = 0;
}
"""
},
"t.T",
"""
package t;
public class T {
public static final int i = 0;
public T();
public void t();
}
""",
"t.T",
"""
package t;
public class T {
public static final int i = 0;
public T();
}
""");
}
int i = 0;
void doTest(String code7, String code8, String testCode, Expect result7, Expect result8) throws Exception {
ToolBox tb = new ToolBox();
Path classes = prepareVersionedCTSym(code7, code8);
Path classes = prepareVersionedCTSym(new String[] {code7}, new String[] {code8});
Path output = classes.getParent();
Path scratch = output.resolve("scratch");
@ -392,6 +457,10 @@ public class CreateSymbolsTestImpl {
}
void doPrintElementTest(String code7, String code8, String className7, String printed7, String className8, String printed8) throws Exception {
doPrintElementTest(new String[] {code7}, new String[] {code8}, className7, printed7, className8, printed8);
}
void doPrintElementTest(String[] code7, String[] code8, String className7, String printed7, String className8, String printed8) throws Exception {
ToolBox tb = new ToolBox();
Path classes = prepareVersionedCTSym(code7, code8);
Path output = classes.getParent();
@ -419,7 +488,7 @@ public class CreateSymbolsTestImpl {
}
void doTestEquivalence(String code7, String code8, String testClass) throws Exception {
Path classes = prepareVersionedCTSym(code7, code8);
Path classes = prepareVersionedCTSym(new String[] {code7}, new String[] {code8});
Path classfile = classes.resolve("78").resolve("java.base").resolve(testClass.replace('.', '/') + ".class");
if (!Files.isReadable(classfile)) {
@ -576,7 +645,7 @@ public class CreateSymbolsTestImpl {
boolean oldIncludeAll = includeAll;
try {
includeAll = false;
Path classes = prepareVersionedCTSym(code, "package other; public class Other {}");
Path classes = prepareVersionedCTSym(new String[] {code}, new String[] {"package other; public class Other {}"});
Path root = classes.resolve("7").resolve("java.base");
try (Stream<Path> classFiles = Files.walk(root)) {
Set<String> names = classFiles.map(p -> root.relativize(p))
@ -595,7 +664,7 @@ public class CreateSymbolsTestImpl {
}
}
Path prepareVersionedCTSym(String code7, String code8) throws Exception {
Path prepareVersionedCTSym(String[] code7, String[] code8) throws Exception {
String testClasses = System.getProperty("test.classes");
Path output = Paths.get(testClasses, "test-data" + i++);
deleteRecursively(output);
@ -694,6 +763,7 @@ public class CreateSymbolsTestImpl {
return files.filter(p -> Files.isRegularFile(p))
.filter(p -> p.getFileName().toString().endsWith(".class"))
.map(p -> root.relativize(p).toString())
.filter(p -> !p.contains("impl"))
.collect(Collectors.toList());
}
}

View File

@ -128,16 +128,16 @@ public class ElementStructureTest {
(byte) 0xB7, (byte) 0x52, (byte) 0x0F, (byte) 0x68
};
static final byte[] hash7 = new byte[] {
(byte) 0x3C, (byte) 0x03, (byte) 0xEA, (byte) 0x4A,
(byte) 0x62, (byte) 0xD2, (byte) 0x18, (byte) 0xE5,
(byte) 0xA5, (byte) 0xC2, (byte) 0xB7, (byte) 0x85,
(byte) 0x90, (byte) 0xFA, (byte) 0x98, (byte) 0xCD
(byte) 0x45, (byte) 0xCA, (byte) 0x83, (byte) 0xCD,
(byte) 0x1A, (byte) 0x68, (byte) 0x57, (byte) 0x9C,
(byte) 0x6F, (byte) 0x2D, (byte) 0xEB, (byte) 0x28,
(byte) 0xAB, (byte) 0x05, (byte) 0x53, (byte) 0x6E
};
static final byte[] hash8 = new byte[] {
(byte) 0x24, (byte) 0x38, (byte) 0x52, (byte) 0x1C,
(byte) 0x5E, (byte) 0x83, (byte) 0x82, (byte) 0xE6,
(byte) 0x41, (byte) 0xC2, (byte) 0xDD, (byte) 0x2A,
(byte) 0xFD, (byte) 0xFF, (byte) 0x5E, (byte) 0x2F
(byte) 0x26, (byte) 0x8C, (byte) 0xFD, (byte) 0x61,
(byte) 0x53, (byte) 0x00, (byte) 0x57, (byte) 0x10,
(byte) 0x36, (byte) 0x2B, (byte) 0x92, (byte) 0x0B,
(byte) 0xE1, (byte) 0x6A, (byte) 0xB5, (byte) 0xFD
};
final static Map<String, byte[]> version2Hash = new HashMap<>();