mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-01 06:09:45 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30885a997e | ||
|
|
929d5352c4 | ||
|
|
5332227582 | ||
|
|
4fb8ed7e15 | ||
|
|
b477e4bb20 | ||
|
|
91d6a17b71 | ||
|
|
99653a7246 | ||
|
|
2d4764e6a5 | ||
|
|
1a5d095ffc | ||
|
|
6e54137bec | ||
|
|
9ae2d19d82 | ||
|
|
5ed37e2ade | ||
|
|
7f2f3dd782 | ||
|
|
c0f008e54d | ||
|
|
83521a04b4 | ||
|
|
a1c716f556 |
@@ -11,8 +11,7 @@ can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntim
|
||||
|
||||
| IDE Version | Latest JBR | Date Released |
|
||||
| --- | --- | --- |
|
||||
| 2022.1 | [17_0_2-b315.1](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr17_0_2b315.1) | 09-Feb-2022 |
|
||||
| 2021.3 | [17_0_1-b164.8](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr17_0_1b164.8) | 15-Nov-2021 |
|
||||
| 2022.2 | [17.0.3-b463.3](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr17.0.3b463.3) | 24-May-2022 |
|
||||
|
||||
## Contents
|
||||
- [Welcome to JetBrains Runtime](#jetbrains-runtime)
|
||||
|
||||
@@ -63,7 +63,9 @@ function create_image_bundle {
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' $__root_dir/release > release
|
||||
mv release $__root_dir/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip $__root_dir/lib
|
||||
for dir in $(ls -d $IMAGES_DIR/jdk/*); do
|
||||
rsync -a --exclude demo --exclude sample $dir $__root_dir
|
||||
done
|
||||
copy_jmods "$__modules" "$__modules_path" "$__root_dir"/jmods
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -58,7 +58,9 @@ function create_image_bundle {
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' $__root_dir/release > release
|
||||
mv release $__root_dir/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip $__root_dir/lib
|
||||
for dir in $(ls -d $IMAGES_DIR/jdk/*); do
|
||||
rsync -a --exclude demo --exclude sample $dir $__root_dir
|
||||
done
|
||||
copy_jmods "$__modules" "$__modules_path" "$__root_dir"/jmods
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ function pack_jbr {
|
||||
__root_dir=${__bundle_name}-${JBSDK_VERSION}-x64-${fastdebug_infix:-}b${build_number%%.*}
|
||||
|
||||
echo Creating $JBR.tar.gz ...
|
||||
|
||||
chmod -R ug+rwx,o+rx ${BASE_DIR}/$__root_dir
|
||||
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR $__root_dir || do_exit $?
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ function pack_jbr {
|
||||
__root_dir=${__bundle_name}-${JBSDK_VERSION}-x86-${fastdebug_infix:-}b${build_number%%.*}
|
||||
|
||||
echo Creating $JBR.tar.gz ...
|
||||
|
||||
chmod -R ug+rwx,o+rx ${BASE_DIR}/$__root_dir
|
||||
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR $__root_dir || do_exit $?
|
||||
}
|
||||
|
||||
|
||||
@@ -1337,7 +1337,6 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
|
||||
log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
|
||||
}
|
||||
if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
|
||||
strcmp(key, "jdk.module.illegalAccess") == 0 ||
|
||||
strcmp(key, "jdk.module.validation") == 0 ||
|
||||
strcmp(key, "java.system.class.loader") == 0) {
|
||||
MetaspaceShared::disable_full_module_graph();
|
||||
@@ -2132,8 +2131,7 @@ bool Arguments::parse_uintx(const char* value,
|
||||
}
|
||||
|
||||
bool Arguments::create_module_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
|
||||
assert(is_internal_module_property(prop_name) ||
|
||||
strcmp(prop_name, "jdk.module.illegalAccess") == 0, "unknown module property: '%s'", prop_name);
|
||||
assert(is_internal_module_property(prop_name), "unknown module property: '%s'", prop_name);
|
||||
size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
|
||||
char* property = AllocateHeap(prop_len, mtArguments);
|
||||
int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
|
||||
@@ -2505,10 +2503,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
|
||||
char version[256];
|
||||
JDK_Version::jdk(17).to_string(version, sizeof(version));
|
||||
warning("Ignoring option %s; support was removed in %s", option->optionString, version);
|
||||
} else if (match_option(option, "--jbr-illegal-access", &tail)) {
|
||||
if (!create_module_property("jdk.module.illegalAccess", "permit", ExternalProperty)) {
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
// -agentlib and -agentpath
|
||||
} else if (match_option(option, "-agentlib:", &tail) ||
|
||||
(is_absolute_path = match_option(option, "-agentpath:", &tail))) {
|
||||
|
||||
@@ -68,14 +68,4 @@ class ExplodedSystemModules implements SystemModules {
|
||||
public Map<String, Set<String>> moduleReads() {
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Set<String>> concealedPackagesToOpen() {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Set<String>> exportedPackagesToOpen() {
|
||||
return Map.of();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.internal.module;
|
||||
|
||||
import sun.nio.cs.UTF_8;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Generates the maps of concealed and exported packages to open at run-time.
|
||||
*
|
||||
* This is used at run-time for exploded builds, and at link-time to generate
|
||||
* the maps for the system modules in the run-time image.
|
||||
*/
|
||||
|
||||
public class IllegalAccessMaps {
|
||||
private final Map<String, Set<String>> concealedPackagesToOpen;
|
||||
private final Map<String, Set<String>> exportedPackagesToOpen;
|
||||
|
||||
private IllegalAccessMaps(Map<String, Set<String>> map1,
|
||||
Map<String, Set<String>> map2) {
|
||||
this.concealedPackagesToOpen = map1;
|
||||
this.exportedPackagesToOpen = map2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of concealed packages to open. The map key is the
|
||||
* module name, the value is the set of concealed packages to open.
|
||||
*/
|
||||
public Map<String, Set<String>> concealedPackagesToOpen() {
|
||||
return concealedPackagesToOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map of exported packages to open. The map key is the
|
||||
* module name, the value is the set of exported packages to open.
|
||||
*/
|
||||
public Map<String, Set<String>> exportedPackagesToOpen() {
|
||||
return exportedPackagesToOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the maps of module to concealed and exported packages for
|
||||
* the system modules that are observable with the given module finder.
|
||||
*/
|
||||
public static IllegalAccessMaps generate(ModuleFinder finder) {
|
||||
Map<String, ModuleDescriptor> map = new HashMap<>();
|
||||
finder.findAll().stream()
|
||||
.map(ModuleReference::descriptor)
|
||||
.forEach(md -> md.packages().forEach(pn -> map.putIfAbsent(pn, md)));
|
||||
|
||||
Map<String, Set<String>> concealedPackagesToOpen = new HashMap<>();
|
||||
Map<String, Set<String>> exportedPackagesToOpen = new HashMap<>();
|
||||
|
||||
String rn = "jdk8_packages.dat";
|
||||
InputStream in = IllegalAccessMaps.class.getResourceAsStream(rn);
|
||||
if (in == null) {
|
||||
throw new InternalError(rn + " not found");
|
||||
}
|
||||
try (BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(in, UTF_8.INSTANCE)))
|
||||
{
|
||||
br.lines()
|
||||
.filter(line -> !line.isEmpty() && !line.startsWith("#"))
|
||||
.forEach(pn -> {
|
||||
ModuleDescriptor descriptor = map.get(pn);
|
||||
if (descriptor != null && !isOpen(descriptor, pn)) {
|
||||
String name = descriptor.name();
|
||||
if (isExported(descriptor, pn)) {
|
||||
exportedPackagesToOpen.computeIfAbsent(name,
|
||||
k -> new HashSet<>()).add(pn);
|
||||
} else {
|
||||
concealedPackagesToOpen.computeIfAbsent(name,
|
||||
k -> new HashSet<>()).add(pn);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
|
||||
return new IllegalAccessMaps(concealedPackagesToOpen, exportedPackagesToOpen);
|
||||
}
|
||||
|
||||
private static boolean isExported(ModuleDescriptor descriptor, String pn) {
|
||||
return descriptor.exports()
|
||||
.stream()
|
||||
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
|
||||
}
|
||||
|
||||
private static boolean isOpen(ModuleDescriptor descriptor, String pn) {
|
||||
return descriptor.opens()
|
||||
.stream()
|
||||
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
|
||||
}
|
||||
}
|
||||
@@ -147,8 +147,7 @@ public final class ModuleBootstrap {
|
||||
getProperty("jdk.module.limitmods") == null && // --limit-modules
|
||||
getProperty("jdk.module.addreads.0") == null && // --add-reads
|
||||
getProperty("jdk.module.addexports.0") == null && // --add-exports
|
||||
getProperty("jdk.module.addopens.0") == null && // --add-opens
|
||||
getProperty("jdk.module.illegalAccess") == null; // --jbr-illegal-access
|
||||
getProperty("jdk.module.addopens.0") == null; // --add-opens
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +188,6 @@ public final class ModuleBootstrap {
|
||||
String mainModule = System.getProperty("jdk.module.main");
|
||||
Set<String> addModules = addModules();
|
||||
Set<String> limitModules = limitModules();
|
||||
String illegalAccess = getAndRemoveProperty("jdk.module.illegalAccess");
|
||||
|
||||
PrintStream traceOutput = null;
|
||||
String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
|
||||
@@ -221,8 +219,7 @@ public final class ModuleBootstrap {
|
||||
&& !haveModulePath
|
||||
&& addModules.isEmpty()
|
||||
&& limitModules.isEmpty()
|
||||
&& !isPatched
|
||||
&& illegalAccess == null) {
|
||||
&& !isPatched) {
|
||||
systemModuleFinder = archivedModuleGraph.finder();
|
||||
hasSplitPackages = archivedModuleGraph.hasSplitPackages();
|
||||
hasIncubatorModules = archivedModuleGraph.hasIncubatorModules();
|
||||
@@ -457,19 +454,10 @@ public final class ModuleBootstrap {
|
||||
checkIncubatingStatus(cf);
|
||||
}
|
||||
|
||||
// --add-reads, --add-exports/--add-opens, and --jbr-illegal-access
|
||||
// --add-reads, --add-exports/--add-opens
|
||||
addExtraReads(bootLayer);
|
||||
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
|
||||
|
||||
if (illegalAccess != null) {
|
||||
assert systemModules != null;
|
||||
addIllegalAccess(illegalAccess,
|
||||
systemModules,
|
||||
upgradeModulePath,
|
||||
bootLayer,
|
||||
extraExportsOrOpens);
|
||||
}
|
||||
|
||||
// add enable native access
|
||||
addEnableNativeAccess(bootLayer);
|
||||
|
||||
@@ -825,74 +813,6 @@ public final class ModuleBootstrap {
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the --jbr-illegal-access option to open packages of system modules
|
||||
* in the boot layer to code in unnamed modules.
|
||||
*/
|
||||
private static void addIllegalAccess(String illegalAccess,
|
||||
SystemModules systemModules,
|
||||
ModuleFinder upgradeModulePath,
|
||||
ModuleLayer bootLayer,
|
||||
boolean extraExportsOrOpens) {
|
||||
|
||||
Map<String, Set<String>> concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
|
||||
Map<String, Set<String>> exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
|
||||
if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
|
||||
// need to generate (exploded build)
|
||||
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
|
||||
concealedPackagesToOpen = maps.concealedPackagesToOpen();
|
||||
exportedPackagesToOpen = maps.exportedPackagesToOpen();
|
||||
}
|
||||
|
||||
// open specific packages in the system modules
|
||||
Set<String> emptySet = Set.of();
|
||||
for (Module m : bootLayer.modules()) {
|
||||
ModuleDescriptor descriptor = m.getDescriptor();
|
||||
String name = m.getName();
|
||||
|
||||
// skip open modules
|
||||
if (descriptor.isOpen()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip modules loaded from the upgrade module path
|
||||
if (upgradeModulePath != null
|
||||
&& upgradeModulePath.find(name).isPresent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<String> concealedPackages = concealedPackagesToOpen.getOrDefault(name, emptySet);
|
||||
Set<String> exportedPackages = exportedPackagesToOpen.getOrDefault(name, emptySet);
|
||||
|
||||
// refresh the set of concealed and exported packages if needed
|
||||
if (extraExportsOrOpens) {
|
||||
concealedPackages = new HashSet<>(concealedPackages);
|
||||
exportedPackages = new HashSet<>(exportedPackages);
|
||||
Iterator<String> iterator = concealedPackages.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String pn = iterator.next();
|
||||
if (m.isExported(pn, BootLoader.getUnnamedModule())) {
|
||||
// concealed package is exported to ALL-UNNAMED
|
||||
iterator.remove();
|
||||
exportedPackages.add(pn);
|
||||
}
|
||||
}
|
||||
iterator = exportedPackages.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String pn = iterator.next();
|
||||
if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
|
||||
// exported package is opened to ALL-UNNAMED
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// open the packages to unnamed modules
|
||||
JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the values of --add-reads, -add-exports, --add-opens or
|
||||
* --patch-modules options that are encoded in system properties.
|
||||
|
||||
@@ -83,16 +83,4 @@ interface SystemModules {
|
||||
* by this SystemModules object.
|
||||
*/
|
||||
Map<String, Set<String>> moduleReads();
|
||||
|
||||
/**
|
||||
* Returns the map of module concealed packages to open. The map key is the
|
||||
* module name, the value is the set of concealed packages to open.
|
||||
*/
|
||||
Map<String, Set<String>> concealedPackagesToOpen();
|
||||
|
||||
/**
|
||||
* Returns the map of module exported packages to open. The map key is the
|
||||
* module name, the value is the set of exported packages to open.
|
||||
*/
|
||||
Map<String, Set<String>> exportedPackagesToOpen();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -188,10 +188,6 @@ java.launcher.X.usage=\n\
|
||||
\ --add-opens <module>/<package>=<target-module>(,<target-module>)*\n\
|
||||
\ updates <module> to open <package> to\n\
|
||||
\ <target-module>, regardless of module declaration.\n\
|
||||
\ --jbr-illegal-access\n\
|
||||
\ permit access to members of types in named modules\n\
|
||||
\ by code in unnamed modules.\n\
|
||||
\ This option will be removed in a future release.\n\
|
||||
\ --limit-modules <module name>[,<module name>...]\n\
|
||||
\ limit the universe of observable modules\n\
|
||||
\ --patch-module <module>=<file>({0}<file>)*\n\
|
||||
|
||||
@@ -50,20 +50,28 @@ Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jclass clazz,
|
||||
jint fd = fdval(env, fdo);
|
||||
int rv;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// On macOS systems we use disconnectx
|
||||
rv = disconnectx(fd, SAE_ASSOCID_ANY, SAE_CONNID_ANY);
|
||||
#else
|
||||
SOCKETADDRESS sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
sa.sa.sa_family = isIPv6 ? AF_INET6 : AF_INET;
|
||||
#else
|
||||
sa.sa.sa_family = AF_UNSPEC;
|
||||
#endif
|
||||
socklen_t len = isIPv6 ? sizeof(struct sockaddr_in6) :
|
||||
sizeof(struct sockaddr_in);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
sa.sa.sa_family = isIPv6 ? AF_INET6 : AF_INET;
|
||||
#else
|
||||
sa.sa.sa_family = AF_UNSPEC;
|
||||
rv = connect(fd, &sa.sa, len);
|
||||
#endif
|
||||
|
||||
rv = connect(fd, &sa.sa, len);
|
||||
|
||||
#if defined(_ALLBSD_SOURCE)
|
||||
#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__)
|
||||
// On _ALLBSD_SOURCE except __APPLE__ we consider EADDRNOTAVAIL
|
||||
// error to be OK and ignore it. __APPLE__ systems are excluded
|
||||
// in this check since for __APPLE__ systems, unlike other BSD systems,
|
||||
// we issue a "disconnectx" call (a few lines above),
|
||||
// which isn't expected to return this error code.
|
||||
if (rv < 0 && errno == EADDRNOTAVAIL)
|
||||
rv = errno = 0;
|
||||
#elif defined(_AIX)
|
||||
|
||||
@@ -63,19 +63,19 @@ static boolean SetupI18nProps(LCID lcid, char** language, char** script, char**
|
||||
static char *
|
||||
getEncodingInternal(LCID lcid)
|
||||
{
|
||||
int codepage;
|
||||
int codepage = 0;
|
||||
char * ret = malloc(16);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GetLocaleInfo(lcid,
|
||||
if (lcid == 0) { // for sun.jnu.encoding
|
||||
codepage = GetACP();
|
||||
_itoa_s(codepage, ret + 2, 14, 10);
|
||||
} else if (GetLocaleInfo(lcid,
|
||||
LOCALE_IDEFAULTANSICODEPAGE,
|
||||
ret+2, 14) == 0) {
|
||||
codepage = 1252;
|
||||
strcpy(ret+2, "1252");
|
||||
} else {
|
||||
codepage = atoi(ret+2);
|
||||
ret + 2, 14) != 0) {
|
||||
codepage = atoi(ret + 2);
|
||||
}
|
||||
|
||||
switch (codepage) {
|
||||
@@ -660,7 +660,6 @@ GetJavaProperties(JNIEnv* env)
|
||||
* (which is a Windows LCID value),
|
||||
*/
|
||||
LCID userDefaultLCID = GetUserDefaultLCID();
|
||||
LCID systemDefaultLCID = GetSystemDefaultLCID();
|
||||
LANGID userDefaultUILang = GetUserDefaultUILanguage();
|
||||
LCID userDefaultUILCID = MAKELCID(userDefaultUILang, SORTIDFROMLCID(userDefaultLCID));
|
||||
|
||||
@@ -693,7 +692,10 @@ GetJavaProperties(JNIEnv* env)
|
||||
&sprops.display_variant,
|
||||
&display_encoding);
|
||||
|
||||
sprops.sun_jnu_encoding = getEncodingInternal(systemDefaultLCID);
|
||||
sprops.sun_jnu_encoding = getEncodingInternal(0);
|
||||
if (sprops.sun_jnu_encoding == NULL) {
|
||||
sprops.sun_jnu_encoding = "UTF-8";
|
||||
}
|
||||
if (LANGIDFROMLCID(userDefaultLCID) == 0x0c04 && majorVersion == 6) {
|
||||
// MS claims "Vista has built-in support for HKSCS-2004.
|
||||
// All of the HKSCS-2004 characters have Unicode 4.1.
|
||||
|
||||
@@ -3190,6 +3190,9 @@ JNI_COCOA_ENTER(env);
|
||||
CTFontRef ctfont = (CTFontRef)nsFont;
|
||||
CFArrayRef tagsArray =
|
||||
CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);
|
||||
if (tagsArray == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
CFIndex numTags = CFArrayGetCount(tagsArray);
|
||||
for (i=0; i<numTags; i++) {
|
||||
if (tag ==
|
||||
|
||||
@@ -183,8 +183,9 @@
|
||||
* or maybe a way for the app to continue running depending on the exact
|
||||
* nature of the problem that has been detected and how survivable it is.
|
||||
*/
|
||||
#define CHECK_EXCEPTION_IN_ENV(env) \
|
||||
if ((*(env))->ExceptionOccurred(env) != NULL) { \
|
||||
#define CHECK_EXCEPTION_IN_ENV(env) { \
|
||||
jthrowable exc = (*(env))->ExceptionOccurred(env); \
|
||||
if (exc != NULL) { \
|
||||
if ([NSThread isMainThread] == YES) { \
|
||||
if (getenv("JNU_APPKIT_TRACE")) { \
|
||||
(*(env))->ExceptionDescribe(env); \
|
||||
@@ -193,12 +194,14 @@
|
||||
(*(env))->ExceptionClear(env); \
|
||||
} \
|
||||
} \
|
||||
if (getenv("JNU_NO_COCOA_EXCEPTION") == NULL) { \
|
||||
[NSException raise:NSGenericException format:@"Java Exception"]; \
|
||||
if (getenv("JNU_NO_COCOA_EXCEPTION") == NULL) {\
|
||||
[NSException raise:NSGenericException \
|
||||
format:@"%@", ThrowableToNSString(env, exc)]; \
|
||||
} else { \
|
||||
(*(env))->ExceptionClear(env); \
|
||||
} \
|
||||
};
|
||||
} \
|
||||
};
|
||||
|
||||
#define CHECK_EXCEPTION() CHECK_EXCEPTION_IN_ENV(env)
|
||||
|
||||
@@ -249,4 +252,6 @@ JNIEXPORT NSString* NormalizedPathNSStringFromJavaString(JNIEnv *env, jstring pa
|
||||
|
||||
JNIEXPORT jstring NormalizedPathJavaStringFromNSString(JNIEnv* env, NSString *str);
|
||||
|
||||
JNIEXPORT NSString *ThrowableToNSString(JNIEnv *env, jthrowable exc);
|
||||
|
||||
#endif /* __JNIUTILITIES_H */
|
||||
|
||||
@@ -113,3 +113,41 @@ jstring NormalizedPathJavaStringFromNSString(JNIEnv* env, NSString *str) {
|
||||
NSString *normStr = [str precomposedStringWithCanonicalMapping];
|
||||
return NSStringToJavaString(env, normStr);
|
||||
}
|
||||
|
||||
NSString *ThrowableToNSString(JNIEnv *env, jthrowable exc) {
|
||||
(*env)->ExceptionClear(env);
|
||||
|
||||
if (JNU_IsInstanceOfByName(env, exc, "java/lang/OutOfMemoryError")) {
|
||||
static NSString* const OOMEDescr = @"OutOfMemoryError";
|
||||
return OOMEDescr;
|
||||
}
|
||||
|
||||
DECLARE_CLASS_RETURN(sjc_Object, "java/lang/Object", nil);
|
||||
DECLARE_METHOD_RETURN(jm_toString, sjc_Object, "toString", "()Ljava/lang/String;", nil);
|
||||
DECLARE_CLASS_RETURN(sjc_Throwable, "java/lang/Throwable", nil);
|
||||
DECLARE_METHOD_RETURN(jm_getStackTrace, sjc_Throwable, "getStackTrace",
|
||||
"()[Ljava/lang/StackTraceElement;", nil);
|
||||
jobject jstr = (*env)->CallObjectMethod(env, exc, jm_toString);
|
||||
|
||||
NSString* result = JavaStringToNSString(env, jstr);
|
||||
|
||||
jobjectArray frames =
|
||||
(jobjectArray) (*env)->CallObjectMethod(env, exc, jm_getStackTrace);
|
||||
if (frames != NULL) {
|
||||
jsize framesLen = (*env)->GetArrayLength(env, frames);
|
||||
|
||||
for (int i = 0; i < framesLen; i++) {
|
||||
jobject stackElem = (*env)->GetObjectArrayElement(env, frames, i);
|
||||
jobject stackElemStr = (*env)->CallObjectMethod(env, stackElem, jm_toString);
|
||||
NSString *frameStr = JavaStringToNSString(env, stackElemStr);
|
||||
result = [result stringByAppendingFormat:@"\n%@", frameStr];
|
||||
(*env)->DeleteLocalRef(env, stackElem);
|
||||
(*env)->DeleteLocalRef(env, stackElemStr);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, frames);
|
||||
}
|
||||
(*env)->DeleteLocalRef(env, jstr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2022, 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
|
||||
@@ -70,10 +70,12 @@ typedef struct tagBitmapheader {
|
||||
|
||||
jfieldID AwtTrayIcon::idID;
|
||||
jfieldID AwtTrayIcon::actionCommandID;
|
||||
jmethodID AwtTrayIcon::updateImageID;
|
||||
|
||||
HWND AwtTrayIcon::sm_msgWindow = NULL;
|
||||
AwtTrayIcon::TrayIconListItem* AwtTrayIcon::sm_trayIconList = NULL;
|
||||
int AwtTrayIcon::sm_instCount = 0;
|
||||
bool AwtTrayIcon::m_bDPIChanged = false;
|
||||
|
||||
/************************************************************************
|
||||
* AwtTrayIcon methods
|
||||
@@ -221,6 +223,18 @@ void AwtTrayIcon::InitNID(UINT uID)
|
||||
m_nid.uVersion = NOTIFYICON_VERSION;
|
||||
}
|
||||
|
||||
// Call updateImage() method on the peer when screen scale changes
|
||||
void AwtTrayIcon::UpdateImage()
|
||||
{
|
||||
JNIEnv *env =(JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
|
||||
jobject peer = GetPeer(env);
|
||||
if (peer != NULL) {
|
||||
env->CallVoidMethod(peer, updateImageID);
|
||||
env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL AwtTrayIcon::SendTrayMessage(DWORD dwMessage)
|
||||
{
|
||||
return Shell_NotifyIcon(dwMessage, (PNOTIFYICONDATA)&m_nid);
|
||||
@@ -248,6 +262,10 @@ LRESULT CALLBACK AwtTrayIcon::TrayWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_DPICHANGED:
|
||||
// Set the flag to update icon images, see WmTaskbarCreated
|
||||
m_bDPIChanged = true;
|
||||
break;
|
||||
default:
|
||||
if(uMsg == s_msgTaskbarCreated) {
|
||||
if (hwnd == AwtTrayIcon::sm_msgWindow) {
|
||||
@@ -474,12 +492,17 @@ MsgRouting AwtTrayIcon::WmContextMenu(UINT flags, int x, int y)
|
||||
MsgRouting AwtTrayIcon::WmTaskbarCreated() {
|
||||
TrayIconListItem* item;
|
||||
for (item = sm_trayIconList; item != NULL; item = item->m_next) {
|
||||
if (m_bDPIChanged) {
|
||||
// Update the icon image
|
||||
item->m_trayIcon->UpdateImage();
|
||||
}
|
||||
BOOL result = item->m_trayIcon->SendTrayMessage(NIM_ADD);
|
||||
// 6270114: Instructs the taskbar to behave according to the Shell version 5.0
|
||||
if (result) {
|
||||
item->m_trayIcon->SendTrayMessage(NIM_SETVERSION);
|
||||
}
|
||||
}
|
||||
m_bDPIChanged = false;
|
||||
return mrDoDefault;
|
||||
}
|
||||
|
||||
@@ -917,6 +940,14 @@ Java_java_awt_TrayIcon_initIDs(JNIEnv *env, jclass cls)
|
||||
DASSERT(AwtTrayIcon::actionCommandID != NULL);
|
||||
CHECK_NULL( AwtTrayIcon::actionCommandID);
|
||||
|
||||
jclass wPeerCls = env->FindClass("sun/awt/windows/WTrayIconPeer");
|
||||
DASSERT(wPeerCls != NULL);
|
||||
CHECK_NULL(wPeerCls);
|
||||
|
||||
AwtTrayIcon::updateImageID = env->GetMethodID(wPeerCls, "updateImage", "()V");
|
||||
DASSERT(AwtTrayIcon::updateImageID != NULL);
|
||||
CHECK_NULL(AwtTrayIcon::updateImageID);
|
||||
|
||||
CATCH_BAD_ALLOC;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2022, 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
|
||||
@@ -86,6 +86,8 @@ public:
|
||||
|
||||
void DisplayMessage(LPCTSTR caption, LPCTSTR text, LPCTSTR msgType);
|
||||
|
||||
void UpdateImage();
|
||||
|
||||
// Adds to the head of the list
|
||||
INLINE void AddTrayIconItem(UINT id) {
|
||||
TrayIconListItem* item = new TrayIconListItem(id, this);
|
||||
@@ -121,6 +123,7 @@ public:
|
||||
*/
|
||||
static jfieldID idID;
|
||||
static jfieldID actionCommandID;
|
||||
static jmethodID updateImageID;
|
||||
|
||||
// ************************
|
||||
|
||||
@@ -151,6 +154,8 @@ private:
|
||||
TrayIconListItem* m_next;
|
||||
};
|
||||
|
||||
static bool m_bDPIChanged;
|
||||
|
||||
public:
|
||||
static TrayIconListItem* sm_trayIconList;
|
||||
};
|
||||
|
||||
@@ -60,7 +60,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import jdk.internal.module.Checks;
|
||||
import jdk.internal.module.DefaultRoots;
|
||||
import jdk.internal.module.IllegalAccessMaps;
|
||||
import jdk.internal.module.Modules;
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleInfo.Attributes;
|
||||
@@ -622,9 +621,6 @@ public final class SystemModulesPlugin extends AbstractPlugin {
|
||||
// generate moduleReads
|
||||
genModuleReads(cw, cf);
|
||||
|
||||
// generate concealedPackagesToOpen and exportedPackagesToOpen
|
||||
genXXXPackagesToOpenMethods(cw);
|
||||
|
||||
return cw;
|
||||
}
|
||||
|
||||
@@ -855,16 +851,6 @@ public final class SystemModulesPlugin extends AbstractPlugin {
|
||||
generate(cw, "moduleReads", map, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate concealedPackagesToOpen and exportedPackagesToOpen methods.
|
||||
*/
|
||||
private void genXXXPackagesToOpenMethods(ClassWriter cw) {
|
||||
ModuleFinder finder = finderOf(moduleInfos);
|
||||
IllegalAccessMaps maps = IllegalAccessMaps.generate(finder);
|
||||
generate(cw, "concealedPackagesToOpen", maps.concealedPackagesToOpen(), false);
|
||||
generate(cw, "exportedPackagesToOpen", maps.exportedPackagesToOpen(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate method to return {@code Map<String, Set<String>>}.
|
||||
*
|
||||
|
||||
128
test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java
Normal file
128
test/jdk/java/awt/TrayIcon/TrayIconScalingTest.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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 8255439
|
||||
* @key headful
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @summary To test tray icon scaling with on-the-fly DPI/Scale changes on Windows
|
||||
* @run main/manual TrayIconScalingTest
|
||||
* @requires (os.family == "windows")
|
||||
*/
|
||||
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.SystemTray;
|
||||
import java.awt.TrayIcon;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.image.BaseMultiResolutionImage;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TrayIconScalingTest {
|
||||
|
||||
private static SystemTray tray;
|
||||
private static TrayIcon icon;
|
||||
|
||||
private static final String INSTRUCTIONS =
|
||||
"This test checks if the tray icon gets updated when DPI / Scale" +
|
||||
" is changed on the fly.\n\n" +
|
||||
"STEPS: \n\n" +
|
||||
"1. Check the system tray / notification area on Windows" +
|
||||
" taskbar, you should see a white icon which displays a" +
|
||||
" number.\n\n" +
|
||||
"2. Navigate to Settings > System > Display and change the" +
|
||||
" display scale by selecting any value from" +
|
||||
" Scale & Layout dropdown.\n\n"+
|
||||
"3. When the scale changes, check the white tray icon," +
|
||||
" there should be no distortion, it should be displayed sharp,\n" +
|
||||
" and the displayed number should correspond to the current"+
|
||||
" scale:\n" +
|
||||
" 100% - 16, 125% - 20, 150% - 24, 175% - 28, 200% - 32.\n\n"+
|
||||
" If the icon is displayed sharp and without any distortion," +
|
||||
" press PASS, otherwise press FAIL.\n";
|
||||
|
||||
private static final Font font = new Font("Dialog", Font.BOLD, 12);
|
||||
|
||||
public static void main(String[] args)
|
||||
throws InterruptedException, InvocationTargetException {
|
||||
// check if SystemTray supported on the machine
|
||||
if (!SystemTray.isSupported()) {
|
||||
System.out.println("SystemTray is not supported");
|
||||
return;
|
||||
}
|
||||
PassFailJFrame passFailJFrame = new PassFailJFrame("TrayIcon " +
|
||||
"Test Instructions", INSTRUCTIONS, 8, 18, 85);
|
||||
createAndShowGUI();
|
||||
try {
|
||||
passFailJFrame.awaitAndCheck();
|
||||
} finally {
|
||||
tray.remove(icon);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createAndShowGUI() {
|
||||
ArrayList<Image> imageList = new ArrayList<>();
|
||||
for (int size = 16; size <= 48; size += 4) {
|
||||
imageList.add(createIcon(size));
|
||||
}
|
||||
Image mRImage =
|
||||
new BaseMultiResolutionImage(imageList.toArray(new Image[0]));
|
||||
|
||||
tray = SystemTray.getSystemTray();
|
||||
icon = new TrayIcon(mRImage);
|
||||
|
||||
try {
|
||||
tray.add(icon);
|
||||
} catch (AWTException e) {
|
||||
throw new RuntimeException("Error while adding icon to system tray");
|
||||
}
|
||||
}
|
||||
|
||||
private static Image createIcon(int size) {
|
||||
BufferedImage image = new BufferedImage(size, size,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = image.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.setColor(Color.WHITE);
|
||||
g.fillRect(0, 0, size, size);
|
||||
g.setFont(font);
|
||||
g.setColor(Color.BLACK);
|
||||
|
||||
TextLayout layout = new TextLayout(String.valueOf(size),
|
||||
g.getFont(), g.getFontRenderContext());
|
||||
int height = (int) layout.getBounds().getHeight();
|
||||
int width = (int) layout.getBounds().getWidth();
|
||||
layout.draw(g, (size - width) / 2f - 1, (size + height) / 2f);
|
||||
g.dispose();
|
||||
return image;
|
||||
}
|
||||
}
|
||||
321
test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
Normal file
321
test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*/
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import static javax.swing.SwingUtilities.invokeAndWait;
|
||||
import static javax.swing.SwingUtilities.isEventDispatchThread;
|
||||
|
||||
public class PassFailJFrame {
|
||||
|
||||
private static final String TITLE = "Test Instruction Frame";
|
||||
private static final long TEST_TIMEOUT = 5;
|
||||
private static final int ROWS = 10;
|
||||
private static final int COLUMNS = 40;
|
||||
|
||||
private static final List<Frame> frameList = new ArrayList<>();
|
||||
private static final Timer timer = new Timer(0, null);
|
||||
private static final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
private static volatile boolean failed;
|
||||
private static volatile boolean timeout;
|
||||
private static volatile String testFailedReason;
|
||||
private static JFrame frame;
|
||||
|
||||
public enum Position {HORIZONTAL, VERTICAL}
|
||||
|
||||
public PassFailJFrame(String instructions) throws InterruptedException,
|
||||
InvocationTargetException {
|
||||
this(instructions, TEST_TIMEOUT);
|
||||
}
|
||||
|
||||
public PassFailJFrame(String instructions, long testTimeOut) throws
|
||||
InterruptedException, InvocationTargetException {
|
||||
this(TITLE, instructions, testTimeOut);
|
||||
}
|
||||
|
||||
public PassFailJFrame(String title, String instructions,
|
||||
long testTimeOut) throws InterruptedException,
|
||||
InvocationTargetException {
|
||||
this(title, instructions, testTimeOut, ROWS, COLUMNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JFrame with a given title & serves as test instructional
|
||||
* frame where the user follows the specified test instruction in order
|
||||
* to test the test case & mark the test pass or fail. If the expected
|
||||
* result is seen then the user click on the 'Pass' button else click
|
||||
* on the 'Fail' button and the reason for the failure should be
|
||||
* specified in the JDialog JTextArea.
|
||||
*
|
||||
* @param title title of the Frame.
|
||||
* @param instructions the instruction for the tester on how to test
|
||||
* and what is expected (pass) and what is not
|
||||
* expected (fail).
|
||||
* @param testTimeOut test timeout where time is specified in minutes.
|
||||
* @param rows number of visible rows of the JTextArea where the
|
||||
* instruction is show.
|
||||
* @param columns Number of columns of the instructional
|
||||
* JTextArea
|
||||
* @throws InterruptedException exception thrown when thread is
|
||||
* interrupted
|
||||
* @throws InvocationTargetException if an exception is thrown while
|
||||
* creating the test instruction frame on
|
||||
* EDT
|
||||
*/
|
||||
public PassFailJFrame(String title, String instructions, long testTimeOut,
|
||||
int rows, int columns) throws InterruptedException,
|
||||
InvocationTargetException {
|
||||
if (isEventDispatchThread()) {
|
||||
createUI(title, instructions, testTimeOut, rows, columns);
|
||||
} else {
|
||||
invokeAndWait(() -> createUI(title, instructions, testTimeOut,
|
||||
rows, columns));
|
||||
}
|
||||
}
|
||||
|
||||
private static void createUI(String title, String instructions,
|
||||
long testTimeOut, int rows, int columns) {
|
||||
frame = new JFrame(title);
|
||||
frame.setLayout(new BorderLayout());
|
||||
JTextArea instructionsText = new JTextArea(instructions, rows, columns);
|
||||
instructionsText.setEditable(false);
|
||||
instructionsText.setLineWrap(true);
|
||||
|
||||
long tTimeout = TimeUnit.MINUTES.toMillis(testTimeOut);
|
||||
|
||||
final JLabel testTimeoutLabel = new JLabel(String.format("Test " +
|
||||
"timeout: %s", convertMillisToTimeStr(tTimeout)), JLabel.CENTER);
|
||||
final long startTime = System.currentTimeMillis();
|
||||
timer.setDelay(1000);
|
||||
timer.addActionListener((e) -> {
|
||||
long leftTime = tTimeout - (System.currentTimeMillis() - startTime);
|
||||
if ((leftTime < 0) || failed) {
|
||||
timer.stop();
|
||||
testFailedReason = "Failure Reason:\n"
|
||||
+ "Timeout User did not perform testing.";
|
||||
timeout = true;
|
||||
latch.countDown();
|
||||
}
|
||||
testTimeoutLabel.setText(String.format("Test timeout: %s", convertMillisToTimeStr(leftTime)));
|
||||
});
|
||||
timer.start();
|
||||
frame.add(testTimeoutLabel, BorderLayout.NORTH);
|
||||
frame.add(new JScrollPane(instructionsText), BorderLayout.CENTER);
|
||||
|
||||
JButton btnPass = new JButton("Pass");
|
||||
btnPass.addActionListener((e) -> {
|
||||
latch.countDown();
|
||||
timer.stop();
|
||||
});
|
||||
|
||||
JButton btnFail = new JButton("Fail");
|
||||
btnFail.addActionListener((e) -> {
|
||||
getFailureReason();
|
||||
timer.stop();
|
||||
});
|
||||
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
buttonsPanel.add(btnPass);
|
||||
buttonsPanel.add(btnFail);
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
super.windowClosing(e);
|
||||
testFailedReason = "Failure Reason:\n"
|
||||
+ "User closed the instruction Frame";
|
||||
failed = true;
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
frame.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
frameList.add(frame);
|
||||
}
|
||||
|
||||
private static String convertMillisToTimeStr(long millis) {
|
||||
if (millis < 0) {
|
||||
return "00:00:00";
|
||||
}
|
||||
long hours = millis / 3_600_000;
|
||||
long minutes = (millis - hours * 3_600_000) / 60_000;
|
||||
long seconds = (millis - hours * 3_600_000 - minutes * 60_000) / 1_000;
|
||||
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the user decision i,e user selects pass or fail button.
|
||||
* If user does not select pass or fail button then the test waits for
|
||||
* the specified timeoutMinutes period and the test gets timeout.
|
||||
* Note: This method should be called from main() thread
|
||||
*
|
||||
* @throws InterruptedException exception thrown when thread is
|
||||
* interrupted
|
||||
* @throws InvocationTargetException if an exception is thrown while
|
||||
* disposing of frames on EDT
|
||||
*/
|
||||
public void awaitAndCheck() throws InterruptedException, InvocationTargetException {
|
||||
if (isEventDispatchThread()) {
|
||||
throw new IllegalStateException("awaitAndCheck() should not be called on EDT");
|
||||
}
|
||||
latch.await();
|
||||
invokeAndWait(PassFailJFrame::disposeFrames);
|
||||
|
||||
if (timeout) {
|
||||
throw new RuntimeException(testFailedReason);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
throw new RuntimeException("Test failed! : " + testFailedReason);
|
||||
}
|
||||
|
||||
System.out.println("Test passed!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose all the frame(s) i,e both the test instruction frame as
|
||||
* well as the frame that is added via addTestFrame(Frame frame)
|
||||
*/
|
||||
private static synchronized void disposeFrames() {
|
||||
for (Frame f : frameList) {
|
||||
f.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the test failure reason and add the reason to the test result
|
||||
* example in the jtreg .jtr file.
|
||||
*/
|
||||
private static void getFailureReason() {
|
||||
final JDialog dialog = new JDialog(frame, "Test Failure ", true);
|
||||
dialog.setTitle("Failure reason");
|
||||
JPanel jPanel = new JPanel(new BorderLayout());
|
||||
JTextArea jTextArea = new JTextArea(5, 20);
|
||||
|
||||
JButton okButton = new JButton("OK");
|
||||
okButton.addActionListener((ae) -> {
|
||||
testFailedReason = "Failure Reason:\n" + jTextArea.getText();
|
||||
dialog.setVisible(false);
|
||||
});
|
||||
|
||||
jPanel.add(new JScrollPane(jTextArea), BorderLayout.CENTER);
|
||||
|
||||
JPanel okayBtnPanel = new JPanel();
|
||||
okayBtnPanel.add(okButton);
|
||||
|
||||
jPanel.add(okayBtnPanel, BorderLayout.SOUTH);
|
||||
dialog.add(jPanel);
|
||||
dialog.setLocationRelativeTo(frame);
|
||||
dialog.pack();
|
||||
dialog.setVisible(true);
|
||||
|
||||
failed = true;
|
||||
dialog.dispose();
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Position the instruction frame with testFrame ( testcase created
|
||||
* frame) by the specified position
|
||||
* Note: This method should be invoked from the method that creates
|
||||
* testFrame
|
||||
*
|
||||
* @param testFrame test frame that the test is created
|
||||
* @param position position can be either HORIZONTAL (both test
|
||||
* instruction frame and test frame as arranged side by
|
||||
* side or VERTICAL ( both test instruction frame and
|
||||
* test frame as arranged up and down)
|
||||
*/
|
||||
public static void positionTestFrame(Frame testFrame, Position position) {
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
if (position.equals(Position.HORIZONTAL)) {
|
||||
int newX = ((screenSize.width / 2) - frame.getWidth());
|
||||
frame.setLocation(newX, frame.getY());
|
||||
|
||||
testFrame.setLocation((frame.getLocation().x + frame.getWidth() + 5), frame.getY());
|
||||
} else if (position.equals(Position.VERTICAL)) {
|
||||
int newY = ((screenSize.height / 2) - frame.getHeight());
|
||||
frame.setLocation(frame.getX(), newY);
|
||||
|
||||
testFrame.setLocation(frame.getX(),
|
||||
(frame.getLocation().y + frame.getHeight() + 5));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the testFrame to the frameList so that test instruction frame
|
||||
* and testFrame and any other frame used in this test is disposed
|
||||
* via disposeFrames()
|
||||
*
|
||||
* @param testFrame testFrame that needs to be disposed
|
||||
*/
|
||||
public static synchronized void addTestFrame(Frame testFrame) {
|
||||
frameList.add(testFrame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcibly pass the test.
|
||||
* <p>The sample usage:
|
||||
* <pre><code>
|
||||
* PrinterJob pj = PrinterJob.getPrinterJob();
|
||||
* if (pj == null || pj.getPrintService() == null) {
|
||||
* System.out.println(""Printer not configured or available.");
|
||||
* PassFailJFrame.forcePass();
|
||||
* }
|
||||
* </code></pre>
|
||||
*/
|
||||
public static void forcePass() {
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcibly fail the test.
|
||||
*/
|
||||
public static void forceFail() {
|
||||
failed = true;
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2022, 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
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 7132924
|
||||
* @bug 7132924 8285515
|
||||
* @library /test/lib
|
||||
* @key intermittent
|
||||
* @summary Test DatagramChannel.disconnect when DatagramChannel is connected to an IPv4 socket
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 8266851
|
||||
* @library /test/lib
|
||||
* @build JbrIllegalAccessTest
|
||||
* @run testng JbrIllegalAccessTest
|
||||
* @summary Make sure that --jbr-illegal-access is working.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.*;
|
||||
import org.testng.annotations.*;
|
||||
|
||||
/**
|
||||
* Make sure that --jbr-illegal-access is working as expected.
|
||||
*/
|
||||
|
||||
@Test
|
||||
public class JbrIllegalAccessTest {
|
||||
|
||||
void run(String text, String... vmopts)
|
||||
throws Exception
|
||||
{
|
||||
var outputAnalyzer = ProcessTools
|
||||
.executeTestJava(vmopts)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out);
|
||||
outputAnalyzer.shouldNotContain(text);
|
||||
}
|
||||
|
||||
public void testObsolete() throws Exception {
|
||||
run("Unrecognized option: --jbr-illegal-access",
|
||||
"-XX:-IgnoreUnrecognizedVMOptions",
|
||||
"--jbr-illegal-access", "--version");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,20 +54,21 @@ import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
public class RenderPerfTest {
|
||||
private static HashSet<String> ignoredTests = new HashSet<>();
|
||||
|
||||
static {
|
||||
ignoredTests.add("testWiredBoxAA");
|
||||
// add ignored tests here
|
||||
// ignoredTests.add("testMyIgnoredTest");
|
||||
}
|
||||
|
||||
private final static int N = 1000;
|
||||
@@ -76,12 +77,14 @@ public class RenderPerfTest {
|
||||
private final static float R = 25;
|
||||
private final static int BW = 50;
|
||||
private final static int BH = 50;
|
||||
private final static int COUNT = 300;
|
||||
private final static int DELAY = 10;
|
||||
private final static int RESOLUTION = 5;
|
||||
private final static int COLOR_TOLERANCE = 10;
|
||||
private final static int MAX_MEASURE_TIME = 5000;
|
||||
private final static int COUNT = 600;
|
||||
private final static int CYCLE_DELAY = 3;
|
||||
private final static int MAX_FRAME_CYCLES = 3000/CYCLE_DELAY;
|
||||
|
||||
private final static int COLOR_TOLERANCE = 10;
|
||||
private final static int MAX_MEASURE_CYCLES = 6000/CYCLE_DELAY;
|
||||
|
||||
private final static Color[] marker = {Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW, Color.ORANGE, Color.MAGENTA};
|
||||
|
||||
interface Configurable {
|
||||
void configure(Graphics2D g2d);
|
||||
@@ -276,6 +279,7 @@ public class RenderPerfTest {
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
setPaint(g2d, id);
|
||||
if (id % 100 != 0) return;
|
||||
Font font = new Font("LucidaGrande", Font.PLAIN, 32);
|
||||
g2d.setFont(font);
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
@@ -599,24 +603,24 @@ public class RenderPerfTest {
|
||||
|
||||
static class PerfMeter {
|
||||
private String name;
|
||||
private int frame = 0;
|
||||
|
||||
|
||||
private JPanel panel;
|
||||
|
||||
private long time;
|
||||
private double execTime = 0;
|
||||
private Color expColor = Color.RED;
|
||||
AtomicBoolean waiting = new AtomicBoolean(false);
|
||||
private AtomicInteger markerIdx = new AtomicInteger(0);
|
||||
private int renderedMarkerIdx = -1;
|
||||
private AtomicLong markerPaintTime = new AtomicLong(0);
|
||||
|
||||
private double fps;
|
||||
private int skippedFrame = 0;
|
||||
|
||||
PerfMeter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
PerfMeter exec(final Renderable renderable) throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(COUNT);
|
||||
final CountDownLatch latchFrame = new CountDownLatch(1);
|
||||
final long endTime = System.currentTimeMillis() + MAX_MEASURE_TIME;
|
||||
|
||||
final JFrame f = new JFrame();
|
||||
f.addWindowListener(new WindowAdapter() {
|
||||
@@ -630,22 +634,27 @@ public class RenderPerfTest {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
panel = new JPanel()
|
||||
{
|
||||
panel = new JPanel() {
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
|
||||
super.paintComponent(g);
|
||||
time = System.nanoTime();
|
||||
int idx = markerIdx.get();
|
||||
if (idx != renderedMarkerIdx) {
|
||||
markerPaintTime.set(System.nanoTime());
|
||||
}
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
renderable.setup(g2d);
|
||||
renderable.render(g2d);
|
||||
g2d.setColor(expColor);
|
||||
g.fillRect(0, 0, BW, BH);
|
||||
g2d.setClip(null);
|
||||
g2d.setPaintMode();
|
||||
g2d.setColor(marker[idx]);
|
||||
g2d.fillRect(0, 0, BW, BH);
|
||||
renderedMarkerIdx = idx;
|
||||
}
|
||||
};
|
||||
|
||||
panel.setPreferredSize(new Dimension((int)(WIDTH + BW), (int)(HEIGHT + BH)));
|
||||
panel.setPreferredSize(new Dimension((int) (WIDTH + BW), (int) (HEIGHT + BH)));
|
||||
panel.setBackground(Color.BLACK);
|
||||
f.add(panel);
|
||||
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
@@ -653,51 +662,51 @@ public class RenderPerfTest {
|
||||
f.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
Robot robot = new Robot();
|
||||
int cycle = 0;
|
||||
int frame = 0;
|
||||
long paintTime = 0;
|
||||
int maxFrameCycle = -1;
|
||||
while (frame < COUNT) {
|
||||
long t;
|
||||
if ((t = markerPaintTime.getAndSet(0)) > 0) {
|
||||
paintTime = t;
|
||||
maxFrameCycle = cycle + MAX_FRAME_CYCLES;
|
||||
}
|
||||
|
||||
Timer timer = new Timer(DELAY, e -> {
|
||||
|
||||
if (waiting.compareAndSet(false, true)) {
|
||||
if (paintTime > 0) {
|
||||
Color c = robot.getPixelColor(
|
||||
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
|
||||
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BW / 2);
|
||||
if (isAlmostEqual(c, Color.BLUE)) {
|
||||
expColor = Color.RED;
|
||||
} else {
|
||||
expColor = Color.BLUE;
|
||||
}
|
||||
renderable.update();
|
||||
panel.getParent().repaint();
|
||||
|
||||
} else {
|
||||
while (!isAlmostEqual(
|
||||
robot.getPixelColor(
|
||||
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
|
||||
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
|
||||
expColor))
|
||||
{
|
||||
try {
|
||||
Thread.sleep(RESOLUTION);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (isAlmostEqual(c, marker[markerIdx.get()])) {
|
||||
execTime += System.nanoTime() - paintTime;
|
||||
frame++;
|
||||
paintTime = 0;
|
||||
maxFrameCycle = -1;
|
||||
markerIdx.accumulateAndGet(marker.length, (x, y) -> (x + 1) % y);
|
||||
renderable.update();
|
||||
panel.getParent().repaint();
|
||||
} else if (cycle >= maxFrameCycle) {
|
||||
skippedFrame++;
|
||||
paintTime = 0;
|
||||
maxFrameCycle = -1;
|
||||
markerIdx.accumulateAndGet(marker.length, (x, y) -> (x + 1) % y);
|
||||
panel.getParent().repaint();
|
||||
}
|
||||
time = System.nanoTime() - time;
|
||||
execTime += time;
|
||||
frame++;
|
||||
waiting.set(false);
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() < endTime) {
|
||||
latch.countDown();
|
||||
} else {
|
||||
while(latch.getCount() > 0) latch.countDown();
|
||||
try {
|
||||
Thread.sleep(CYCLE_DELAY);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
latch.await();
|
||||
if (cycle >= MAX_MEASURE_CYCLES) {
|
||||
break;
|
||||
}
|
||||
cycle++;
|
||||
}
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
timer.stop();
|
||||
f.setVisible(false);
|
||||
f.dispose();
|
||||
});
|
||||
@@ -713,12 +722,15 @@ public class RenderPerfTest {
|
||||
}
|
||||
|
||||
private void report() {
|
||||
if (skippedFrame > 0) {
|
||||
System.err.println(skippedFrame + " frame(s) skipped");
|
||||
}
|
||||
System.err.println(name + " : " + String.format("%.2f FPS", fps));
|
||||
}
|
||||
|
||||
private boolean isAlmostEqual(Color c1, Color c2) {
|
||||
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
|
||||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
|
||||
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE &&
|
||||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE &&
|
||||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user