OpenJDK / jdk / hs
changeset 27449:7ed11cfd9be8
Merge
author | iveresov |
---|---|
date | Fri, 31 Oct 2014 12:01:27 -1000 |
parents | a98064f3bf24 c461dfe64745 |
children | 603dbcf4f547 |
files | jdk/src/java.base/share/conf/calendars.properties jdk/src/java.base/share/conf/hijrah-config-umalqura.properties jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.StreamPrintServiceFactory jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.PrintServiceLookup jdk/src/java.desktop/windows/classes/META-INF/services/javax.print.StreamPrintServiceFactory jdk/src/java.desktop/windows/classes/sun/print/Win32PrintServiceLookup.java jdk/test/java/sql/TEST.properties jdk/test/java/sql/test/sql/BatchUpdateExceptionTests.java jdk/test/java/sql/test/sql/DataTruncationTests.java jdk/test/java/sql/test/sql/DateTests.java jdk/test/java/sql/test/sql/DriverManagerPermissionsTests.java jdk/test/java/sql/test/sql/DriverManagerTests.java jdk/test/java/sql/test/sql/SQLClientInfoExceptionTests.java jdk/test/java/sql/test/sql/SQLDataExceptionTests.java jdk/test/java/sql/test/sql/SQLExceptionTests.java jdk/test/java/sql/test/sql/SQLFeatureNotSupportedExceptionTests.java jdk/test/java/sql/test/sql/SQLIntegrityConstraintViolationExceptionTests.java jdk/test/java/sql/test/sql/SQLInvalidAuthorizationSpecExceptionTests.java jdk/test/java/sql/test/sql/SQLNonTransientConnectionExceptionTests.java jdk/test/java/sql/test/sql/SQLNonTransientExceptionTests.java jdk/test/java/sql/test/sql/SQLRecoverableExceptionTests.java jdk/test/java/sql/test/sql/SQLSyntaxErrorExceptionTests.java jdk/test/java/sql/test/sql/SQLTimeoutExceptionTests.java jdk/test/java/sql/test/sql/SQLTransactionRollbackExceptionTests.java jdk/test/java/sql/test/sql/SQLTransientConnectionExceptionTests.java jdk/test/java/sql/test/sql/SQLTransientExceptionTests.java jdk/test/java/sql/test/sql/SQLWarningTests.java jdk/test/java/sql/test/sql/TimeTests.java jdk/test/java/sql/test/sql/TimestampTests.java jdk/test/java/sql/util/BaseTest.java jdk/test/java/sql/util/DriverActionImpl.java jdk/test/java/sql/util/SerializedBatchUpdateException.java jdk/test/java/sql/util/StubBlob.java jdk/test/java/sql/util/StubConnection.java jdk/test/java/sql/util/StubDriver.java jdk/test/java/sql/util/StubDriverDA.java jdk/test/java/sql/util/TestPolicy.java jdk/test/javax/sql/testng/util/BaseTest.java jdk/test/javax/sql/testng/util/TestPolicy.java |
diffstat | 453 files changed, 16677 insertions(+), 12904 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -279,3 +279,4 @@ 9618201c5df28a460631577fad1f61e96f775c34 jdk9-b34 a137992d750c72f6f944f341aa19b0d0d96afe0c jdk9-b35 41df50e7303daf73c0d661ef601c4fe250915de5 jdk9-b36 +b409bc51bc23cfd51f2bd04ea919ec83535af9d0 jdk9-b37
--- a/.hgtags-top-repo Fri Oct 31 11:31:30 2014 +0000 +++ b/.hgtags-top-repo Fri Oct 31 12:01:27 2014 -1000 @@ -279,3 +279,4 @@ 087b23f35631e68e950496a36fce8ccca612966a jdk9-b34 c173ba994245380fb11ef077d1e59823386840eb jdk9-b35 201d4e235d597a25a2d3ee1404394789ba386119 jdk9-b36 +723a67b0c442391447b1d8aad8b249d06d1032e8 jdk9-b37
--- a/common/autoconf/flags.m4 Fri Oct 31 11:31:30 2014 +0000 +++ b/common/autoconf/flags.m4 Fri Oct 31 12:01:27 2014 -1000 @@ -136,8 +136,8 @@ SYSROOT_CFLAGS="-isysroot \"$SYSROOT\" -iframework\"$SYSROOT/System/Library/Frameworks\"" SYSROOT_LDFLAGS=$SYSROOT_CFLAGS elif test "x$TOOLCHAIN_TYPE" = xgcc; then - SYSROOT_CFLAGS="--sysroot=\"$SYSROOT\"" - SYSROOT_LDFLAGS="--sysroot=\"$SYSROOT\"" + SYSROOT_CFLAGS="--sysroot=$SYSROOT" + SYSROOT_LDFLAGS="--sysroot=$SYSROOT" elif test "x$TOOLCHAIN_TYPE" = xclang; then SYSROOT_CFLAGS="-isysroot \"$SYSROOT\"" SYSROOT_LDFLAGS="-isysroot \"$SYSROOT\""
--- a/common/autoconf/generated-configure.sh Fri Oct 31 11:31:30 2014 +0000 +++ b/common/autoconf/generated-configure.sh Fri Oct 31 12:01:27 2014 -1000 @@ -4328,7 +4328,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1413533532 +DATE_WHEN_GENERATED=1414663067 ############################################################################### # @@ -41681,8 +41681,8 @@ SYSROOT_CFLAGS="-isysroot \"$SYSROOT\" -iframework\"$SYSROOT/System/Library/Frameworks\"" SYSROOT_LDFLAGS=$SYSROOT_CFLAGS elif test "x$TOOLCHAIN_TYPE" = xgcc; then - SYSROOT_CFLAGS="--sysroot=\"$SYSROOT\"" - SYSROOT_LDFLAGS="--sysroot=\"$SYSROOT\"" + SYSROOT_CFLAGS="--sysroot=$SYSROOT" + SYSROOT_LDFLAGS="--sysroot=$SYSROOT" elif test "x$TOOLCHAIN_TYPE" = xclang; then SYSROOT_CFLAGS="-isysroot \"$SYSROOT\"" SYSROOT_LDFLAGS="-isysroot \"$SYSROOT\"" @@ -44037,17 +44037,6 @@ -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi - # - # Weird Sol10 something check...TODO change to try compile - # - if test "x${OPENJDK_TARGET_OS}" = xsolaris; then - if test "`uname -r`" = "5.10"; then - if test "`${EGREP} -c XLinearGradient ${OPENWIN_HOME}/share/include/X11/extensions/Xrender.h`" = "0"; then - X_CFLAGS="${X_CFLAGS} -DSOLARIS10_NO_XRENDER_STRUCTS" - fi - fi - fi - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -44055,7 +44044,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 for ac_header in X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h @@ -44079,6 +44068,31 @@ done + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XlinearGradient is defined in Xrender.h" >&5 +$as_echo_n "checking if XlinearGradient is defined in Xrender.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <X11/extensions/Xrender.h> +int +main () +{ +XLinearGradient x; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$OLD_CFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS'
--- a/common/autoconf/libraries.m4 Fri Oct 31 11:31:30 2014 +0000 +++ b/common/autoconf/libraries.m4 Fri Oct 31 12:01:27 2014 -1000 @@ -139,20 +139,9 @@ -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi - # - # Weird Sol10 something check...TODO change to try compile - # - if test "x${OPENJDK_TARGET_OS}" = xsolaris; then - if test "`uname -r`" = "5.10"; then - if test "`${EGREP} -c XLinearGradient ${OPENWIN_HOME}/share/include/X11/extensions/Xrender.h`" = "0"; then - X_CFLAGS="${X_CFLAGS} -DSOLARIS10_NO_XRENDER_STRUCTS" - fi - fi - fi - AC_LANG_PUSH(C) OLD_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $X_CFLAGS" + CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS" # Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10 AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h], @@ -164,6 +153,16 @@ ] ) + # If XLinearGradient isn't available in Xrender.h, signal that it needs to be + # defined in libawt_xawt. + AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include <X11/extensions/Xrender.h>]], + [[XLinearGradient x;]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"]) + CFLAGS="$OLD_CFLAGS" AC_LANG_POP(C)
--- a/corba/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/corba/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -279,3 +279,4 @@ 24a0bad5910f775bb4002d1dacf8b3af87c63cd8 jdk9-b34 9bc2dbd3dfb8c9fa88e00056b8b93a81ee6d306e jdk9-b35 ffd90c81d4ef9d94d880fc852e2fc482ecd9b374 jdk9-b36 +7e9add74ad50841fb39dae75db56374aefa1de4c jdk9-b37
--- a/hotspot/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -439,3 +439,4 @@ 821164b0131a47ca065697c7d27d8f215e608c8d jdk9-b34 438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35 464ab653fbb17eb518d8ef60f8df301de7ef00d0 jdk9-b36 +b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37
--- a/hotspot/src/os/aix/vm/os_aix.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -4137,15 +4137,6 @@ return 1; } -int os::socket_available(int fd, jint *pbytes) { - // Linux doc says EINTR not returned, unlike Solaris - int ret = ::ioctl(fd, FIONREAD, pbytes); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret < 0) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only,
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -178,92 +178,14 @@ return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Linux any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // Linux doc says this can't return EINTR, unlike accept() on Solaris. - // But see attachListener_linux.cpp, LinuxAttachListener::dequeue(). - return (int)::accept(fd, him, len); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { // mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments) return true;
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -3958,21 +3958,6 @@ return 1; } -int os::socket_available(int fd, jint *pbytes) { - if (fd < 0) { - return OS_OK; - } - - int ret; - - RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - - return (ret == OS_ERR) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only,
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -181,91 +181,14 @@ return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Bsd any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // At least OpenBSD and FreeBSD can return EINTR from accept. - RESTARTABLE_RETURN_INT(::accept(fd, him, len)); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr *to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char *optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { #ifdef __APPLE__ return true;
--- a/hotspot/src/os/linux/vm/os_linux.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -5211,15 +5211,6 @@ return 1; } -int os::socket_available(int fd, jint *pbytes) { - // Linux doc says EINTR not returned, unlike Solaris - int ret = ::ioctl(fd, FIONREAD, pbytes); - - //%% note ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret < 0) ? 0 : 1; -} - // Map a block of memory. char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only,
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -173,92 +173,14 @@ return os::send(fd, buf, nBytes, flags); } -inline int os::timeout(int fd, long timeout) { - julong prevtime,newtime; - struct timeval t; - - gettimeofday(&t, NULL); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for(;;) { - struct pollfd pfd; - - pfd.fd = fd; - pfd.events = POLLIN | POLLERR; - - int res = ::poll(&pfd, 1, timeout); - - if (res == OS_ERR && errno == EINTR) { - - // On Linux any value < 0 means "forever" - - if(timeout >= 0) { - gettimeofday(&t, NULL); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - timeout -= newtime - prevtime; - if(timeout <= 0) - return OS_OK; - prevtime = newtime; - } - } else - return res; - } -} - -inline int os::listen(int fd, int count) { - return ::listen(fd, count); -} - inline int os::connect(int fd, struct sockaddr* him, socklen_t len) { RESTARTABLE_RETURN_INT(::connect(fd, him, len)); } -inline int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - // Linux doc says this can't return EINTR, unlike accept() on Solaris. - // But see attachListener_linux.cpp, LinuxAttachListener::dequeue(). - return (int)::accept(fd, him, len); -} - -inline int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -inline int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -inline int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -inline int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { return Linux::_clock_gettime != NULL; }
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -5912,37 +5912,6 @@ // a poll() is done with timeout == -1, in which case we repeat with this // "wait forever" value. -int os::timeout(int fd, long timeout) { - int res; - struct timeval t; - julong prevtime, newtime; - static const char* aNull = 0; - struct pollfd pfd; - pfd.fd = fd; - pfd.events = POLLIN; - - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - - gettimeofday(&t, &aNull); - prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; - - for (;;) { - res = ::poll(&pfd, 1, timeout); - if (res == OS_ERR && errno == EINTR) { - if (timeout != -1) { - gettimeofday(&t, &aNull); - newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; - timeout -= newtime - prevtime; - if (timeout <= 0) { - return OS_OK; - } - prevtime = newtime; - } - } else return res; - } -} - int os::connect(int fd, struct sockaddr *him, socklen_t len) { int _result; _result = ::connect(fd, him, len); @@ -5982,46 +5951,6 @@ return _result; } -int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - if (fd < 0) { - return OS_ERR; - } - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::accept(fd, him, len)); -} - -int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); -} - -int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); -} - -int os::socket_available(int fd, jint *pbytes) { - if (fd < 0) { - return OS_OK; - } - int ret; - RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); - // note: ioctl can return 0 when successful, JVM_SocketAvailable - // is expected to return 0 on failure and 1 on success to the jdk. - return (ret == OS_ERR) ? 0 : 1; -} - -int os::bind(int fd, struct sockaddr* him, socklen_t len) { - assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, - "Assumed _thread_in_native"); - return ::bind(fd, him, len); -} - // Get the default path to the core file // Returns the length of the string int os::get_core_path(char* buffer, size_t bufferSize) {
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -120,38 +120,10 @@ return ::socket(domain, type, protocol); } -inline int os::listen(int fd, int count) { - if (fd < 0) return OS_ERR; - - return ::listen(fd, count); -} - -inline int os::socket_shutdown(int fd, int howto){ - return ::shutdown(fd, howto); -} - -inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){ - return ::getsockname(fd, him, len); -} - -inline int os::get_host_name(char* name, int namelen){ - return ::gethostname(name, namelen); -} - inline struct hostent* os::get_host_by_name(char* name) { return ::gethostbyname(name); } -inline int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -inline int os::set_sock_opt(int fd, int level, int optname, - const char *optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - inline bool os::supports_monotonic_clock() { // javaTimeNanos() is monotonic on Solaris, see getTimeNanos() comments return true;
--- a/hotspot/src/os/windows/vm/os_windows.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -5091,39 +5091,14 @@ return ::closesocket(fd); } -int os::socket_available(int fd, jint *pbytes) { - int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes); - return (ret < 0) ? 0 : 1; -} - int os::socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); } -int os::listen(int fd, int count) { - return ::listen(fd, count); -} - int os::connect(int fd, struct sockaddr* him, socklen_t len) { return ::connect(fd, him, len); } -int os::accept(int fd, struct sockaddr* him, socklen_t* len) { - return ::accept(fd, him, len); -} - -int os::sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen) { - - return ::sendto(fd, buf, (int)len, flags, to, tolen); -} - -int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags, - sockaddr* from, socklen_t* fromlen) { - - return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen); -} - int os::recv(int fd, char* buf, size_t nBytes, uint flags) { return ::recv(fd, buf, (int)nBytes, flags); } @@ -5136,45 +5111,6 @@ return ::send(fd, buf, (int)nBytes, flags); } -int os::timeout(int fd, long timeout) { - fd_set tbl; - struct timeval t; - - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - - tbl.fd_count = 1; - tbl.fd_array[0] = fd; - - return ::select(1, &tbl, 0, 0, &t); -} - -int os::get_host_name(char* name, int namelen) { - return ::gethostname(name, namelen); -} - -int os::socket_shutdown(int fd, int howto) { - return ::shutdown(fd, howto); -} - -int os::bind(int fd, struct sockaddr* him, socklen_t len) { - return ::bind(fd, him, len); -} - -int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) { - return ::getsockname(fd, him, len); -} - -int os::get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen) { - return ::getsockopt(fd, level, optname, optval, optlen); -} - -int os::set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen) { - return ::setsockopt(fd, level, optname, optval, optlen); -} - // WINDOWS CONTEXT Flags for THREAD_SAMPLING #if defined(IA32) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -2557,7 +2557,7 @@ Array<Method*>* ClassFileParser::parse_methods(bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, - bool* has_default_methods, + bool* declares_default_methods, TRAPS) { ClassFileStream* cfs = stream(); cfs->guarantee_more(2, CHECK_NULL); // length @@ -2576,11 +2576,11 @@ if (method->is_final()) { *has_final_method = true; } - if (is_interface && !(*has_default_methods) - && !method->is_abstract() && !method->is_static() - && !method->is_private()) { - // default method - *has_default_methods = true; + // declares_default_methods: declares concrete instance methods, any access flags + // used for interface initialization, and default method inheritance analysis + if (is_interface && !(*declares_default_methods) + && !method->is_abstract() && !method->is_static()) { + *declares_default_methods = true; } _methods->at_put(index, method()); } @@ -3739,6 +3739,7 @@ JvmtiCachedClassFileData *cached_class_file = NULL; Handle class_loader(THREAD, loader_data->class_loader()); bool has_default_methods = false; + bool declares_default_methods = false; ResourceMark rm(THREAD); ClassFileStream* cfs = stream(); @@ -3976,9 +3977,13 @@ Array<Method*>* methods = parse_methods(access_flags.is_interface(), &promoted_flags, &has_final_method, - &has_default_methods, + &declares_default_methods, CHECK_(nullHandle)); + if (declares_default_methods) { + has_default_methods = true; + } + // Additional attributes ClassAnnotationCollector parsed_annotations; parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle)); @@ -4120,6 +4125,7 @@ this_klass->set_minor_version(minor_version); this_klass->set_major_version(major_version); this_klass->set_has_default_methods(has_default_methods); + this_klass->set_declares_default_methods(declares_default_methods); if (!host_klass.is_null()) { assert (this_klass->is_anonymous(), "should be the same");
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -247,7 +247,7 @@ Array<Method*>* parse_methods(bool is_interface, AccessFlags* promoted_flags, bool* has_final_method, - bool* has_default_method, + bool* declares_default_methods, TRAPS); intArray* sort_methods(Array<Method*>* methods);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -127,41 +127,6 @@ }; -class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { - size_t _num_processed; - CardTableModRefBS* _ctbs; - int _histo[256]; - - public: - ClearLoggedCardTableEntryClosure() : - _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set()) - { - for (int i = 0; i < 256; i++) _histo[i] = 0; - } - - bool do_card_ptr(jbyte* card_ptr, uint worker_i) { - unsigned char* ujb = (unsigned char*)card_ptr; - int ind = (int)(*ujb); - _histo[ind]++; - - *card_ptr = (jbyte)CardTableModRefBS::clean_card_val(); - _num_processed++; - - return true; - } - - size_t num_processed() { return _num_processed; } - - void print_histo() { - gclog_or_tty->print_cr("Card table value histogram:"); - for (int i = 0; i < 256; i++) { - if (_histo[i] != 0) { - gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); - } - } - } -}; - class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { private: size_t _num_processed; @@ -475,48 +440,6 @@ return !hr->is_humongous(); } -void G1CollectedHeap::check_ct_logs_at_safepoint() { - DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); - CardTableModRefBS* ct_bs = g1_barrier_set(); - - // Count the dirty cards at the start. - CountNonCleanMemRegionClosure count1(this); - ct_bs->mod_card_iterate(&count1); - int orig_count = count1.n(); - - // First clear the logged cards. - ClearLoggedCardTableEntryClosure clear; - dcqs.apply_closure_to_all_completed_buffers(&clear); - dcqs.iterate_closure_all_threads(&clear, false); - clear.print_histo(); - - // Now ensure that there's no dirty cards. - CountNonCleanMemRegionClosure count2(this); - ct_bs->mod_card_iterate(&count2); - if (count2.n() != 0) { - gclog_or_tty->print_cr("Card table has %d entries; %d originally", - count2.n(), orig_count); - } - guarantee(count2.n() == 0, "Card table should be clean."); - - RedirtyLoggedCardTableEntryClosure redirty; - dcqs.apply_closure_to_all_completed_buffers(&redirty); - dcqs.iterate_closure_all_threads(&redirty, false); - gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", - clear.num_processed(), orig_count); - guarantee(redirty.num_processed() == clear.num_processed(), - err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT, - redirty.num_processed(), clear.num_processed())); - - CountNonCleanMemRegionClosure count3(this); - ct_bs->mod_card_iterate(&count3); - if (count3.n() != orig_count) { - gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", - orig_count, count3.n()); - guarantee(count3.n() >= orig_count, "Should have restored them all."); - } -} - // Private class members. G1CollectedHeap* G1CollectedHeap::_g1h; @@ -5760,14 +5683,10 @@ // not copied during the pause. process_discovered_references(n_workers); - // Weak root processing. - { + if (G1StringDedup::is_enabled()) { G1STWIsAliveClosure is_alive(this); G1KeepAliveClosure keep_alive(this); - JNIHandles::weak_oops_do(&is_alive, &keep_alive); - if (G1StringDedup::is_enabled()) { - G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); - } + G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); } _allocator->release_gc_alloc_regions(n_workers, evacuation_info);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -797,9 +797,6 @@ // The closure used to refine a single card. RefineCardTableEntryClosure* _refine_cte_cl; - // A function to check the consistency of dirty card logs. - void check_ct_logs_at_safepoint(); - // A DirtyCardQueueSet that is used to hold cards that contain // references into the current collection set. This is used to // update the remembered sets of the regions in the collection
--- a/hotspot/src/share/vm/memory/metaspace.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -3157,6 +3157,16 @@ SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment); SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment); + // the min_misc_code_size estimate is based on MetaspaceShared::generate_vtable_methods() + uintx min_misc_code_size = align_size_up( + (MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) * + (sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size, + max_alignment); + + if (SharedMiscCodeSize < min_misc_code_size) { + report_out_of_shared_space(SharedMiscCode); + } + // Initialize with the sum of the shared space sizes. The read-only // and read write metaspace chunks will be allocated out of this and the // remainder is the misc code and data chunks.
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -57,11 +57,16 @@ static bool _archive_loading_failed; public: enum { - vtbl_list_size = 17, // number of entries in the shared space vtable list. - num_virtuals = 200 // maximum number of virtual functions - // If virtual functions are added to Metadata, - // this number needs to be increased. Also, - // SharedMiscCodeSize will need to be increased. + vtbl_list_size = 17, // number of entries in the shared space vtable list. + num_virtuals = 200, // maximum number of virtual functions + // If virtual functions are added to Metadata, + // this number needs to be increased. Also, + // SharedMiscCodeSize will need to be increased. + // The following 2 sizes were based on + // MetaspaceShared::generate_vtable_methods() + vtbl_method_size = 16, // conservative size of the mov1 and jmp instructions + // for the x64 platform + vtbl_common_code_size = (1*K) // conservative size of the "common_code" for the x64 platform }; enum {
--- a/hotspot/src/share/vm/oops/constantPool.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/oops/constantPool.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -206,7 +206,8 @@ } } -Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) { +Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, + bool save_resolution_error, TRAPS) { assert(THREAD->is_Java_thread(), "must be a Java thread"); // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*. @@ -249,7 +250,18 @@ // Failed to resolve class. We must record the errors so that subsequent attempts // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). if (HAS_PENDING_EXCEPTION) { - save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); + if (save_resolution_error) { + save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL); + // If CHECK_NULL above doesn't return the exception, that means that + // some other thread has beaten us and has resolved the class. + // To preserve old behavior, we return the resolved class. + entry = this_cp->resolved_klass_at(which); + assert(entry.is_resolved(), "must be resolved if exception was cleared"); + assert(entry.get_klass()->is_klass(), "must be resolved to a klass"); + return entry.get_klass(); + } else { + return NULL; // return the pending exception + } } // Make this class loader depend upon the class loader owning the class reference @@ -260,10 +272,10 @@ // skip resolving the constant pool so that this code gets // called the next time some bytecodes refer to this class. trace_class_resolution(this_cp, k); - return k(); - } else { - this_cp->klass_at_put(which, k()); - } + return k(); + } else { + this_cp->klass_at_put(which, k()); + } entry = this_cp->resolved_klass_at(which); assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point"); @@ -573,24 +585,25 @@ Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION); SystemDictionary::add_resolution_error(this_cp, which, error, message); // CAS in the tag. If a thread beat us to registering this error that's fine. - // If another thread resolved the reference, this is an error. The resolution - // must deterministically get an error. So why do we save this? - // We save this because jvmti can add classes to the bootclass path after this - // error, so it needs to get the same error if the error is first. + // If another thread resolved the reference, this is a race condition. This + // thread may have had a security manager or something temporary. + // This doesn't deterministically get an error. So why do we save this? + // We save this because jvmti can add classes to the bootclass path after + // this error, so it needs to get the same error if the error is first. jbyte old_tag = Atomic::cmpxchg((jbyte)error_tag, (jbyte*)this_cp->tag_addr_at(which), (jbyte)tag.value()); - assert(old_tag == error_tag || old_tag == tag.value(), "should not be resolved otherwise"); + if (old_tag != error_tag && old_tag != tag.value()) { + // MethodHandles and MethodType doesn't change to resolved version. + assert(this_cp->tag_at(which).is_klass(), "Wrong tag value"); + // Forget the exception and use the resolved class. + CLEAR_PENDING_EXCEPTION; + } } else { // some other thread put this in error state throw_resolution_error(this_cp, which, CHECK); } - - // This exits with some pending exception - assert(HAS_PENDING_EXCEPTION, "should not be cleared"); } - - // Called to resolve constants in the constant pool and return an oop. // Some constant pool entries cache their resolved oop. This is also // called to create oops from constants to use in arguments for invokedynamic @@ -627,7 +640,7 @@ case JVM_CONSTANT_Class: { assert(cache_index == _no_index_sentinel, "should not have been set"); - Klass* resolved = klass_at_impl(this_cp, index, CHECK_NULL); + Klass* resolved = klass_at_impl(this_cp, index, true, CHECK_NULL); // ldc wants the java mirror. result_oop = resolved->java_mirror(); break; @@ -660,7 +673,7 @@ ref_kind, index, this_cp->method_handle_index_at(index), callee_index, name->as_C_string(), signature->as_C_string()); KlassHandle callee; - { Klass* k = klass_at_impl(this_cp, callee_index, CHECK_NULL); + { Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL); callee = KlassHandle(THREAD, k); } KlassHandle klass(THREAD, this_cp->pool_holder());
--- a/hotspot/src/share/vm/oops/constantPool.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/oops/constantPool.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -336,7 +336,13 @@ Klass* klass_at(int which, TRAPS) { constantPoolHandle h_this(THREAD, this); - return klass_at_impl(h_this, which, CHECK_NULL); + return klass_at_impl(h_this, which, true, CHECK_NULL); + } + + // Version of klass_at that doesn't save the resolution error, called during deopt + Klass* klass_at_ignore_error(int which, TRAPS) { + constantPoolHandle h_this(THREAD, this); + return klass_at_impl(h_this, which, false, CHECK_NULL); } Symbol* klass_name_at(int which); // Returns the name, w/o resolving. @@ -793,7 +799,8 @@ // Implementation of methods that needs an exposed 'this' pointer, in order to // handle GC while executing the method - static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS); + static Klass* klass_at_impl(constantPoolHandle this_cp, int which, + bool save_resolution_error, TRAPS); static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS); static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -736,6 +736,41 @@ } } +// Eagerly initialize superinterfaces that declare default methods (concrete instance: any access) +void InstanceKlass::initialize_super_interfaces(instanceKlassHandle this_k, TRAPS) { + if (this_k->has_default_methods()) { + for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { + Klass* iface = this_k->local_interfaces()->at(i); + InstanceKlass* ik = InstanceKlass::cast(iface); + if (ik->should_be_initialized()) { + if (ik->has_default_methods()) { + ik->initialize_super_interfaces(ik, THREAD); + } + // Only initialize() interfaces that "declare" concrete methods. + // has_default_methods drives searching superinterfaces since it + // means has_default_methods in its superinterface hierarchy + if (!HAS_PENDING_EXCEPTION && ik->declares_default_methods()) { + ik->initialize(THREAD); + } + if (HAS_PENDING_EXCEPTION) { + Handle e(THREAD, PENDING_EXCEPTION); + CLEAR_PENDING_EXCEPTION; + { + EXCEPTION_MARK; + // Locks object, set state, and notify all waiting threads + this_k->set_initialization_state_and_notify( + initialization_error, THREAD); + + // ignore any exception thrown, superclass initialization error is + // thrown below + CLEAR_PENDING_EXCEPTION; + } + THROW_OOP(e()); + } + } + } + } +} void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) { // Make sure klass is linked (verified) before initialization @@ -815,33 +850,11 @@ } } + // Recursively initialize any superinterfaces that declare default methods + // Only need to recurse if has_default_methods which includes declaring and + // inheriting default methods if (this_k->has_default_methods()) { - // Step 7.5: initialize any interfaces which have default methods - for (int i = 0; i < this_k->local_interfaces()->length(); ++i) { - Klass* iface = this_k->local_interfaces()->at(i); - InstanceKlass* ik = InstanceKlass::cast(iface); - if (ik->has_default_methods() && ik->should_be_initialized()) { - ik->initialize(THREAD); - - if (HAS_PENDING_EXCEPTION) { - Handle e(THREAD, PENDING_EXCEPTION); - CLEAR_PENDING_EXCEPTION; - { - EXCEPTION_MARK; - // Locks object, set state, and notify all waiting threads - this_k->set_initialization_state_and_notify( - initialization_error, THREAD); - - // ignore any exception thrown, superclass initialization error is - // thrown below - CLEAR_PENDING_EXCEPTION; - } - DTRACE_CLASSINIT_PROBE_WAIT( - super__failed, InstanceKlass::cast(this_k()), -1, wait); - THROW_OOP(e()); - } - } - } + this_k->initialize_super_interfaces(this_k, CHECK); } // Step 8
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -199,13 +199,14 @@ bool _has_unloaded_dependent; enum { - _misc_rewritten = 1 << 0, // methods rewritten. - _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops - _misc_should_verify_class = 1 << 2, // allow caching of preverification - _misc_is_anonymous = 1 << 3, // has embedded _host_klass field - _misc_is_contended = 1 << 4, // marked with contended annotation - _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods - _misc_has_been_redefined = 1 << 6 // class has been redefined + _misc_rewritten = 1 << 0, // methods rewritten. + _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops + _misc_should_verify_class = 1 << 2, // allow caching of preverification + _misc_is_anonymous = 1 << 3, // has embedded _host_klass field + _misc_is_contended = 1 << 4, // marked with contended annotation + _misc_has_default_methods = 1 << 5, // class/superclass/implemented interfaces has default methods + _misc_declares_default_methods = 1 << 6, // directly declares default methods (any access) + _misc_has_been_redefined = 1 << 7 // class has been redefined }; u2 _misc_flags; u2 _minor_version; // minor version number of class file @@ -651,6 +652,17 @@ } } + bool declares_default_methods() const { + return (_misc_flags & _misc_declares_default_methods) != 0; + } + void set_declares_default_methods(bool b) { + if (b) { + _misc_flags |= _misc_declares_default_methods; + } else { + _misc_flags &= ~_misc_declares_default_methods; + } + } + // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available inline u2 next_method_idnum(); void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } @@ -1023,6 +1035,7 @@ static bool link_class_impl (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS); static bool verify_code (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS); static void initialize_impl (instanceKlassHandle this_k, TRAPS); + static void initialize_super_interfaces (instanceKlassHandle this_k, TRAPS); static void eager_initialize_impl (instanceKlassHandle this_k); static void set_initialization_state_and_notify_impl (instanceKlassHandle this_k, ClassState state, TRAPS); static void call_class_initializer_impl (instanceKlassHandle this_k, TRAPS);
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -3271,8 +3271,10 @@ THROW_0(vmSymbols::java_lang_NullPointerException()); } oop a = JNIHandles::resolve_non_null(arr); - if (!a->is_array() || (type_array_only && !a->is_typeArray())) { + if (!a->is_array()) { THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array"); + } else if (type_array_only && !a->is_typeArray()) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Argument is not an array of primitive type"); } return arrayOop(a); }
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -41,6 +41,7 @@ void JvmtiClassFileReconstituter::write_field_infos() { HandleMark hm(thread()); Array<AnnotationArray*>* fields_anno = ikh()->fields_annotations(); + Array<AnnotationArray*>* fields_type_anno = ikh()->fields_type_annotations(); // Compute the real number of Java fields int java_fields = ikh()->java_fields_count(); @@ -55,6 +56,7 @@ // int offset = ikh()->field_offset( index ); int generic_signature_index = fs.generic_signature_index(); AnnotationArray* anno = fields_anno == NULL ? NULL : fields_anno->at(fs.index()); + AnnotationArray* type_anno = fields_type_anno == NULL ? NULL : fields_type_anno->at(fs.index()); // JVMSpec| field_info { // JVMSpec| u2 access_flags; @@ -80,6 +82,9 @@ if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } write_u2(attr_count); @@ -97,6 +102,9 @@ if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } } } @@ -537,6 +545,7 @@ AnnotationArray* anno = method->annotations(); AnnotationArray* param_anno = method->parameter_annotations(); AnnotationArray* default_anno = method->annotation_default(); + AnnotationArray* type_anno = method->type_annotations(); // skip generated default interface methods if (method->is_overpass()) { @@ -572,6 +581,9 @@ if (param_anno != NULL) { ++attr_count; // has RuntimeVisibleParameterAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } write_u2(attr_count); if (const_method->code_size() > 0) { @@ -596,6 +608,9 @@ if (param_anno != NULL) { write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } } // Write the class attributes portion of ClassFile structure @@ -605,6 +620,7 @@ u2 inner_classes_length = inner_classes_attribute_length(); Symbol* generic_signature = ikh()->generic_signature(); AnnotationArray* anno = ikh()->class_annotations(); + AnnotationArray* type_anno = ikh()->class_type_annotations(); int attr_count = 0; if (generic_signature != NULL) { @@ -622,6 +638,9 @@ if (anno != NULL) { ++attr_count; // has RuntimeVisibleAnnotations attribute } + if (type_anno != NULL) { + ++attr_count; // has RuntimeVisibleTypeAnnotations attribute + } if (cpool()->operands() != NULL) { ++attr_count; } @@ -643,6 +662,9 @@ if (anno != NULL) { write_annotations_attribute("RuntimeVisibleAnnotations", anno); } + if (type_anno != NULL) { + write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno); + } if (cpool()->operands() != NULL) { write_bootstrapmethod_attribute(); }
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -1569,6 +1569,29 @@ return false; } + // rewrite constant pool references in the class_type_annotations: + if (!rewrite_cp_refs_in_class_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // rewrite constant pool references in the fields_type_annotations: + if (!rewrite_cp_refs_in_fields_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // rewrite constant pool references in the methods_type_annotations: + if (!rewrite_cp_refs_in_methods_type_annotations(scratch_class, THREAD)) { + // propagate failure back to caller + return false; + } + + // There can be type annotations in the Code part of a method_info attribute. + // These annotations are not accessible, even by reflection. + // Currently they are not even parsed by the ClassFileParser. + // If runtime access is added they will also need to be rewritten. + // rewrite source file name index: u2 source_file_name_idx = scratch_class->source_file_name_index(); if (source_file_name_idx != 0) { @@ -2239,6 +2262,588 @@ } // end rewrite_cp_refs_in_methods_default_annotations() +// Rewrite constant pool references in a class_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_class_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + AnnotationArray* class_type_annotations = scratch_class->class_type_annotations(); + if (class_type_annotations == NULL || class_type_annotations->length() == 0) { + // no class_type_annotations so nothing to do + return true; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("class_type_annotations length=%d", class_type_annotations->length())); + + int byte_i = 0; // byte index into class_type_annotations + return rewrite_cp_refs_in_type_annotations_typeArray(class_type_annotations, + byte_i, "ClassFile", THREAD); +} // end rewrite_cp_refs_in_class_type_annotations() + + +// Rewrite constant pool references in a fields_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_fields_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + Array<AnnotationArray*>* fields_type_annotations = scratch_class->fields_type_annotations(); + if (fields_type_annotations == NULL || fields_type_annotations->length() == 0) { + // no fields_type_annotations so nothing to do + return true; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("fields_type_annotations length=%d", fields_type_annotations->length())); + + for (int i = 0; i < fields_type_annotations->length(); i++) { + AnnotationArray* field_type_annotations = fields_type_annotations->at(i); + if (field_type_annotations == NULL || field_type_annotations->length() == 0) { + // this field does not have any annotations so skip it + continue; + } + + int byte_i = 0; // byte index into field_type_annotations + if (!rewrite_cp_refs_in_type_annotations_typeArray(field_type_annotations, + byte_i, "field_info", THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad field_type_annotations at %d", i)); + // propagate failure back to caller + return false; + } + } + + return true; +} // end rewrite_cp_refs_in_fields_type_annotations() + + +// Rewrite constant pool references in a methods_type_annotations field. +bool VM_RedefineClasses::rewrite_cp_refs_in_methods_type_annotations( + instanceKlassHandle scratch_class, TRAPS) { + + for (int i = 0; i < scratch_class->methods()->length(); i++) { + Method* m = scratch_class->methods()->at(i); + AnnotationArray* method_type_annotations = m->constMethod()->type_annotations(); + + if (method_type_annotations == NULL || method_type_annotations->length() == 0) { + // this method does not have any annotations so skip it + continue; + } + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("methods type_annotations length=%d", method_type_annotations->length())); + + int byte_i = 0; // byte index into method_type_annotations + if (!rewrite_cp_refs_in_type_annotations_typeArray(method_type_annotations, + byte_i, "method_info", THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad method_type_annotations at %d", i)); + // propagate failure back to caller + return false; + } + } + + return true; +} // end rewrite_cp_refs_in_methods_type_annotations() + + +// Rewrite constant pool references in a type_annotations +// field. This "structure" is adapted from the +// RuntimeVisibleTypeAnnotations_attribute described in +// section 4.7.20 of the Java SE 8 Edition of the VM spec: +// +// type_annotations_typeArray { +// u2 num_annotations; +// type_annotation annotations[num_annotations]; +// } +// +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotations_typeArray( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + // not enough room for num_annotations field + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for num_annotations field")); + return false; + } + + u2 num_annotations = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("num_type_annotations=%d", num_annotations)); + + int calc_num_annotations = 0; + for (; calc_num_annotations < num_annotations; calc_num_annotations++) { + if (!rewrite_cp_refs_in_type_annotation_struct(type_annotations_typeArray, + byte_i_ref, location_mesg, THREAD)) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("bad type_annotation_struct at %d", calc_num_annotations)); + // propagate failure back to caller + return false; + } + } + assert(num_annotations == calc_num_annotations, "sanity check"); + + if (byte_i_ref != type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("read wrong amount of bytes at end of processing " + "type_annotations_typeArray (%d of %d bytes were read)", + byte_i_ref, type_annotations_typeArray->length())); + return false; + } + + return true; +} // end rewrite_cp_refs_in_type_annotations_typeArray() + + +// Rewrite constant pool references in a type_annotation +// field. This "structure" is adapted from the +// RuntimeVisibleTypeAnnotations_attribute described in +// section 4.7.20 of the Java SE 8 Edition of the VM spec: +// +// type_annotation { +// u1 target_type; +// union { +// type_parameter_target; +// supertype_target; +// type_parameter_bound_target; +// empty_target; +// method_formal_parameter_target; +// throws_target; +// localvar_target; +// catch_target; +// offset_target; +// type_argument_target; +// } target_info; +// type_path target_path; +// annotation anno; +// } +// +bool VM_RedefineClasses::rewrite_cp_refs_in_type_annotation_struct( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if (!skip_type_annotation_target(type_annotations_typeArray, + byte_i_ref, location_mesg, THREAD)) { + return false; + } + + if (!skip_type_annotation_type_path(type_annotations_typeArray, + byte_i_ref, THREAD)) { + return false; + } + + if (!rewrite_cp_refs_in_annotation_struct(type_annotations_typeArray, + byte_i_ref, THREAD)) { + return false; + } + + return true; +} // end rewrite_cp_refs_in_type_annotation_struct() + + +// Read, verify and skip over the target_type and target_info part +// so that rewriting can continue in the later parts of the struct. +// +// u1 target_type; +// union { +// type_parameter_target; +// supertype_target; +// type_parameter_bound_target; +// empty_target; +// method_formal_parameter_target; +// throws_target; +// localvar_target; +// catch_target; +// offset_target; +// type_argument_target; +// } target_info; +// +bool VM_RedefineClasses::skip_type_annotation_target( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS) { + + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + // not enough room for a target_type let alone the rest of a type_annotation + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a target_type")); + return false; + } + + u1 target_type = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("target_type=0x%.2x", target_type)); + RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("location=%s", location_mesg)); + + // Skip over target_info + switch (target_type) { + case 0x00: + // kind: type parameter declaration of generic class or interface + // location: ClassFile + case 0x01: + // kind: type parameter declaration of generic method or constructor + // location: method_info + + { + // struct: + // type_parameter_target { + // u1 type_parameter_index; + // } + // + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_parameter_target")); + return false; + } + + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_parameter_target: type_parameter_index=%d", + type_parameter_index)); + } break; + + case 0x10: + // kind: type in extends clause of class or interface declaration + // (including the direct superclass of an anonymous class declaration), + // or in implements clause of interface declaration + // location: ClassFile + + { + // struct: + // supertype_target { + // u2 supertype_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a supertype_target")); + return false; + } + + u2 supertype_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("supertype_target: supertype_index=%d", supertype_index)); + } break; + + case 0x11: + // kind: type in bound of type parameter declaration of generic class or interface + // location: ClassFile + case 0x12: + // kind: type in bound of type parameter declaration of generic method or constructor + // location: method_info + + { + // struct: + // type_parameter_bound_target { + // u1 type_parameter_index; + // u1 bound_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_parameter_bound_target")); + return false; + } + + u1 type_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + u1 bound_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_parameter_bound_target: type_parameter_index=%d, bound_index=%d", + type_parameter_index, bound_index)); + } break; + + case 0x13: + // kind: type in field declaration + // location: field_info + case 0x14: + // kind: return type of method, or type of newly constructed object + // location: method_info + case 0x15: + // kind: receiver type of method or constructor + // location: method_info + + { + // struct: + // empty_target { + // } + // + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("empty_target")); + } break; + + case 0x16: + // kind: type in formal parameter declaration of method, constructor, or lambda expression + // location: method_info + + { + // struct: + // formal_parameter_target { + // u1 formal_parameter_index; + // } + // + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a formal_parameter_target")); + return false; + } + + u1 formal_parameter_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("formal_parameter_target: formal_parameter_index=%d", + formal_parameter_index)); + } break; + + case 0x17: + // kind: type in throws clause of method or constructor + // location: method_info + + { + // struct: + // throws_target { + // u2 throws_type_index + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a throws_target")); + return false; + } + + u2 throws_type_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("throws_target: throws_type_index=%d", throws_type_index)); + } break; + + case 0x40: + // kind: type in local variable declaration + // location: Code + case 0x41: + // kind: type in resource variable declaration + // location: Code + + { + // struct: + // localvar_target { + // u2 table_length; + // struct { + // u2 start_pc; + // u2 length; + // u2 index; + // } table[table_length]; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + // not enough room for a table_length let alone the rest of a localvar_target + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a localvar_target table_length")); + return false; + } + + u2 table_length = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("localvar_target: table_length=%d", table_length)); + + int table_struct_size = 2 + 2 + 2; // 3 u2 variables per table entry + int table_size = table_length * table_struct_size; + + if ((byte_i_ref + table_size) > type_annotations_typeArray->length()) { + // not enough room for a table + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a table array of length %d", table_length)); + return false; + } + + // Skip over table + byte_i_ref += table_size; + } break; + + case 0x42: + // kind: type in exception parameter declaration + // location: Code + + { + // struct: + // catch_target { + // u2 exception_table_index; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a catch_target")); + return false; + } + + u2 exception_table_index = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("catch_target: exception_table_index=%d", exception_table_index)); + } break; + + case 0x43: + // kind: type in instanceof expression + // location: Code + case 0x44: + // kind: type in new expression + // location: Code + case 0x45: + // kind: type in method reference expression using ::new + // location: Code + case 0x46: + // kind: type in method reference expression using ::Identifier + // location: Code + + { + // struct: + // offset_target { + // u2 offset; + // } + // + if ((byte_i_ref + 2) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a offset_target")); + return false; + } + + u2 offset = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("offset_target: offset=%d", offset)); + } break; + + case 0x47: + // kind: type in cast expression + // location: Code + case 0x48: + // kind: type argument for generic constructor in new expression or + // explicit constructor invocation statement + // location: Code + case 0x49: + // kind: type argument for generic method in method invocation expression + // location: Code + case 0x4A: + // kind: type argument for generic constructor in method reference expression using ::new + // location: Code + case 0x4B: + // kind: type argument for generic method in method reference expression using ::Identifier + // location: Code + + { + // struct: + // type_argument_target { + // u2 offset; + // u1 type_argument_index; + // } + // + if ((byte_i_ref + 3) > type_annotations_typeArray->length()) { + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_argument_target")); + return false; + } + + u2 offset = Bytes::get_Java_u2((address) + type_annotations_typeArray->adr_at(byte_i_ref)); + byte_i_ref += 2; + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_argument_target: offset=%d, type_argument_index=%d", + offset, type_argument_index)); + } break; + + default: + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("unknown target_type")); +#ifdef ASSERT + ShouldNotReachHere(); +#endif + return false; + } + + return true; +} // end skip_type_annotation_target() + + +// Read, verify and skip over the type_path part so that rewriting +// can continue in the later parts of the struct. +// +// type_path { +// u1 path_length; +// { +// u1 type_path_kind; +// u1 type_argument_index; +// } path[path_length]; +// } +// +bool VM_RedefineClasses::skip_type_annotation_type_path( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS) { + + if ((byte_i_ref + 1) > type_annotations_typeArray->length()) { + // not enough room for a path_length let alone the rest of the type_path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for a type_path")); + return false; + } + + u1 path_length = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_path: path_length=%d", path_length)); + + int calc_path_length = 0; + for (; calc_path_length < path_length; calc_path_length++) { + if ((byte_i_ref + 1 + 1) > type_annotations_typeArray->length()) { + // not enough room for a path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("length() is too small for path entry %d of %d", + calc_path_length, path_length)); + return false; + } + + u1 type_path_kind = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + u1 type_argument_index = type_annotations_typeArray->at(byte_i_ref); + byte_i_ref += 1; + + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("type_path: path[%d]: type_path_kind=%d, type_argument_index=%d", + calc_path_length, type_path_kind, type_argument_index)); + + if (type_path_kind > 3 || (type_path_kind != 3 && type_argument_index != 0)) { + // not enough room for a path + RC_TRACE_WITH_THREAD(0x02000000, THREAD, + ("inconsistent type_path values")); + return false; + } + } + assert(path_length == calc_path_length, "sanity check"); + + return true; +} // end skip_type_annotation_type_path() + + // Rewrite constant pool references in the method's stackmap table. // These "structures" are adapted from the StackMapTable_attribute that // is described in section 4.8.4 of the 6.0 version of the VM spec @@ -3223,23 +3828,6 @@ void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class, instanceKlassHandle scratch_class) { - // Since there is currently no rewriting of type annotations indexes - // into the CP, we null out type annotations on scratch_class before - // we swap annotations with the_class rather than facing the - // possibility of shipping annotations with broken indexes to - // Java-land. - ClassLoaderData* loader_data = scratch_class->class_loader_data(); - AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations(); - if (new_class_type_annotations != NULL) { - MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations); - scratch_class->annotations()->set_class_type_annotations(NULL); - } - Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations(); - if (new_field_type_annotations != NULL) { - Annotations::free_contents(loader_data, new_field_type_annotations); - scratch_class->annotations()->set_fields_type_annotations(NULL); - } - // Swap annotation fields values Annotations* old_annotations = the_class->annotations(); the_class->set_annotations(scratch_class->annotations());
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -452,6 +452,17 @@ instanceKlassHandle scratch_class, TRAPS); bool rewrite_cp_refs_in_element_value( AnnotationArray* class_annotations, int &byte_i_ref, TRAPS); + bool rewrite_cp_refs_in_type_annotations_typeArray( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool rewrite_cp_refs_in_type_annotation_struct( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool skip_type_annotation_target( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, + const char * location_mesg, TRAPS); + bool skip_type_annotation_type_path( + AnnotationArray* type_annotations_typeArray, int &byte_i_ref, TRAPS); bool rewrite_cp_refs_in_fields_annotations( instanceKlassHandle scratch_class, TRAPS); void rewrite_cp_refs_in_method(methodHandle method, @@ -463,6 +474,12 @@ instanceKlassHandle scratch_class, TRAPS); bool rewrite_cp_refs_in_methods_parameter_annotations( instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_class_type_annotations( + instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_fields_type_annotations( + instanceKlassHandle scratch_class, TRAPS); + bool rewrite_cp_refs_in_methods_type_annotations( + instanceKlassHandle scratch_class, TRAPS); void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS); void rewrite_cp_refs_in_verification_type_info( address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -1173,7 +1173,7 @@ void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { // in case of an unresolved klass entry, load the class. if (constant_pool->tag_at(index).is_unresolved_klass()) { - Klass* tk = constant_pool->klass_at(index, CHECK); + Klass* tk = constant_pool->klass_at_ignore_error(index, CHECK); return; }
--- a/hotspot/src/share/vm/runtime/os.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/runtime/os.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -680,28 +680,10 @@ // SocketInterface (ex HPI SocketInterface ) static int socket(int domain, int type, int protocol); static int socket_close(int fd); - static int socket_shutdown(int fd, int howto); static int recv(int fd, char* buf, size_t nBytes, uint flags); static int send(int fd, char* buf, size_t nBytes, uint flags); static int raw_send(int fd, char* buf, size_t nBytes, uint flags); - static int timeout(int fd, long timeout); - static int listen(int fd, int count); static int connect(int fd, struct sockaddr* him, socklen_t len); - static int bind(int fd, struct sockaddr* him, socklen_t len); - static int accept(int fd, struct sockaddr* him, socklen_t* len); - static int recvfrom(int fd, char* buf, size_t nbytes, uint flags, - struct sockaddr* from, socklen_t* fromlen); - static int get_sock_name(int fd, struct sockaddr* him, socklen_t* len); - static int sendto(int fd, char* buf, size_t len, uint flags, - struct sockaddr* to, socklen_t tolen); - static int socket_available(int fd, jint* pbytes); - - static int get_sock_opt(int fd, int level, int optname, - char* optval, socklen_t* optlen); - static int set_sock_opt(int fd, int level, int optname, - const char* optval, socklen_t optlen); - static int get_host_name(char* name, int namelen); - static struct hostent* get_host_by_name(char* name); // Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal)
--- a/hotspot/src/share/vm/utilities/debug.cpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/utilities/debug.cpp Fri Oct 31 12:01:27 2014 -1000 @@ -256,16 +256,18 @@ static const char* name[] = { "shared read only space", "shared read write space", - "shared miscellaneous data space" + "shared miscellaneous data space", + "shared miscellaneous code space" }; static const char* flag[] = { "SharedReadOnlySize", "SharedReadWriteSize", - "SharedMiscDataSize" + "SharedMiscDataSize", + "SharedMiscCodeSize" }; warning("\nThe %s is not large enough\n" - "to preload requested classes. Use -XX:%s=\n" + "to preload requested classes. Use -XX:%s=<size>\n" "to increase the initial size of %s.\n", name[shared_space], flag[shared_space], name[shared_space]); exit(2);
--- a/hotspot/src/share/vm/utilities/debug.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/utilities/debug.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -245,7 +245,8 @@ enum SharedSpaceType { SharedReadOnly, SharedReadWrite, - SharedMiscData + SharedMiscData, + SharedMiscCode }; void report_out_of_shared_space(SharedSpaceType space_type);
--- a/hotspot/src/share/vm/utilities/dtrace_disabled.hpp Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/src/share/vm/utilities/dtrace_disabled.hpp Fri Oct 31 12:01:27 2014 -1000 @@ -27,7 +27,7 @@ /* This file contains dummy provider probes needed when compiling a hotspot * that does not support dtrace probes. This could be because we're building - * on a system that doesn't suuport dtrace or because we're bulding a variant + * on a system that doesn't support dtrace or because we're bulding a variant * of hotspot (like core) where we do not support dtrace */ #if !defined(DTRACE_ENABLED)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/arguments/TestUseNUMAInterleaving.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 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 TestUseNUMAInterleaving + * @summary Tests that UseNUMAInterleaving enabled for all collectors by + * ergonomics, on all platforms when UseNUMA feature is enabled. + * @bug 8059614 + * @key gc + * @library /testlibrary + * @run driver TestUseNUMAInterleaving + */ +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class TestUseNUMAInterleaving { + + public static void main(String[] args) throws Exception { + String[] vmargs = new String[]{ + "-XX:+UseNUMA", + "-XX:+PrintFlagsFinal", + "-version" + }; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, vmargs); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + boolean isNUMAEnabled + = Boolean.parseBoolean(output.firstMatch(NUMA_FLAG_PATTERN, 1)); + + if (isNUMAEnabled) { + output.shouldMatch("\\bUseNUMAInterleaving\\b.*?=.*?true"); + System.out.println(output.getStdout()); + } else { + System.out.println(output.firstMatch(NUMA_FLAG_PATTERN)); + System.out.println(output.firstMatch(NUMA_FLAG_PATTERN, 1)); + } + } + + private static final String NUMA_FLAG_PATTERN = "\\bUseNUMA\\b.*?=.*?([a-z]+)"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/RedefineTests/RedefineAnnotations.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2014, 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 + * @library /testlibrary + * @summary Test that type annotations are retained after a retransform + * @run main RedefineAnnotations buildagent + * @run main/othervm -javaagent:redefineagent.jar RedefineAnnotations + */ + +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.lang.NoSuchFieldException; +import java.lang.NoSuchMethodException; +import java.lang.RuntimeException; +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.lang.instrument.UnmodifiableClassException; +import java.lang.reflect.AnnotatedArrayType; +import java.lang.reflect.AnnotatedParameterizedType; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.AnnotatedWildcardType; +import java.lang.reflect.Executable; +import java.lang.reflect.TypeVariable; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import static jdk.internal.org.objectweb.asm.Opcodes.ASM5; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE_USE) +@interface TestAnn { + String site(); +} + +public class RedefineAnnotations { + static Instrumentation inst; + public static void premain(String agentArgs, Instrumentation inst) { + RedefineAnnotations.inst = inst; + } + + static class Transformer implements ClassFileTransformer { + + public byte[] asm(ClassLoader loader, String className, + Class<?> classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + + ClassWriter cw = new ClassWriter(0); + ClassVisitor cv = new ReAddDummyFieldsClassVisitor(ASM5, cw) { }; + ClassReader cr = new ClassReader(classfileBuffer); + cr.accept(cv, 0); + return cw.toByteArray(); + } + + public class ReAddDummyFieldsClassVisitor extends ClassVisitor { + + LinkedList<F> fields = new LinkedList<>(); + + public ReAddDummyFieldsClassVisitor(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override public FieldVisitor visitField(int access, String name, + String desc, String signature, Object value) { + if (name.startsWith("dummy")) { + // Remove dummy field + fields.addLast(new F(access, name, desc, signature, value)); + return null; + } + return cv.visitField(access, name, desc, signature, value); + } + + @Override public void visitEnd() { + F f; + while ((f = fields.pollFirst()) != null) { + // Re-add dummy fields + cv.visitField(f.access, f.name, f.desc, f.signature, f.value); + } + } + + private class F { + private int access; + private String name; + private String desc; + private String signature; + private Object value; + F(int access, String name, String desc, String signature, Object value) { + this.access = access; + this.name = name; + this.desc = desc; + this.signature = signature; + this.value = value; + } + } + } + + @Override public byte[] transform(ClassLoader loader, String className, + Class<?> classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + + if (className.contains("TypeAnnotatedTestClass")) { + try { + // Here we remove and re-add the dummy fields. This shuffles the constant pool + return asm(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); + } catch (Throwable e) { + // The retransform native code that called this method does not propagate + // exceptions. Instead of getting an uninformative generic error, catch + // problems here and print it, then exit. + e.printStackTrace(); + System.exit(1); + } + } + return null; + } + } + + private static void buildAgent() { + try { + ClassFileInstaller.main("RedefineAnnotations"); + } catch (Exception e) { + throw new RuntimeException("Could not write agent classfile", e); + } + + try { + PrintWriter pw = new PrintWriter("MANIFEST.MF"); + pw.println("Premain-Class: RedefineAnnotations"); + pw.println("Agent-Class: RedefineAnnotations"); + pw.println("Can-Retransform-Classes: true"); + pw.close(); + } catch (FileNotFoundException e) { + throw new RuntimeException("Could not write manifest file for the agent", e); + } + + sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar"); + if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineAnnotations.class" })) { + throw new RuntimeException("Could not write the agent jar file"); + } + } + + public static void main(String argv[]) throws NoSuchFieldException, NoSuchMethodException { + if (argv.length == 1 && argv[0].equals("buildagent")) { + buildAgent(); + return; + } + + if (inst == null) { + throw new RuntimeException("Instrumentation object was null"); + } + + RedefineAnnotations test = new RedefineAnnotations(); + test.testTransformAndVerify(); + } + + // Class type annotations + private Annotation classTypeParameterTA; + private Annotation extendsTA; + private Annotation implementsTA; + + // Field type annotations + private Annotation fieldTA; + private Annotation innerTA; + private Annotation[] arrayTA = new Annotation[4]; + private Annotation[] mapTA = new Annotation[5]; + + // Method type annotations + private Annotation returnTA, methodTypeParameterTA, formalParameterTA, throwsTA; + + private void testTransformAndVerify() + throws NoSuchFieldException, NoSuchMethodException { + + Class<TypeAnnotatedTestClass> c = TypeAnnotatedTestClass.class; + Class<?> myClass = c; + + /* + * Verify that the expected annotations are where they should be before transform. + */ + verifyClassTypeAnnotations(c); + verifyFieldTypeAnnotations(c); + verifyMethodTypeAnnotations(c); + + try { + inst.addTransformer(new Transformer(), true); + inst.retransformClasses(myClass); + } catch (UnmodifiableClassException e) { + throw new RuntimeException(e); + } + + /* + * Verify that the expected annotations are where they should be after transform. + * Also verify that before and after are equal. + */ + verifyClassTypeAnnotations(c); + verifyFieldTypeAnnotations(c); + verifyMethodTypeAnnotations(c); + } + + private void verifyClassTypeAnnotations(Class c) { + Annotation anno; + + anno = c.getTypeParameters()[0].getAnnotations()[0]; + verifyTestAnn(classTypeParameterTA, anno, "classTypeParameter"); + classTypeParameterTA = anno; + + anno = c.getAnnotatedSuperclass().getAnnotations()[0]; + verifyTestAnn(extendsTA, anno, "extends"); + extendsTA = anno; + + anno = c.getAnnotatedInterfaces()[0].getAnnotations()[0]; + verifyTestAnn(implementsTA, anno, "implements"); + implementsTA = anno; + } + + private void verifyFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + verifyBasicFieldTypeAnnotations(c); + verifyInnerFieldTypeAnnotations(c); + verifyArrayFieldTypeAnnotations(c); + verifyMapFieldTypeAnnotations(c); + } + + private void verifyBasicFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno = c.getDeclaredField("typeAnnotatedBoolean").getAnnotatedType().getAnnotations()[0]; + verifyTestAnn(fieldTA, anno, "field"); + fieldTA = anno; + } + + private void verifyInnerFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + AnnotatedType at = c.getDeclaredField("typeAnnotatedInner").getAnnotatedType(); + Annotation anno = at.getAnnotations()[0]; + verifyTestAnn(innerTA, anno, "inner"); + innerTA = anno; + } + + private void verifyArrayFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno; + AnnotatedType at; + + at = c.getDeclaredField("typeAnnotatedArray").getAnnotatedType(); + anno = at.getAnnotations()[0]; + verifyTestAnn(arrayTA[0], anno, "array1"); + arrayTA[0] = anno; + + for (int i = 1; i <= 3; i++) { + at = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType(); + anno = at.getAnnotations()[0]; + verifyTestAnn(arrayTA[i], anno, "array" + (i + 1)); + arrayTA[i] = anno; + } + } + + private void verifyMapFieldTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + + Annotation anno; + AnnotatedType atBase; + AnnotatedType atParameter; + atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType(); + + anno = atBase.getAnnotations()[0]; + verifyTestAnn(mapTA[0], anno, "map1"); + mapTA[0] = anno; + + atParameter = + ((AnnotatedParameterizedType) atBase). + getAnnotatedActualTypeArguments()[0]; + anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0]; + verifyTestAnn(mapTA[1], anno, "map2"); + mapTA[1] = anno; + + anno = + ((AnnotatedWildcardType) atParameter). + getAnnotatedUpperBounds()[0].getAnnotations()[0]; + verifyTestAnn(mapTA[2], anno, "map3"); + mapTA[2] = anno; + + atParameter = + ((AnnotatedParameterizedType) atBase). + getAnnotatedActualTypeArguments()[1]; + anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0]; + verifyTestAnn(mapTA[3], anno, "map4"); + mapTA[3] = anno; + + anno = + ((AnnotatedParameterizedType) atParameter). + getAnnotatedActualTypeArguments()[0].getAnnotations()[0]; + verifyTestAnn(mapTA[4], anno, "map5"); + mapTA[4] = anno; + } + + private void verifyMethodTypeAnnotations(Class c) + throws NoSuchFieldException, NoSuchMethodException { + Annotation anno; + Executable typeAnnotatedMethod = + c.getDeclaredMethod("typeAnnotatedMethod", TypeAnnotatedTestClass.class); + + anno = typeAnnotatedMethod.getAnnotatedReturnType().getAnnotations()[0]; + verifyTestAnn(returnTA, anno, "return"); + returnTA = anno; + + anno = typeAnnotatedMethod.getTypeParameters()[0].getAnnotations()[0]; + verifyTestAnn(methodTypeParameterTA, anno, "methodTypeParameter"); + methodTypeParameterTA = anno; + + anno = typeAnnotatedMethod.getAnnotatedParameterTypes()[0].getAnnotations()[0]; + verifyTestAnn(formalParameterTA, anno, "formalParameter"); + formalParameterTA = anno; + + anno = typeAnnotatedMethod.getAnnotatedExceptionTypes()[0].getAnnotations()[0]; + verifyTestAnn(throwsTA, anno, "throws"); + throwsTA = anno; + } + + private static void verifyTestAnn(Annotation verifyAgainst, Annotation anno, String expectedSite) { + verifyTestAnnSite(anno, expectedSite); + + // When called before transform verifyAgainst will be null, when called + // after transform it will be the annotation from before the transform + if (verifyAgainst != null) { + assertTrue(anno.equals(verifyAgainst), + "Annotations do not match before and after." + + " Before: \"" + verifyAgainst + "\", After: \"" + anno + "\""); + } + } + + private static void verifyTestAnnSite(Annotation testAnn, String expectedSite) { + String expectedAnn = "@TestAnn(site=" + expectedSite + ")"; + assertTrue(testAnn.toString().equals(expectedAnn), + "Expected \"" + expectedAnn + "\", got \"" + testAnn + "\""); + } + + public static class TypeAnnotatedTestClass <@TestAnn(site="classTypeParameter") S,T> + extends @TestAnn(site="extends") Thread + implements @TestAnn(site="implements") Runnable { + + public @TestAnn(site="field") boolean typeAnnotatedBoolean; + + public + RedefineAnnotations. + @TestAnn(site="inner") TypeAnnotatedTestClass + typeAnnotatedInner; + + public + @TestAnn(site="array4") boolean + @TestAnn(site="array1") [] + @TestAnn(site="array2") [] + @TestAnn(site="array3") [] + typeAnnotatedArray; + + public @TestAnn(site="map1") Map + <@TestAnn(site="map2") ? extends @TestAnn(site="map3") String, + @TestAnn(site="map4") List<@TestAnn(site="map5") Object>> typeAnnotatedMap; + + public int dummy1; + public int dummy2; + public int dummy3; + + @TestAnn(site="return") <@TestAnn(site="methodTypeParameter") U,V> Class + typeAnnotatedMethod(@TestAnn(site="formalParameter") TypeAnnotatedTestClass arg) + throws @TestAnn(site="throws") ClassNotFoundException { + + @TestAnn(site="local_variable_type") int foo = 0; + throw new ClassNotFoundException(); + } + + public void run() {} + } +}
--- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java Fri Oct 31 12:01:27 2014 -1000 @@ -51,9 +51,12 @@ // Known issue, JDK-8038422 (assert() on Windows) // new SharedSizeTestData("-XX:SharedMiscDataSize", "500k", "miscellaneous data"), - // This will cause a VM crash; commenting out for now; see bug JDK-8038268 - // @ignore JDK-8038268 - // new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"), + // Too small of a misc code size should not cause a vm crash. + // It should result in the following error message: + // The shared miscellaneous code space is not large enough + // to preload requested classes. Use -XX:SharedMiscCodeSize= + // to increase the initial size of shared miscellaneous code space. + new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"), // these values are larger than default ones, but should // be acceptable and not cause failure
--- a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java Fri Oct 31 11:31:30 2014 +0000 +++ b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java Fri Oct 31 12:01:27 2014 -1000 @@ -33,11 +33,12 @@ import java.util.function.*; import java.util.*; +public class InvokespecialInterface { interface I { default void imethod() { System.out.println("I::imethod"); } } -class C implements I { +static class C implements I { public void foo() { I.super.imethod(); } // invokespecial InterfaceMethod public void bar() { I i = this; i.imethod(); } // invokeinterface same public void doSomeInvokedynamic() { @@ -48,7 +49,6 @@ } } -public class InvokespecialInterface { public static void main(java.lang.String[] unused) { // need to create C and call I::foo() C c = new C();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/lambda-features/TestInterfaceInit.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 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 8034275 + * @summary [JDK 8u40] Test interface initialization: only for interfaces declaring default methods + * @run main TestInterfaceInit + */ +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +public class TestInterfaceInit { + + static List<Class<?>> cInitOrder = new ArrayList<>(); + + // Declares a default method and initializes + interface I { + boolean v = TestInterfaceInit.out(I.class); + default void x() {} + } + + // Declares a default method and initializes + interface J extends I { + boolean v = TestInterfaceInit.out(J.class); + default void x() {} + } + // No default method, does not initialize + interface JN extends J { + boolean v = TestInterfaceInit.out(JN.class); + } + + // Declares a default method and initializes + interface K extends I { + boolean v = TestInterfaceInit.out(K.class); + default void x() {} + } + + // No default method, does not initialize + interface KN extends K { + boolean v = TestInterfaceInit.out(KN.class); + } + + interface L extends JN, KN { + boolean v = TestInterfaceInit.out(L.class); + default void x() {} + } + + public static void main(String[] args) { + // Trigger initialization + boolean v = L.v; + + List<Class<?>> expectedCInitOrder = Arrays.asList(I.class,J.class,K.class,L.class); + if (!cInitOrder.equals(expectedCInitOrder)) { + throw new RuntimeException(String.format("Class initialization array %s not equal to expected array %s", cInitOrder, expectedCInitOrder)); + } + } + + static boolean out(Class c) { + System.out.println("#: initializing " + c.getName()); + cInitOrder.add(c); + return true; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/lambda-features/TestInterfaceOrder.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014, 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 8034275 + * @summary [JDK 8u40] Test interface initialization order + * @run main TestInterfaceOrder + */ + +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; + +public class TestInterfaceOrder { + static List<Class<?>> cInitOrder = new ArrayList<>(); + + public static void main(java.lang.String[] args) { + //Trigger initialization + C c = new C(); + + List<Class<?>> expectedCInitOrder = Arrays.asList(I.class, J.class, A.class, K.class, B.class, L.class, C.class); + if (!cInitOrder.equals(expectedCInitOrder)) { + throw new RuntimeException(String.format("Class initialization order %s not equal to expected order %s", cInitOrder, expectedCInitOrder)); + } + } + + interface I { + boolean v = TestInterfaceOrder.out(I.class); + default void i() {} + } + + interface J extends I { + boolean v = TestInterfaceOrder.out(J.class); + default void j() {} + } + + static class A implements J { + static boolean v = TestInterfaceOrder.out(A.class); + } + + interface K extends I { + boolean v = TestInterfaceOrder.out(K.class); + default void k() {} + } + + static class B extends A implements K { + static boolean v = TestInterfaceOrder.out(B.class); + } + + interface L { + boolean v = TestInterfaceOrder.out(L.class); + default void l() {} + } + + static class C extends B implements L { + static boolean v = TestInterfaceOrder.out(C.class); + } + + + static boolean out(Class c) { + System.out.println("#: initializing " + c.getName()); + cInitOrder.add(c); + return true; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/reflect/ArrayGetIntException.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, 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 6191224 + * @summary (reflect) Misleading detail string in IllegalArgumentException thrown by Array.get<Type> + * @run main ArrayGetIntException + */ +import java.io.*; +import java.lang.reflect.Array; + +public class ArrayGetIntException { + public static void main(String[] args) throws Exception { + Object[] objArray = {new Integer(Integer.MAX_VALUE)}; + + // this access is legal + try { + System.out.println(Array.get(objArray, 0)); + System.out.println("Test #1 PASSES"); + } catch(Exception e) { + failTest("Test #1 FAILS - legal access denied" + e.getMessage()); + } + + // this access is not legal, but needs to generate the proper exception message + try { + System.out.println(Array.getInt(objArray, 0)); + failTest("Test #2 FAILS - no exception"); + } catch(Exception e) { + System.out.println(e); + if (e.getMessage().equals("Argument is not an array of primitive type")) { + System.out.println("Test #2 PASSES"); + } else { + failTest("Test #2 FAILS - incorrect message: " + e.getMessage()); + } + } + + // this access is not legal, but needs to generate the proper exception message + try { + System.out.println(Array.getInt(new Object(), 0)); + failTest("Test #3 FAILS - no exception"); + } catch(Exception e) { + System.out.println(e); + if (e.getMessage().equals("Argument is not an array")) { + System.out.println("Test #3 PASSES"); + } else { + failTest("Test #3 FAILS - incorrect message: " + e.getMessage()); + } + } + } + + private static void failTest(String errStr) { + System.out.println(errStr); + throw new Error(errStr); + } +}
--- a/jaxp/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/jaxp/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -279,3 +279,4 @@ 6b343b9b7a7008f5f699a2d99881163cab7a2986 jdk9-b34 b9370464572fc663a38956047aa612d6e7854c3d jdk9-b35 61b4c9acaa58e482db6601ec5dc4fc3d2d8dbb55 jdk9-b36 +48e4ec70cc1c8651e4a0324d91f193c4edd83af9 jdk9-b37
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/io/UTF8Reader.java Fri Oct 31 12:01:27 2014 -1000 @@ -529,6 +529,16 @@ invalidByte(4, 4, b2); } + // check if output buffer is large enough to hold 2 surrogate chars + if (out + 1 >= ch.length) { + fBuffer[0] = (byte)b0; + fBuffer[1] = (byte)b1; + fBuffer[2] = (byte)b2; + fBuffer[3] = (byte)b3; + fOffset = 4; + return out - offset; + } + // decode bytes into surrogate characters int uuuuu = ((b0 << 2) & 0x001C) | ((b1 >> 4) & 0x0003); if (uuuuu > 0x10) {
--- a/jaxws/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/jaxws/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -282,3 +282,4 @@ 28ea43d925f1e5250976097a2977dd3e66e11f0b jdk9-b34 afe0c89e2edbdfb1a7ceff3d9b3ff46c4186202f jdk9-b35 84803c3be7f79d29c7dc40749d7743675f64107a jdk9-b36 +90de6ecbff46386a3f9d6f7ca876e7aa6381f50a jdk9-b37
--- a/jdk/.hgtags Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/.hgtags Fri Oct 31 12:01:27 2014 -1000 @@ -279,3 +279,4 @@ 21568031434d7a9dbb0cc6516cc3183d349c2253 jdk9-b34 e549291a0227031310fa91c574891f892d27f959 jdk9-b35 cdcf2e599e42935c2d1d19a24bb19e808aeb43b5 jdk9-b36 +27c3345d6dce39a22c262f30bb1f0e0b00c3709e jdk9-b37
--- a/jdk/make/copy/Copy-java.base.gmk Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/copy/Copy-java.base.gmk Fri Oct 31 12:01:27 2014 -1000 @@ -48,22 +48,6 @@ ################################################################################ -CALENDARS_SRC := $(JDK_TOPDIR)/src/java.base/share/conf - -$(LIB_DST_DIR)/calendars.properties: $(CALENDARS_SRC)/calendars.properties - $(call install-file) - -BASE_CONF_FILES += $(LIB_DST_DIR)/calendars.properties - -$(LIB_DST_DIR)/hijrah-config-umalqura.properties: $(CALENDARS_SRC)/hijrah-config-umalqura.properties - $(MKDIR) -p $(@D) - $(RM) $@ - $(CP) $< $@ - -BASE_CONF_FILES += $(LIB_DST_DIR)/hijrah-config-umalqura.properties - -################################################################################ - ifneq ($(findstring $(OPENJDK_TARGET_OS), windows aix),) TZMAPPINGS_SRC := $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/conf
--- a/jdk/make/copy/Copy-java.desktop.gmk Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/copy/Copy-java.desktop.gmk Fri Oct 31 12:01:27 2014 -1000 @@ -67,8 +67,11 @@ FREETYPE_TARGET_LIB := $(JDK_OUTPUTDIR)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/$(call SHARED_LIBRARY,freetype).6 endif + # We can't use $(install-file) in this rule because it preserves symbolic links and + # libfreetype.so is usually a symbolic link to something like libfreetype.so.6 on Unix. $(FREETYPE_TARGET_LIB): $(FREETYPE_BUNDLE_LIB_PATH)/$(call SHARED_LIBRARY,freetype) - $(install-file) + $(MKDIR) -p $(@D) + $(CP) $< $@ ifeq ($(OPENJDK_BUILD_OS), windows) $(CHMOD) +rx $@ endif
--- a/jdk/make/data/tzdata/VERSION Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/VERSION Fri Oct 31 12:01:27 2014 -1000 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2014g +tzdata2014i
--- a/jdk/make/data/tzdata/africa Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/africa Fri Oct 31 12:01:27 2014 -1000 @@ -133,23 +133,13 @@ # See Africa/Lagos. # Botswana -# From Paul Eggert (2013-02-21): -# Milne says they were regulated by the Cape Town Signal in 1899; -# assume they switched to 2:00 when Cape Town did. -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Gaborone 1:43:40 - LMT 1885 - 1:30 - SAST 1903 Mar - 2:00 - CAT 1943 Sep 19 2:00 - 2:00 1:00 CAST 1944 Mar 19 2:00 - 2:00 - CAT +# See Africa/Maputo. # Burkina Faso # See Africa/Abidjan. # Burundi -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Bujumbura 1:57:28 - LMT 1890 - 2:00 - CAT +# See Africa/Maputo. # Cameroon # See Africa/Lagos. @@ -184,10 +174,7 @@ 3:00 - EAT # Democratic Republic of the Congo -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Lubumbashi 1:49:52 - LMT 1897 Nov 9 - 2:00 - CAT -# The above is for the eastern part; see Africa/Lagos for the western part. +# See Africa/Lagos for the western part and Africa/Maputo for the eastern. # Republic of the Congo # See Africa/Lagos. @@ -339,7 +326,7 @@ # Egypt is to change back to Daylight system on May 15 # http://english.ahram.org.eg/NewsContent/1/64/100735/Egypt/Politics-/Egypts-government-to-reapply-daylight-saving-time-.aspx -# From Gunther Vermier (2015-05-13): +# From Gunther Vermier (2014-05-13): # our Egypt office confirms that the change will be at 15 May "midnight" (24:00) # From Imed Chihi (2014-06-04): @@ -489,11 +476,7 @@ 3:00 - EAT # Lesotho -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Maseru 1:50:00 - LMT 1903 Mar - 2:00 - SAST 1943 Sep 19 2:00 - 2:00 1:00 SAST 1944 Mar 19 2:00 - 2:00 - SAST +# See Africa/Johannesburg. # Liberia # From Paul Eggert (2006-03-22): @@ -575,9 +558,7 @@ 3:00 - EAT # Malawi -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Blantyre 2:20:00 - LMT 1903 Mar - 2:00 - CAT +# See Africa/Maputo. # Mali # Mauritania @@ -987,6 +968,13 @@ # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Maputo 2:10:20 - LMT 1903 Mar 2:00 - CAT +Link Africa/Maputo Africa/Blantyre # Malawi +Link Africa/Maputo Africa/Bujumbura # Burundi +Link Africa/Maputo Africa/Gaborone # Botswana +Link Africa/Maputo Africa/Harare # Zimbabwe +Link Africa/Maputo Africa/Kigali # Rwanda +Link Africa/Maputo Africa/Lubumbashi # E Dem. Rep. of Congo +Link Africa/Maputo Africa/Lusaka # Zambia # Namibia # The 1994-04-03 transition is from Shanks & Pottenger. @@ -1054,9 +1042,7 @@ # Tromelin - inhabited until at least 1958 # Rwanda -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Kigali 2:00:16 - LMT 1935 Jun - 2:00 - CAT +# See Africa/Maputo. # St Helena # See Africa/Abidjan. @@ -1100,6 +1086,9 @@ Zone Africa/Johannesburg 1:52:00 - LMT 1892 Feb 8 1:30 - SAST 1903 Mar 2:00 SA SAST +Link Africa/Johannesburg Africa/Maseru # Lesotho +Link Africa/Johannesburg Africa/Mbabane # Swaziland +# # Marion and Prince Edward Is # scientific station since 1947 # no information @@ -1127,9 +1116,7 @@ Link Africa/Khartoum Africa/Juba # Swaziland -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Mbabane 2:04:24 - LMT 1903 Mar - 2:00 - SAST +# See Africa/Johannesburg. # Tanzania # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -1250,11 +1237,5 @@ 3:00 - EAT # Zambia -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Lusaka 1:53:08 - LMT 1903 Mar - 2:00 - CAT - # Zimbabwe -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Harare 2:04:12 - LMT 1903 Mar - 2:00 - CAT +# See Africa/Maputo.
--- a/jdk/make/data/tzdata/asia Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/asia Fri Oct 31 12:01:27 2014 -1000 @@ -70,10 +70,11 @@ # 3:30 IRST IRDT Iran # 4:00 GST Gulf* # 5:30 IST India -# 7:00 ICT Indochina* +# 7:00 ICT Indochina, most times and locations* # 7:00 WIB west Indonesia (Waktu Indonesia Barat) # 8:00 WITA central Indonesia (Waktu Indonesia Tengah) # 8:00 CST China +# 8:00 IDT Indochina, 1943-45, 1947-55, 1960-75 (some locations)* # 8:00 JWST Western Standard Time (Japan, 1896/1937)* # 9:00 JCST Central Standard Time (Japan, 1896/1937) # 9:00 WIT east Indonesia (Waktu Indonesia Timur) @@ -294,12 +295,8 @@ 6:30 - MMT # Myanmar Time # Cambodia -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Phnom_Penh 6:59:40 - LMT 1906 Jun 9 - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May - 7:00 - ICT +# See Asia/Bangkok. + # China @@ -916,6 +913,10 @@ # Indonesia # +# From Paul Eggert (2014-09-06): +# The 1876 Report of the Secretary of the [US] Navy, p 306 says that Batavia +# civil time was 7:07:12.5; round to even for Jakarta. +# # From Gwillim Law (2001-05-28), overriding Shanks & Pottenger: # http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime # says that Indonesia's time zones changed on 1988-01-01. Looking at some @@ -1733,12 +1734,8 @@ 3:00 - AST # Laos -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Vientiane 6:50:24 - LMT 1906 Jun 9 # or Viangchan - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May - 7:00 - ICT +# See Asia/Bangkok. + # Lebanon # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S @@ -2751,6 +2748,8 @@ Zone Asia/Bangkok 6:42:04 - LMT 1880 6:42:04 - BMT 1920 Apr # Bangkok Mean Time 7:00 - ICT +Link Asia/Bangkok Asia/Phnom_Penh # Cambodia +Link Asia/Bangkok Asia/Vientiane # Laos # Turkmenistan # From Shanks & Pottenger. @@ -2788,22 +2787,65 @@ # Vietnam -# From Paul Eggert (2013-02-21): +# From Paul Eggert (2014-10-04): # Milne gives 7:16:56 for the meridian of Saigon in 1899, as being # used in Lower Laos, Cambodia, and Annam. But this is quite a ways # from Saigon's location. For now, ignore this and stick with Shanks -# and Pottenger. +# and Pottenger for LMT before 1906. # From Arthur David Olson (2008-03-18): # The English-language name of Vietnam's most populous city is "Ho Chi Minh # City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters. -# From Shanks & Pottenger: +# From Paul Eggert (2014-10-21) after a heads-up from Trần Ngọc Quân: +# Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)" +# (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50, +# is quoted verbatim in: +# http://www.thoigian.com.vn/?mPage=P80D01 +# is translated by Brian Inglis in: +# http://mm.icann.org/pipermail/tz/2014-October/021654.html +# and is the basis for the information below. +# +# The 1906 transition was effective July 1 and standardized Indochina to +# Phù Liễn Observatory, legally 104 deg. 17'17" east of Paris. +# It's unclear whether this meant legal Paris Mean Time (00:09:21) or +# the Paris Meridian (2 deg. 20'14.03" E); the former yields 07:06:30.1333... +# and the latter 07:06:29.333... so either way it rounds to 07:06:30, +# which is used below even though the modern-day Phù Liễn Observatory +# is closer to 07:06:31. Abbreviate Phù Liễn Mean Time as PLMT. +# +# The following transitions occurred in Indochina in general (before 1954) +# and in South Vietnam in particular (after 1954): +# To 07:00 on 1911-05-01. +# To 08:00 on 1942-12-31 at 23:00. +# To 09:00 in 1945-03-14 at 23:00. +# To 07:00 on 1945-09-02 in Vietnam. +# To 08:00 on 1947-04-01 in French-controlled Indochina. +# To 07:00 on 1955-07-01 in South Vietnam. +# To 08:00 on 1959-12-31 at 23:00 in South Vietnam. +# To 07:00 on 1975-06-13 in South Vietnam. +# +# Trần cites the following sources; it's unclear which supplied the info above. +# +# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội, +# No. 9, Paris, February 1982. +# +# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)", +# NXB Thống kê, Hanoi, 2000. +# +# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu", +# NXB Thuận Hoá, Huế, 1995. + # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jun 9 - 7:06:20 - SMT 1911 Mar 11 0:01 # Saigon MT? - 7:00 - ICT 1912 May - 8:00 - ICT 1931 May +Zone Asia/Ho_Chi_Minh 7:06:40 - LMT 1906 Jul 1 + 7:06:30 - PLMT 1911 May 1 + 7:00 - ICT 1942 Dec 31 23:00 + 8:00 - IDT 1945 Mar 14 23:00 + 9:00 - JST 1945 Sep 2 + 7:00 - ICT 1947 Apr 1 + 8:00 - IDT 1955 Jul 1 + 7:00 - ICT 1959 Dec 31 23:00 + 8:00 - IDT 1975 Jun 13 7:00 - ICT # Yemen
--- a/jdk/make/data/tzdata/australasia Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/australasia Fri Oct 31 12:01:27 2014 -1000 @@ -354,20 +354,27 @@ # Fiji will end DST on 2014-01-19 02:00: # http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVINGS-TO-END-THIS-MONTH-%281%29.aspx -# From Paul Eggert (2014-01-10): -# For now, guess that Fiji springs forward the Sunday before the fourth -# Monday in October, and springs back the penultimate Sunday in January. -# This is ad hoc, but matches recent practice. +# From Ken Rylander (2014-10-20): +# DST will start Nov. 2 this year. +# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-SUNDAY,-NOVEMBER-2ND.aspx + +# From Paul Eggert (2014-10-20): +# For now, guess DST from 02:00 the first Sunday in November to +# 03:00 the first Sunday on or after January 18. Although ad hoc, it +# matches this year's plan and seems more likely to match future +# practice than guessing no DST. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Fiji 1998 1999 - Nov Sun>=1 2:00 1:00 S Rule Fiji 1999 2000 - Feb lastSun 3:00 0 - Rule Fiji 2009 only - Nov 29 2:00 1:00 S Rule Fiji 2010 only - Mar lastSun 3:00 0 - -Rule Fiji 2010 max - Oct Sun>=21 2:00 1:00 S +Rule Fiji 2010 2013 - Oct Sun>=21 2:00 1:00 S Rule Fiji 2011 only - Mar Sun>=1 3:00 0 - Rule Fiji 2012 2013 - Jan Sun>=18 3:00 0 - -Rule Fiji 2014 max - Jan Sun>=18 2:00 0 - +Rule Fiji 2014 only - Jan Sun>=18 2:00 0 - +Rule Fiji 2014 max - Nov Sun>=1 2:00 1:00 S +Rule Fiji 2015 max - Jan Sun>=18 3:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Pacific/Fiji 11:55:44 - LMT 1915 Oct 26 # Suva 12:00 Fiji FJ%sT # Fiji Time @@ -542,6 +549,30 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 # Port Moresby Mean Time 10:00 - PGT # Papua New Guinea Time +# +# From Paul Eggert (2014-10-13): +# Base the Bougainville entry on the Arawa-Kieta region, which appears to have +# the most people even though it was devastated in the Bougainville Civil War. +# +# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates +# are apparently rough guesswork from the starts of military campaigns. +# The World War II entries below are instead based on Arawa-Kieta. +# The Japanese occupied Kieta in July 1942, +# according to the Pacific War Online Encyclopedia +# http://pwencycl.kgbudge.com/B/o/Bougainville.htm +# and seem to have controlled it until their 1945-08-21 surrender. +# +# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11 +# on 2014-12-28 at 02:00. They call UTC+11 "Bougainville Standard Time"; +# abbreviate this as BST. See: +# http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/ +# +Zone Pacific/Bougainville 10:22:16 - LMT 1880 + 9:48:32 - PMMT 1895 + 10:00 - PGT 1942 Jul + 9:00 - JST 1945 Aug 21 + 10:00 - PGT 2014 Dec 28 2:00 + 11:00 - BST # Pitcairn # Zone NAME GMTOFF RULES FORMAT [UNTIL] @@ -826,6 +857,7 @@ # 10:00 AEST AEDT Eastern Australia # 10:00 ChST Chamorro # 10:30 LHST LHDT Lord Howe* +# 11:00 BST Bougainville* # 11:30 NZMT NZST New Zealand through 1945 # 12:00 NZST NZDT New Zealand 1946-present # 12:15 CHAST Chatham through 1945*
--- a/jdk/make/data/tzdata/europe Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/europe Fri Oct 31 12:01:27 2014 -1000 @@ -91,10 +91,11 @@ # 0:00 WET WEST WEMT Western Europe # 0:19:32.13 AMT NST Amsterdam, Netherlands Summer (1835-1937)* # 0:20 NET NEST Netherlands (1937-1940)* +# 1:00 BST British Standard (1968-1971) # 1:00 CET CEST CEMT Central Europe # 1:00:14 SET Swedish (1879-1899)* # 2:00 EET EEST Eastern Europe -# 3:00 FET Further-eastern Europe* +# 3:00 FET Further-eastern Europe (2011-2014)* # 3:00 MSK MSD MSM* Moscow # From Peter Ilieve (1994-12-04), @@ -746,6 +747,13 @@ # http://www.belta.by/ru/all_news/society/V-Belarusi-otmenjaetsja-perexod-na-sezonnoe-vremja_i_572952.html # http://naviny.by/rubrics/society/2011/09/16/ic_articles_116_175144/ # http://news.tut.by/society/250578.html +# +# From Alexander Bokovoy (2014-10-09): +# Belarussian government decided against changing to winter time.... +# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html +# From Paul Eggert (2014-10-08): +# Hence Belarus can share time zone abbreviations with Moscow again. +# # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Minsk 1:50:16 - LMT 1880 1:50 - MMT 1924 May 2 # Minsk Mean Time @@ -758,7 +766,8 @@ 2:00 - EET 1992 Mar 29 0:00s 2:00 1:00 EEST 1992 Sep 27 0:00s 2:00 Russia EE%sT 2011 Mar 27 2:00s - 3:00 - FET + 3:00 - FET 2014 Oct 26 1:00s + 3:00 - MSK # Belgium # @@ -2524,7 +2533,7 @@ # The Kemerovo region will remain at UTC+7 through the 2014-10-26 change, thus # realigning itself with KRAT. -Zone Asia/Novokuznetsk 5:48:48 - NMT 1920 Jan 6 +Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1 6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time 7:00 Russia KRA%sT 1991 Mar 31 2:00s 6:00 Russia KRA%sT 1992 Jan 19 2:00s
--- a/jdk/make/data/tzdata/northamerica Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/northamerica Fri Oct 31 12:01:27 2014 -1000 @@ -300,6 +300,12 @@ # time zone, but we do go by the Eastern time zone because so many people work # in Columbus." +# From Paul Eggert (2014-09-06): +# Monthly Notices of the Royal Astronomical Society 44, 4 (1884-02-08), 208 +# says that New York City Hall time was 3 minutes 58.4 seconds fast of +# Eastern time (i.e., -4:56:01.6) just before the 1883 switch. Round to the +# nearest second. + # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER Rule NYC 1920 only - Mar lastSun 2:00 1:00 D Rule NYC 1920 only - Oct lastSun 2:00 0 S @@ -1118,17 +1124,16 @@ # An amendment to the Interpretation Act was registered on February 19/2007.... # http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf -# From Paul Eggert (2006-04-25): +# From Paul Eggert (2014-10-18): # H. David Matthews and Mary Vincent's map # "It's about TIME", _Canadian Geographic_ (September-October 1998) -# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp +# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp # contains detailed boundaries for regions observing nonstandard # time and daylight saving time arrangements in Canada circa 1998. # -# INMS, the Institute for National Measurement Standards in Ottawa, has -# information about standard and daylight saving time zones in Canada. -# http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php -# (updated periodically). +# National Research Council Canada maintains info about time zones and DST. +# http://www.nrc-cnrc.gc.ca/eng/services/time/time_zones.html +# http://www.nrc-cnrc.gc.ca/eng/services/time/faq/index.html#Q5 # Its unofficial information is often taken from Matthews and Vincent. # From Paul Eggert (2006-06-27): @@ -1993,10 +1998,7 @@ # [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).] # From Gwillim Law (2005-05-21): -# According to maps at -# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg -# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg -# (both dated 2003), and +# According to ... # http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp # (from a 1998 Canadian Geographic article), the de facto and de jure time # for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year @@ -2005,9 +2007,11 @@ # predates the creation of Nunavut, it probably goes back many years.... # The Inuktitut name of Coral Harbour is Sallit, but it's rarely used. # -# From Paul Eggert (2005-07-26): +# From Paul Eggert (2014-10-17): # For lack of better information, assume that Southampton Island observed -# daylight saving only during wartime. +# daylight saving only during wartime. Gwillim Law's email also +# mentioned maps now maintained by National Research Council Canada; +# see above for an up-to-date link. # From Chris Walton (2007-03-01): # ... the community of Resolute (located on Cornwallis Island in @@ -3008,10 +3012,21 @@ # Shanks & Pottenger give -5:07:12, but Milne records -5:07:10.41 from an # unspecified official document, and says "This time is used throughout the # island". Go with Milne. Round to the nearest second as required by zic. +# +# Shanks & Pottenger give April 28 for the 1974 spring-forward transition, but +# Lance Neita writes that Prime Minister Michael Manley decreed it January 5. +# Assume Neita meant Jan 6 02:00, the same as the US. Neita also writes that +# Manley's supporters associated this act with Manley's nickname "Joshua" +# (recall that in the Bible the sun stood still at Joshua's request), +# and with the Rod of Correction which Manley said he had received from +# Haile Selassie, Emperor of Ethiopia. See: +# Neita L. The politician in all of us. Jamaica Observer 2014-09-20 +# http://www.jamaicaobserver.com/columns/The-politician-in-all-of-us_17573647 +# # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Jamaica -5:07:11 - LMT 1890 # Kingston -5:07:11 - KMT 1912 Feb # Kingston Mean Time - -5:00 - EST 1974 Apr 28 2:00 + -5:00 - EST 1974 -5:00 US E%sT 1984 -5:00 - EST
--- a/jdk/make/data/tzdata/zone.tab Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/data/tzdata/zone.tab Fri Oct 31 12:01:27 2014 -1000 @@ -330,7 +330,8 @@ PF -1732-14934 Pacific/Tahiti Society Islands PF -0900-13930 Pacific/Marquesas Marquesas Islands PF -2308-13457 Pacific/Gambier Gambier Islands -PG -0930+14710 Pacific/Port_Moresby +PG -0930+14710 Pacific/Port_Moresby most locations +PG -0613+15534 Pacific/Bougainville Bougainville PH +1435+12100 Asia/Manila PK +2452+06703 Asia/Karachi PL +5215+02100 Europe/Warsaw
--- a/jdk/make/mapfiles/libjava/mapfile-vers Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/mapfiles/libjava/mapfile-vers Fri Oct 31 12:01:27 2014 -1000 @@ -75,6 +75,7 @@ Java_java_io_FileDescriptor_initIDs; Java_java_io_FileDescriptor_sync; + Java_java_io_FileDescriptor_getAppend; Java_java_io_FileInputStream_available; Java_java_io_FileInputStream_close0; Java_java_io_FileInputStream_initIDs;
--- a/jdk/make/profile-includes.txt Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/make/profile-includes.txt Fri Oct 31 12:01:27 2014 -1000 @@ -54,14 +54,12 @@ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm.diz \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \ - calendars.properties \ classlist \ ext/localedata.jar \ ext/meta-index \ ext/sunec.jar \ ext/sunjce_provider.jar \ ext/sunpkcs11.jar \ - hijrah-config-umalqura.properties \ jce.jar \ jsse.jar \ logging.properties \
--- a/jdk/src/java.base/share/classes/java/io/File.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/io/File.java Fri Oct 31 12:01:27 2014 -1000 @@ -1588,7 +1588,7 @@ /** * A convenience method to set the owner's read permission for this abstract * pathname. On some platforms it may be possible to start the Java virtual - * machine with special privileges that allow it to read files that that are + * machine with special privileges that allow it to read files that are * marked as unreadable. * * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
--- a/jdk/src/java.base/share/classes/java/io/FileOutputStream.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/io/FileOutputStream.java Fri Oct 31 12:01:27 2014 -1000 @@ -26,6 +26,8 @@ package java.io; import java.nio.channels.FileChannel; +import sun.misc.SharedSecrets; +import sun.misc.JavaIOFileDescriptorAccess; import sun.nio.ch.FileChannelImpl; @@ -53,16 +55,17 @@ class FileOutputStream extends OutputStream { /** + * Access to FileDescriptor internals. + */ + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + + /** * The system dependent file descriptor. */ private final FileDescriptor fd; /** - * True if the file is opened for append. - */ - private final boolean append; - - /** * The associated channel, initialized lazily. */ private FileChannel channel; @@ -207,7 +210,6 @@ } this.fd = new FileDescriptor(); fd.attach(this); - this.append = append; this.path = name; open(name, append); @@ -245,7 +247,6 @@ security.checkWrite(fdObj); } this.fd = fdObj; - this.append = false; this.path = null; fd.attach(this); @@ -287,7 +288,7 @@ * @exception IOException if an I/O error occurs. */ public void write(int b) throws IOException { - write(b, append); + write(b, fdAccess.getAppend(fd)); } /** @@ -310,7 +311,7 @@ * @exception IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { - writeBytes(b, 0, b.length, append); + writeBytes(b, 0, b.length, fdAccess.getAppend(fd)); } /** @@ -323,7 +324,7 @@ * @exception IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { - writeBytes(b, off, len, append); + writeBytes(b, off, len, fdAccess.getAppend(fd)); } /** @@ -395,7 +396,7 @@ public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, path, false, true, append, this); + channel = FileChannelImpl.open(fd, path, false, true, this); } return channel; }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DelegatingMethodHandle.java Fri Oct 31 12:01:27 2014 -1000 @@ -44,6 +44,10 @@ super(type, chooseDelegatingForm(target)); } + protected DelegatingMethodHandle(MethodType type, LambdaForm form) { + super(type, form); + } + /** Define this to extract the delegated target which supplies the invocation behavior. */ abstract protected MethodHandle getTarget(); @@ -88,14 +92,31 @@ return makeReinvokerForm(target, MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, NF_getTarget); } + static LambdaForm makeReinvokerForm(MethodHandle target, + int whichCache, + Object constraint, + NamedFunction getTargetFn) { + String debugString; + switch(whichCache) { + case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; + case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; + default: debugString = "MH.reinvoke"; break; + } + // No pre-action needed. + return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null); + } /** Create a LF which simply reinvokes a target of the given basic type. */ static LambdaForm makeReinvokerForm(MethodHandle target, int whichCache, Object constraint, - NamedFunction getTargetFn) { + String debugString, + boolean forceInline, + NamedFunction getTargetFn, + NamedFunction preActionFn) { MethodType mtype = target.type().basicType(); boolean customized = (whichCache < 0 || mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY); + boolean hasPreAction = (preActionFn != null); LambdaForm form; if (!customized) { form = mtype.form().cachedLambdaForm(whichCache); @@ -105,12 +126,16 @@ final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; + final int PRE_ACTION = hasPreAction ? nameCursor++ : -1; final int NEXT_MH = customized ? -1 : nameCursor++; final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); assert(names.length == nameCursor); names[THIS_DMH] = names[THIS_DMH].withConstraint(constraint); Object[] targetArgs; + if (hasPreAction) { + names[PRE_ACTION] = new LambdaForm.Name(preActionFn, names[THIS_DMH]); + } if (customized) { targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); names[REINVOKE] = new LambdaForm.Name(target, targetArgs); // the invoker is the target itself @@ -120,20 +145,14 @@ targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs); } - String debugString; - switch(whichCache) { - case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break; - case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break; - default: debugString = "MH.reinvoke"; break; - } - form = new LambdaForm(debugString, ARG_LIMIT, names); + form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline); if (!customized) { form = mtype.form().setCachedLambdaForm(whichCache, form); } return form; } - private static final NamedFunction NF_getTarget; + static final NamedFunction NF_getTarget; static { try { NF_getTarget = new NamedFunction(DelegatingMethodHandle.class
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Oct 31 12:01:27 2014 -1000 @@ -628,8 +628,13 @@ // Mark this method as a compiled LambdaForm mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true); - // Force inlining of this invoker method. - mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + if (lambdaForm.forceInline) { + // Force inlining of this invoker method. + mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); + } else { + mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); + } + // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Fri Oct 31 12:01:27 2014 -1000 @@ -119,6 +119,7 @@ class LambdaForm { final int arity; final int result; + final boolean forceInline; @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared @@ -243,11 +244,16 @@ LambdaForm(String debugName, int arity, Name[] names, int result) { + this(debugName, arity, names, result, true); + } + LambdaForm(String debugName, + int arity, Name[] names, int result, boolean forceInline) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); this.debugName = fixDebugName(debugName); + this.forceInline = forceInline; int maxOutArity = normalize(); if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) { // Cannot use LF interpreter on very high arity expressions. @@ -255,17 +261,23 @@ compileToBytecode(); } } - LambdaForm(String debugName, int arity, Name[] names) { - this(debugName, - arity, names, LAST_RESULT); + this(debugName, arity, names, LAST_RESULT, true); } - + LambdaForm(String debugName, + int arity, Name[] names, boolean forceInline) { + this(debugName, arity, names, LAST_RESULT, forceInline); + } LambdaForm(String debugName, Name[] formals, Name[] temps, Name result) { this(debugName, - formals.length, buildNames(formals, temps, result), LAST_RESULT); + formals.length, buildNames(formals, temps, result), LAST_RESULT, true); + } + LambdaForm(String debugName, + Name[] formals, Name[] temps, Name result, boolean forceInline) { + this(debugName, + formals.length, buildNames(formals, temps, result), LAST_RESULT, forceInline); } private static Name[] buildNames(Name[] formals, Name[] temps, Name result) { @@ -279,6 +291,10 @@ } private LambdaForm(String sig) { + this(sig, true); + } + + private LambdaForm(String sig, boolean forceInline) { // Make a blank lambda form, which returns a constant zero or null. // It is used as a template for managing the invocation of similar forms that are non-empty. // Called only from getPreparedForm. @@ -287,6 +303,7 @@ this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, sig); this.debugName = "LF.zero"; + this.forceInline = forceInline; assert(nameRefsAreLegal()); assert(isEmpty()); assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Fri Oct 31 12:01:27 2014 -1000 @@ -1438,10 +1438,9 @@ /*non-public*/ void updateForm(LambdaForm newForm) { if (form == newForm) return; - assert(this instanceof DirectMethodHandle && this.internalMemberName().isStatic()); - // ISSUE: Should we have a memory fence here? + newForm.prepare(); // as in MethodHandle.<init> UNSAFE.putObject(this, FORM_OFFSET, newForm); - this.form.prepare(); // as in MethodHandle.<init> + UNSAFE.fullFence(); } private static final long FORM_OFFSET;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.function.Function; import sun.invoke.empty.Empty; import sun.invoke.util.ValueConversions; @@ -713,10 +714,11 @@ LambdaForm form = makeGuardWithTestForm(basicType); BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); BoundMethodHandle mh; + try { mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, - (Object) test, (Object) target, (Object) fallback); + (Object) test, (Object) profile(target), (Object) profile(fallback)); } catch (Throwable ex) { throw uncaughtException(ex); } @@ -724,6 +726,129 @@ return mh; } + + static + MethodHandle profile(MethodHandle target) { + if (DONT_INLINE_THRESHOLD >= 0) { + return makeBlockInlningWrapper(target); + } else { + return target; + } + } + + /** + * Block inlining during JIT-compilation of a target method handle if it hasn't been invoked enough times. + * Corresponding LambdaForm has @DontInline when compiled into bytecode. + */ + static + MethodHandle makeBlockInlningWrapper(MethodHandle target) { + LambdaForm lform = PRODUCE_BLOCK_INLINING_FORM.apply(target); + return new CountingWrapper(target, lform, + PRODUCE_BLOCK_INLINING_FORM, PRODUCE_REINVOKER_FORM, + DONT_INLINE_THRESHOLD); + } + + /** Constructs reinvoker lambda form which block inlining during JIT-compilation for a particular method handle */ + private static final Function<MethodHandle, LambdaForm> PRODUCE_BLOCK_INLINING_FORM = new Function<MethodHandle, LambdaForm>() { + @Override + public LambdaForm apply(MethodHandle target) { + return DelegatingMethodHandle.makeReinvokerForm(target, + MethodTypeForm.LF_DELEGATE_BLOCK_INLINING, CountingWrapper.class, "reinvoker.dontInline", false, + DelegatingMethodHandle.NF_getTarget, CountingWrapper.NF_maybeStopCounting); + } + }; + + /** Constructs simple reinvoker lambda form for a particular method handle */ + private static final Function<MethodHandle, LambdaForm> PRODUCE_REINVOKER_FORM = new Function<MethodHandle, LambdaForm>() { + @Override + public LambdaForm apply(MethodHandle target) { + return DelegatingMethodHandle.makeReinvokerForm(target, + MethodTypeForm.LF_DELEGATE, DelegatingMethodHandle.class, DelegatingMethodHandle.NF_getTarget); + } + }; + + /** + * Counting method handle. It has 2 states: counting and non-counting. + * It is in counting state for the first n invocations and then transitions to non-counting state. + * Behavior in counting and non-counting states is determined by lambda forms produced by + * countingFormProducer & nonCountingFormProducer respectively. + */ + static class CountingWrapper extends DelegatingMethodHandle { + private final MethodHandle target; + private int count; + private Function<MethodHandle, LambdaForm> countingFormProducer; + private Function<MethodHandle, LambdaForm> nonCountingFormProducer; + private volatile boolean isCounting; + + private CountingWrapper(MethodHandle target, LambdaForm lform, + Function<MethodHandle, LambdaForm> countingFromProducer, + Function<MethodHandle, LambdaForm> nonCountingFormProducer, + int count) { + super(target.type(), lform); + this.target = target; + this.count = count; + this.countingFormProducer = countingFromProducer; + this.nonCountingFormProducer = nonCountingFormProducer; + this.isCounting = (count > 0); + } + + @Hidden + @Override + protected MethodHandle getTarget() { + return target; + } + + @Override + public MethodHandle asTypeUncached(MethodType newType) { + MethodHandle newTarget = target.asType(newType); + MethodHandle wrapper; + if (isCounting) { + LambdaForm lform; + lform = countingFormProducer.apply(target); + wrapper = new CountingWrapper(newTarget, lform, countingFormProducer, nonCountingFormProducer, DONT_INLINE_THRESHOLD); + } else { + wrapper = newTarget; // no need for a counting wrapper anymore + } + return (asTypeCache = wrapper); + } + + boolean countDown() { + if (count <= 0) { + // Try to limit number of updates. MethodHandle.updateForm() doesn't guarantee LF update visibility. + if (isCounting) { + isCounting = false; + return true; + } else { + return false; + } + } else { + --count; + return false; + } + } + + @Hidden + static void maybeStopCounting(Object o1) { + CountingWrapper wrapper = (CountingWrapper) o1; + if (wrapper.countDown()) { + // Reached invocation threshold. Replace counting behavior with a non-counting one. + LambdaForm lform = wrapper.nonCountingFormProducer.apply(wrapper.target); + lform.compileToBytecode(); // speed up warmup by avoiding LF interpretation again after transition + wrapper.updateForm(lform); + } + } + + static final NamedFunction NF_maybeStopCounting; + static { + Class<?> THIS_CLASS = CountingWrapper.class; + try { + NF_maybeStopCounting = new NamedFunction(THIS_CLASS.getDeclaredMethod("maybeStopCounting", Object.class)); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } + } + } + static LambdaForm makeGuardWithTestForm(MethodType basicType) { LambdaForm lform = basicType.form().cachedLambdaForm(MethodTypeForm.LF_GWT);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Fri Oct 31 12:01:27 2014 -1000 @@ -47,10 +47,11 @@ static final boolean TRACE_METHOD_LINKAGE; static final boolean USE_LAMBDA_FORM_EDITOR; static final int COMPILE_THRESHOLD; + static final int DONT_INLINE_THRESHOLD; static final int PROFILE_LEVEL; static { - final Object[] values = { false, false, false, false, false, null, null }; + final Object[] values = new Object[8]; AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES"); @@ -59,7 +60,8 @@ values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE"); values[4] = Boolean.getBoolean("java.lang.invoke.MethodHandle.USE_LF_EDITOR"); values[5] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD", 30); - values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); + values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.DONT_INLINE_THRESHOLD", 30); + values[7] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0); return null; } }); @@ -69,7 +71,8 @@ TRACE_METHOD_LINKAGE = (Boolean) values[3]; USE_LAMBDA_FORM_EDITOR = (Boolean) values[4]; COMPILE_THRESHOLD = (Integer) values[5]; - PROFILE_LEVEL = (Integer) values[6]; + DONT_INLINE_THRESHOLD = (Integer) values[6]; + PROFILE_LEVEL = (Integer) values[7]; } /** Tell if any of the debugging switches are turned on.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java Fri Oct 31 12:01:27 2014 -1000 @@ -63,24 +63,25 @@ final @Stable LambdaForm[] lambdaForms; // Indexes into lambdaForms: static final int - LF_INVVIRTUAL = 0, // DMH invokeVirtual - LF_INVSTATIC = 1, - LF_INVSPECIAL = 2, - LF_NEWINVSPECIAL = 3, - LF_INVINTERFACE = 4, - LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier - LF_INTERPRET = 6, // LF interpreter - LF_REBIND = 7, // BoundMethodHandle - LF_DELEGATE = 8, // DelegatingMethodHandle - LF_EX_LINKER = 9, // invokeExact_MT (for invokehandle) - LF_EX_INVOKER = 10, // MHs.invokeExact - LF_GEN_LINKER = 11, // generic invoke_MT (for invokehandle) - LF_GEN_INVOKER = 12, // generic MHs.invoke - LF_CS_LINKER = 13, // linkToCallSite_CS - LF_MH_LINKER = 14, // linkToCallSite_MH - LF_GWC = 15, // guardWithCatch (catchException) - LF_GWT = 16, // guardWithTest - LF_LIMIT = 17; + LF_INVVIRTUAL = 0, // DMH invokeVirtual + LF_INVSTATIC = 1, + LF_INVSPECIAL = 2, + LF_NEWINVSPECIAL = 3, + LF_INVINTERFACE = 4, + LF_INVSTATIC_INIT = 5, // DMH invokeStatic with <clinit> barrier + LF_INTERPRET = 6, // LF interpreter + LF_REBIND = 7, // BoundMethodHandle + LF_DELEGATE = 8, // DelegatingMethodHandle + LF_DELEGATE_BLOCK_INLINING = 9, // Counting DelegatingMethodHandle w/ @DontInline + LF_EX_LINKER = 10, // invokeExact_MT (for invokehandle) + LF_EX_INVOKER = 11, // MHs.invokeExact + LF_GEN_LINKER = 12, // generic invoke_MT (for invokehandle) + LF_GEN_INVOKER = 13, // generic MHs.invoke + LF_CS_LINKER = 14, // linkToCallSite_CS + LF_MH_LINKER = 15, // linkToCallSite_MH + LF_GWC = 16, // guardWithCatch (catchException) + LF_GWT = 17, // guardWithTest + LF_LIMIT = 18; /** Return the type corresponding uniquely (1-1) to this MT-form. * It might have any primitive returns or arguments, but will have no references except Object.
--- a/jdk/src/java.base/share/classes/java/nio/Buffer.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java Fri Oct 31 12:01:27 2014 -1000 @@ -239,7 +239,7 @@ * @throws IllegalArgumentException * If the preconditions on <tt>newPosition</tt> do not hold */ - public final Buffer position(int newPosition) { + public Buffer position(int newPosition) { if ((newPosition > limit) || (newPosition < 0)) throw new IllegalArgumentException(); position = newPosition; @@ -270,7 +270,7 @@ * @throws IllegalArgumentException * If the preconditions on <tt>newLimit</tt> do not hold */ - public final Buffer limit(int newLimit) { + public Buffer limit(int newLimit) { if ((newLimit > capacity) || (newLimit < 0)) throw new IllegalArgumentException(); limit = newLimit; @@ -284,7 +284,7 @@ * * @return This buffer */ - public final Buffer mark() { + public Buffer mark() { mark = position; return this; } @@ -300,7 +300,7 @@ * @throws InvalidMarkException * If the mark has not been set */ - public final Buffer reset() { + public Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); @@ -325,7 +325,7 @@ * * @return This buffer */ - public final Buffer clear() { + public Buffer clear() { position = 0; limit = capacity; mark = -1; @@ -353,7 +353,7 @@ * * @return This buffer */ - public final Buffer flip() { + public Buffer flip() { limit = position; position = 0; mark = -1; @@ -375,7 +375,7 @@ * * @return This buffer */ - public final Buffer rewind() { + public Buffer rewind() { position = 0; mark = -1; return this;
--- a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Fri Oct 31 12:01:27 2014 -1000 @@ -208,4 +208,76 @@ private native boolean isLoaded0(long address, long length, int pageCount); private native void load0(long address, long length); private native void force0(FileDescriptor fd, long address, long length); + + // -- Covariant return type overrides + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer position(int newPosition) { + super.position(newPosition); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer limit(int newLimit) { + super.limit(newLimit); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer mark() { + super.mark(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer reset() { + super.reset(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer clear() { + super.clear(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer flip() { + super.flip(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public final MappedByteBuffer rewind() { + super.rewind(); + return this; + } }
--- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Fri Oct 31 12:01:27 2014 -1000 @@ -1025,6 +1025,106 @@ return offset; } + // -- Covariant return type overrides + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer position(int newPosition) { + super.position(newPosition); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer limit(int newLimit) { + super.limit(newLimit); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer mark() { + super.mark(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer reset() { + super.reset(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer clear() { + super.clear(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer flip() { + super.flip(); + return this; + } + + /** + * {@inheritDoc} + * @since 1.9 + */ + @Override + public +#if[!byte] + final +#end[!byte] + $Type$Buffer rewind() { + super.rewind(); + return this; + } + /** * Compacts this buffer <i>(optional operation)</i>. *
--- a/jdk/src/java.base/share/classes/java/nio/file/FileStore.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/file/FileStore.java Fri Oct 31 12:01:27 2014 -1000 @@ -208,7 +208,7 @@ * @param attribute * the attribute to read - * @return the attribute value; {@code null} may be a valid for some + * @return the attribute value; {@code null} may be valid for some * attributes * * @throws UnsupportedOperationException
--- a/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/nio/file/attribute/package-info.java Fri Oct 31 12:01:27 2014 -1000 @@ -51,7 +51,7 @@ * <p> An attribute view provides a read-only or updatable view of the non-opaque * values, or <em>metadata</em>, associated with objects in a file system. * The {@link java.nio.file.attribute.FileAttributeView} interface is - * extended by several other interfaces that views to specific sets of file + * extended by several other interfaces that provide views to specific sets of file * attributes. {@code FileAttributeViews} are selected by invoking the {@link * java.nio.file.Files#getFileAttributeView} method with a * <em>type-token</em> to identify the required view. Views can also be identified
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Fri Oct 31 12:01:27 2014 -1000 @@ -61,13 +61,14 @@ import java.io.File; import java.io.FileInputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; import java.security.AccessController; -import java.security.PrivilegedActionException; +import java.security.PrivilegedAction; import java.time.Clock; import java.time.DateTimeException; import java.time.Instant; @@ -145,29 +146,8 @@ * property resource that defines the {@code ID}, the {@code calendar type}, * the start of the calendar, the alignment with the * ISO calendar, and the length of each month for a range of years. - * The variants are identified in the {@code calendars.properties} file. - * The new properties are prefixed with {@code "calendars.hijrah."}: - * <table cellpadding="2" border="0" summary="Configuration of Hijrah Calendar Variants"> - * <thead> - * <tr class="tableSubHeadingColor"> - * <th class="colFirst" align="left">Property Name</th> - * <th class="colFirst" align="left">Property value</th> - * <th class="colLast" align="left">Description </th> - * </tr> - * </thead> - * <tbody> - * <tr class="altColor"> - * <td>calendars.hijrah.{ID}</td> - * <td>The property resource defining the {@code {ID}} variant</td> - * <td>The property resource is located with the {@code calendars.properties} file</td> - * </tr> - * <tr class="rowColor"> - * <td>calendars.hijrah.{ID}.type</td> - * <td>The calendar type</td> - * <td>LDML defines the calendar type names</td> - * </tr> - * </tbody> - * </table> + * The variants are loaded by HijrahChronology as a resource from + * hijrah-config-<calendar type>.properties. * <p> * The Hijrah property resource is a set of properties that describe the calendar. * The syntax is defined by {@code java.util.Properties#load(Reader)}. @@ -279,91 +259,41 @@ * Computed by {@link #createEpochMonths}. */ private transient int maxYearLength; - /** - * A reference to the properties stored in - * ${java.home}/lib/calendars.properties - */ - private final transient static Properties calendarProperties; /** - * Prefix of property names for Hijrah calendar variants. + * Prefix of resource names for Hijrah calendar variants. */ - private static final String PROP_PREFIX = "calendar.hijrah."; - /** - * Suffix of property names containing the calendar type of a variant. - */ - private static final String PROP_TYPE_SUFFIX = ".type"; + private static final String RESOURCE_PREFIX = "hijrah-config-"; /** - * Static initialization of the predefined calendars found in the - * lib/calendars.properties file. + * Suffix of resource names for Hijrah calendar variants. + */ + private static final String RESOURCE_SUFFIX = ".properties"; + + /** + * Static initialization of the built-in calendars. + * The data is not loaded until it is used. */ static { - try { - calendarProperties = sun.util.calendar.BaseCalendar.getCalendarProperties(); - } catch (IOException ioe) { - throw new InternalError("Can't initialize lib/calendars.properties", ioe); - } - - try { - INSTANCE = new HijrahChronology("Hijrah-umalqura"); - // Register it by its aliases - AbstractChronology.registerChrono(INSTANCE, "Hijrah"); - AbstractChronology.registerChrono(INSTANCE, "islamic"); - } catch (DateTimeException ex) { - // Absence of Hijrah calendar is fatal to initializing this class. - PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); - logger.severe("Unable to initialize Hijrah calendar: Hijrah-umalqura", ex); - throw new RuntimeException("Unable to initialize Hijrah-umalqura calendar", ex.getCause()); - } - registerVariants(); + INSTANCE = new HijrahChronology("Hijrah-umalqura", "islamic-umalqura"); + // Register it by its aliases + AbstractChronology.registerChrono(INSTANCE, "Hijrah"); + AbstractChronology.registerChrono(INSTANCE, "islamic"); } /** - * For each Hijrah variant listed, create the HijrahChronology and register it. - * Exceptions during initialization are logged but otherwise ignored. + * Create a HijrahChronology for the named variant and type. + * + * @param id the id of the calendar + * @param calType the typeId of the calendar + * @throws IllegalArgumentException if the id or typeId is empty */ - private static void registerVariants() { - for (String name : calendarProperties.stringPropertyNames()) { - if (name.startsWith(PROP_PREFIX)) { - String id = name.substring(PROP_PREFIX.length()); - if (id.indexOf('.') >= 0) { - continue; // no name or not a simple name of a calendar - } - if (id.equals(INSTANCE.getId())) { - continue; // do not duplicate the default - } - try { - // Create and register the variant - HijrahChronology chrono = new HijrahChronology(id); - AbstractChronology.registerChrono(chrono); - } catch (DateTimeException ex) { - // Log error and continue - PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono"); - logger.severe("Unable to initialize Hijrah calendar: " + id, ex); - } - } - } - } - - /** - * Create a HijrahChronology for the named variant. - * The resource and calendar type are retrieved from properties - * in the {@code calendars.properties}. - * The property names are {@code "calendar.hijrah." + id} - * and {@code "calendar.hijrah." + id + ".type"} - * @param id the id of the calendar - * @throws DateTimeException if the calendar type is missing from the properties file. - * @throws IllegalArgumentException if the id is empty - */ - private HijrahChronology(String id) throws DateTimeException { + private HijrahChronology(String id, String calType) { if (id.isEmpty()) { throw new IllegalArgumentException("calendar id is empty"); } - String propName = PROP_PREFIX + id + PROP_TYPE_SUFFIX; - String calType = calendarProperties.getProperty(propName); - if (calType == null || calType.isEmpty()) { - throw new DateTimeException("calendarType is missing or empty for: " + propName); + if (calType.isEmpty()) { + throw new IllegalArgumentException("calendar typeId is empty"); } this.typeId = id; this.calendarType = calType; @@ -866,30 +796,26 @@ /** * Return the configuration properties from the resource. * <p> - * The default location of the variant configuration resource is: + * The location of the variant configuration resource is: * <pre> - * "$java.home/lib/" + resource-name + * "/java/time/chrono/hijrah-config-" + calendarType + ".properties" * </pre> * - * @param resource the name of the calendar property resource + * @param calendarType the calendarType of the calendar variant * @return a Properties containing the properties read from the resource. * @throws Exception if access to the property resource fails */ - private static Properties readConfigProperties(final String resource) throws Exception { - try { - return AccessController - .doPrivileged((java.security.PrivilegedExceptionAction<Properties>) - () -> { - String libDir = System.getProperty("java.home") + File.separator + "lib"; - File file = new File(libDir, resource); - Properties props = new Properties(); - try (InputStream is = new FileInputStream(file)) { - props.load(is); - } - return props; - }); - } catch (PrivilegedActionException pax) { - throw pax.getException(); + private Properties readConfigProperties(final String calendarType) throws Exception { + String resourceName = RESOURCE_PREFIX + calendarType + RESOURCE_SUFFIX; + PrivilegedAction<InputStream> getResourceAction = () -> HijrahChronology.class.getResourceAsStream(resourceName); + FilePermission perm = new FilePermission("<<ALL FILES>>", "read"); + try (InputStream is = AccessController.doPrivileged(getResourceAction, null, perm)) { + if (is == null) { + throw new RuntimeException("Hijrah calendar resource not found: /java/time/chrono/" + resourceName); + } + Properties props = new Properties(); + props.load(is); + return props; } } @@ -906,9 +832,7 @@ */ private void loadCalendarData() { try { - String resourceName = calendarProperties.getProperty(PROP_PREFIX + typeId); - Objects.requireNonNull(resourceName, "Resource missing for calendar: " + PROP_PREFIX + typeId); - Properties props = readConfigProperties(resourceName); + Properties props = readConfigProperties(calendarType); Map<Integer, int[]> years = new HashMap<>(); int minYear = Integer.MAX_VALUE; @@ -937,7 +861,7 @@ default: try { // Everything else is either a year or invalid - int year = Integer.valueOf(key); + int year = Integer.parseInt(key); int[] months = parseMonths((String) entry.getValue()); years.put(year, months); maxYear = Math.max(maxYear, year); @@ -1045,7 +969,7 @@ } for (int i = 0; i < 12; i++) { try { - months[i] = Integer.valueOf(numbers[i]); + months[i] = Integer.parseInt(numbers[i]); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("bad key: " + numbers[i]); } @@ -1067,9 +991,9 @@ throw new IllegalArgumentException("date must be yyyy-MM-dd"); } int[] ymd = new int[3]; - ymd[0] = Integer.valueOf(string.substring(0, 4)); - ymd[1] = Integer.valueOf(string.substring(5, 7)); - ymd[2] = Integer.valueOf(string.substring(8, 10)); + ymd[0] = Integer.parseInt(string, 0, 4, 10); + ymd[1] = Integer.parseInt(string, 5, 7, 10); + ymd[2] = Integer.parseInt(string, 8, 10, 10); return ymd; } catch (NumberFormatException ex) { throw new IllegalArgumentException("date must be yyyy-MM-dd", ex);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/java/time/chrono/hijrah-config-islamic-umalqura.properties Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,369 @@ +# Copyright (c) 2013, 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. +# +# This properties file defines a Hijrah calendar variant. +# +# Fields: +# +# <version> ::= 'version' '=' <version string> +# <id> ::= 'id' '=' <id string> +# <type> ::= 'type' '=' <type string> +# <iso-start> ::= 'iso-start' '=' <start date in the ISO calendar> +# <year> ::= <yyyy> '=' <nn nn nn nn nn nn nn nn nn nn nn nn> +# +# version ... (Required) +# +# id ... (Required) +# Identifies the Java Chronology +# +# type ... (Required) +# Identifies the type of calendar in the standard calendar ID scheme +# iso-start ... (Required) +# Specifies the corresponding ISO date to the first Hijrah day +# in the defined range of dates +# +# year ... (Required) +# Number of days for each month of a Hijrah year +# * Each line defines a year. The years must be in chronological +# order and no gap is allowed. +# * Each line is in the form indicated above. <yyyy> is a Hijrah year and +# nn is the number of days for a month listed in the order of the months. +# * Each year must have 12 months. +# * Each month should be 29 or 30 days long. +# * There must be one or more space characters between the months. +# + +# Version of this definition +version=1.8.0_1 + +# Java chronology ID +id=Hijrah-umalqura + +# Standard calendar type specification +type=islamic-umalqura + +# defines the corresponding ISO date to the earliest Hijrah date +iso-start=1882-11-12 + +# 1 2 3 4 5 6 7 8 9 10 11 12 +1300=30 29 30 29 30 29 30 29 30 29 30 29 +1301=30 30 29 30 29 30 29 30 29 30 29 29 +1302=30 30 30 29 30 30 29 29 30 29 29 30 +1303=29 30 30 29 30 30 29 30 29 30 29 29 +1304=29 30 30 29 30 30 30 29 30 29 30 29 +1305=29 29 30 30 29 30 30 29 30 30 29 29 +1306=30 29 30 29 30 29 30 29 30 30 29 30 +1307=29 30 29 30 29 30 29 30 29 30 29 30 +1308=29 30 30 29 30 29 30 29 30 29 29 30 +1309=29 30 30 30 30 29 29 30 29 29 30 29 +1310=30 29 30 30 30 29 30 29 30 29 29 30 +1311=29 30 29 30 30 30 29 30 29 30 29 29 +1312=30 29 30 29 30 30 29 30 30 29 30 29 +1313=29 30 29 30 29 30 29 30 30 30 29 29 +1314=30 30 29 30 29 29 30 29 30 30 29 30 +1315=29 30 30 29 30 29 29 30 29 30 29 30 +1316=29 30 30 30 29 30 29 29 30 29 30 29 +1317=30 29 30 30 29 30 29 30 29 30 29 29 +1318=30 29 30 30 29 30 30 29 30 29 30 29 +1319=29 30 29 30 30 29 30 29 30 30 29 30 +1320=29 30 29 29 30 29 30 29 30 30 30 29 +1321=30 29 30 29 29 30 29 29 30 30 30 30 +1322=29 30 29 30 29 29 29 30 29 30 30 30 +1323=29 30 30 29 30 29 29 29 30 29 30 30 +1324=29 30 30 29 30 29 30 29 29 30 29 30 +1325=30 29 30 29 30 30 29 30 29 30 29 30 +1326=29 29 30 29 30 30 29 30 29 30 30 29 +1327=30 29 29 30 29 30 29 30 30 29 30 30 +1328=29 30 29 29 30 29 29 30 30 30 29 30 +1329=30 29 30 29 29 30 29 29 30 30 29 30 +1330=30 30 29 30 29 29 30 29 29 30 30 29 +1331=30 30 29 30 30 29 29 30 29 30 29 30 +1332=29 30 29 30 30 29 30 29 30 30 29 29 +1333=30 29 29 30 30 29 30 30 29 30 30 29 +1334=29 29 30 29 30 29 30 30 30 29 30 29 +1335=30 29 30 29 29 30 29 30 30 29 30 30 +1336=29 30 29 30 29 29 30 29 30 29 30 30 +1337=30 29 30 29 30 29 29 30 29 30 29 30 +1338=29 30 30 29 30 30 29 29 30 29 30 29 +1339=30 29 30 29 30 30 30 29 30 29 29 30 +1340=29 29 30 29 30 30 30 30 29 30 29 29 +1341=30 29 29 30 29 30 30 30 29 30 30 29 +1342=29 29 30 29 30 29 30 30 29 30 30 29 +1343=30 29 29 30 29 30 29 30 29 30 30 29 +1344=30 29 30 29 30 30 29 29 30 29 30 29 +1345=30 29 30 30 30 29 30 29 29 30 29 29 +1346=30 29 30 30 30 30 29 30 29 29 30 29 +1347=29 30 29 30 30 30 29 30 30 29 29 30 +1348=29 29 30 29 30 30 29 30 30 30 29 29 +1349=30 29 29 30 29 30 30 29 30 30 29 30 +1350=29 30 29 30 29 30 29 29 30 30 29 30 +1351=30 29 30 29 30 29 30 29 29 30 29 30 +1352=30 29 30 30 29 30 29 30 29 29 30 29 +1353=30 29 30 30 30 29 30 29 29 30 29 30 +1354=29 30 29 30 30 29 30 30 29 30 29 29 +1355=30 29 29 30 30 29 30 30 29 30 30 29 +1356=29 30 29 30 29 30 29 30 29 30 30 30 +1357=29 29 30 29 30 29 29 30 29 30 30 30 +1358=29 30 29 30 29 30 29 29 30 29 30 30 +1359=29 30 30 29 30 29 30 29 29 29 30 30 +1360=29 30 30 30 29 30 29 30 29 29 30 29 +1361=30 29 30 30 29 30 30 29 29 30 29 30 +1362=29 30 29 30 29 30 30 29 30 29 30 29 +1363=30 29 30 29 30 29 30 29 30 29 30 30 +1364=29 30 29 30 29 29 30 29 30 29 30 30 +1365=30 30 29 29 30 29 29 30 29 30 29 30 +1366=30 30 29 30 29 30 29 29 30 29 30 29 +1367=30 30 29 30 30 29 30 29 29 30 29 30 +1368=29 30 29 30 30 30 29 29 30 29 30 29 +1369=30 29 30 29 30 30 29 30 29 30 30 29 +1370=30 29 29 30 29 30 29 30 29 30 30 30 +1371=29 30 29 29 30 29 30 29 30 29 30 30 +1372=30 29 29 30 29 30 29 29 30 29 30 30 +1373=30 29 30 29 30 29 30 29 29 30 29 30 +1374=30 29 30 30 29 30 29 30 29 29 30 29 +1375=30 29 30 30 29 30 30 29 30 29 30 29 +1376=29 30 29 30 29 30 30 30 29 30 29 30 +1377=29 29 30 29 29 30 30 30 29 30 30 29 +1378=30 29 29 29 30 29 30 30 29 30 30 30 +1379=29 30 29 29 29 30 29 30 30 29 30 30 +1380=29 30 29 30 29 30 29 30 29 30 29 30 +1381=29 30 29 30 30 29 30 29 30 29 29 30 +1382=29 30 29 30 30 29 30 30 29 30 29 29 +1383=30 29 29 30 30 30 29 30 30 29 30 29 +1384=29 30 29 29 30 30 29 30 30 30 29 30 +1385=29 29 30 29 29 30 30 29 30 30 30 29 +1386=30 29 29 30 29 29 30 30 29 30 30 29 +1387=30 29 30 29 30 29 30 29 30 29 30 29 +1388=30 30 29 30 29 30 29 30 29 30 29 29 +1389=30 30 29 30 30 29 30 30 29 29 30 29 +1390=29 30 29 30 30 30 29 30 29 30 29 30 +1391=29 29 30 29 30 30 29 30 30 29 30 29 +1392=30 29 29 30 29 30 29 30 30 29 30 30 +1393=29 30 29 29 30 29 30 29 30 29 30 30 +1394=30 29 30 29 29 30 29 30 29 30 29 30 +1395=30 29 30 30 29 30 29 29 30 29 29 30 +1396=30 29 30 30 29 30 30 29 29 30 29 29 +1397=30 29 30 30 29 30 30 30 29 29 29 30 +1398=29 30 29 30 30 29 30 30 29 30 29 29 +1399=30 29 30 29 30 29 30 30 29 30 29 30 +1400=30 29 30 29 29 30 29 30 29 30 29 30 +1401=30 30 29 30 29 29 30 29 29 30 29 30 +1402=30 30 30 29 30 29 29 30 29 29 30 29 +1403=30 30 30 29 30 30 29 29 30 29 29 30 +1404=29 30 30 29 30 30 29 30 29 30 29 29 +1405=30 29 30 29 30 30 30 29 30 29 29 30 +1406=30 29 29 30 29 30 30 29 30 29 30 30 +1407=29 30 29 29 30 29 30 29 30 29 30 30 +1408=30 29 30 29 30 29 29 30 29 29 30 30 +1409=30 30 29 30 29 30 29 29 30 29 29 30 +1410=30 30 29 30 30 29 30 29 29 30 29 29 +1411=30 30 29 30 30 29 30 30 29 29 30 29 +1412=30 29 30 29 30 29 30 30 30 29 29 30 +1413=29 30 29 29 30 29 30 30 30 29 30 29 +1414=30 29 30 29 29 30 29 30 30 29 30 30 +1415=29 30 29 30 29 29 30 29 30 29 30 30 +1416=30 29 30 29 30 29 29 30 29 30 29 30 +1417=30 29 30 30 29 29 30 29 30 29 30 29 +1418=30 29 30 30 29 30 29 30 29 30 29 30 +1419=29 30 29 30 29 30 29 30 30 30 29 29 +1420=29 30 29 29 30 29 30 30 30 30 29 30 +1421=29 29 30 29 29 29 30 30 30 30 29 30 +1422=30 29 29 30 29 29 29 30 30 30 29 30 +1423=30 29 30 29 30 29 29 30 29 30 29 30 +1424=30 29 30 30 29 30 29 29 30 29 30 29 +1425=30 29 30 30 29 30 29 30 30 29 30 29 +1426=29 30 29 30 29 30 30 29 30 30 29 30 +1427=29 29 30 29 30 29 30 30 29 30 30 29 +1428=30 29 29 30 29 29 30 30 30 29 30 30 +1429=29 30 29 29 30 29 29 30 30 29 30 30 +1430=29 30 30 29 29 30 29 30 29 30 29 30 +1431=29 30 30 29 30 29 30 29 30 29 29 30 +1432=29 30 30 30 29 30 29 30 29 30 29 29 +1433=30 29 30 30 29 30 30 29 30 29 30 29 +1434=29 30 29 30 29 30 30 29 30 30 29 29 +1435=30 29 30 29 30 29 30 29 30 30 29 30 +1436=29 30 29 30 29 30 29 30 29 30 29 30 +1437=30 29 30 30 29 29 30 29 30 29 29 30 +1438=30 29 30 30 30 29 29 30 29 29 30 29 +1439=30 29 30 30 30 29 30 29 30 29 29 30 +1440=29 30 29 30 30 30 29 30 29 30 29 29 +1441=30 29 30 29 30 30 29 30 30 29 30 29 +1442=29 30 29 30 29 30 29 30 30 29 30 29 +1443=30 29 30 29 30 29 30 29 30 29 30 30 +1444=29 30 29 30 30 29 29 30 29 30 29 30 +1445=29 30 30 30 29 30 29 29 30 29 29 30 +1446=29 30 30 30 29 30 30 29 29 30 29 29 +1447=30 29 30 30 30 29 30 29 30 29 30 29 +1448=29 30 29 30 30 29 30 30 29 30 29 30 +1449=29 29 30 29 30 29 30 30 29 30 30 29 +1450=30 29 30 29 29 30 29 30 29 30 30 29 +1451=30 30 30 29 29 30 29 29 30 30 29 30 +1452=30 29 30 30 29 29 30 29 29 30 29 30 +1453=30 29 30 30 29 30 29 30 29 29 30 29 +1454=30 29 30 30 29 30 30 29 30 29 30 29 +1455=29 30 29 30 30 29 30 29 30 30 29 30 +1456=29 29 30 29 30 29 30 29 30 30 30 29 +1457=30 29 29 30 29 29 30 29 30 30 30 30 +1458=29 30 29 29 30 29 29 30 29 30 30 30 +1459=29 30 30 29 29 30 29 29 30 29 30 30 +1460=29 30 30 29 30 29 30 29 29 30 29 30 +1461=29 30 30 29 30 29 30 29 30 30 29 29 +1462=30 29 30 29 30 30 29 30 29 30 30 29 +1463=29 30 29 30 29 30 29 30 30 30 29 30 +1464=29 30 29 29 30 29 29 30 30 30 29 30 +1465=30 29 30 29 29 30 29 29 30 30 29 30 +1466=30 30 29 30 29 29 29 30 29 30 30 29 +1467=30 30 29 30 30 29 29 30 29 30 29 30 +1468=29 30 29 30 30 29 30 29 30 29 30 29 +1469=29 30 29 30 30 29 30 30 29 30 29 30 +1470=29 29 30 29 30 30 29 30 30 29 30 29 +1471=30 29 29 30 29 30 29 30 30 29 30 30 +1472=29 30 29 29 30 29 30 29 30 30 29 30 +1473=29 30 29 30 30 29 29 30 29 30 29 30 +1474=29 30 30 29 30 30 29 29 30 29 30 29 +1475=29 30 30 29 30 30 30 29 29 30 29 29 +1476=30 29 30 29 30 30 30 29 30 29 30 29 +1477=29 30 29 29 30 30 30 30 29 30 29 30 +1478=29 29 30 29 30 29 30 30 29 30 30 29 +1479=30 29 29 30 29 30 29 30 29 30 30 29 +1480=30 29 30 29 30 29 30 29 30 29 30 29 +1481=30 29 30 30 29 30 29 30 29 30 29 29 +1482=30 29 30 30 30 30 29 30 29 29 30 29 +1483=29 30 29 30 30 30 29 30 30 29 29 30 +1484=29 29 30 29 30 30 30 29 30 29 30 29 +1485=30 29 29 30 29 30 30 29 30 30 29 30 +1486=29 30 29 29 30 29 30 29 30 30 29 30 +1487=30 29 30 29 30 29 29 30 29 30 29 30 +1488=30 29 30 30 29 30 29 29 30 29 30 29 +1489=30 29 30 30 30 29 30 29 29 30 29 30 +1490=29 30 29 30 30 29 30 30 29 29 30 29 +1491=30 29 29 30 30 29 30 30 29 30 29 30 +1492=29 30 29 29 30 30 29 30 29 30 30 29 +1493=30 29 30 29 30 29 29 30 29 30 30 30 +1494=29 30 29 30 29 30 29 29 29 30 30 30 +1495=29 30 30 29 30 29 29 30 29 29 30 30 +1496=29 30 30 30 29 30 29 29 30 29 29 30 +1497=30 29 30 30 29 30 29 30 29 30 29 30 +1498=29 30 29 30 29 30 30 29 30 29 30 29 +1499=30 29 30 29 29 30 30 29 30 29 30 30 +1500=29 30 29 30 29 29 30 29 30 29 30 30 +1501=30 29 30 29 30 29 29 29 30 29 30 30 +1502=30 30 29 30 29 30 29 29 29 30 30 29 +1503=30 30 29 30 30 29 30 29 29 29 30 30 +1504=29 30 29 30 30 30 29 29 30 29 30 29 +1505=30 29 30 29 30 30 29 30 29 30 30 29 +1506=29 30 29 29 30 30 29 30 30 29 30 30 +1507=29 29 30 29 29 30 30 29 30 29 30 30 +1508=30 29 29 30 29 30 29 29 30 29 30 30 +1509=30 29 30 29 30 29 30 29 29 30 29 30 +1510=30 29 30 30 29 30 29 30 29 29 30 29 +1511=30 29 30 30 29 30 30 29 30 29 29 30 +1512=29 30 29 30 29 30 30 30 29 30 29 30 +1513=29 29 29 30 29 30 30 30 29 30 30 29 +1514=30 29 29 29 30 29 30 30 29 30 30 30 +1515=29 29 30 29 29 30 29 30 30 29 30 30 +1516=29 30 29 30 29 29 30 29 30 29 30 30 +1517=29 30 29 30 29 30 30 29 29 30 29 30 +1518=29 30 29 30 30 29 30 30 29 30 29 29 +1519=30 29 29 30 30 30 29 30 30 29 30 29 +1520=29 30 29 29 30 30 30 29 30 30 29 30 +1521=29 29 29 30 29 30 30 29 30 30 29 30 +1522=30 29 29 29 30 29 30 30 29 30 30 29 +1523=30 29 30 29 30 29 30 29 29 30 30 29 +1524=30 30 29 30 29 30 29 30 29 29 30 29 +1525=30 30 29 30 30 29 30 29 30 29 29 30 +1526=29 30 29 30 30 30 29 30 29 30 29 29 +1527=30 29 30 29 30 30 29 30 30 29 30 29 +1528=30 29 29 30 29 30 29 30 30 29 30 30 +1529=29 30 29 29 30 29 30 29 30 29 30 30 +1530=29 30 30 29 29 30 29 30 29 29 30 30 +1531=29 30 30 30 29 29 30 29 30 29 29 30 +1532=29 30 30 30 29 30 30 29 29 29 30 29 +1533=30 29 30 30 30 29 30 29 30 29 29 30 +1534=29 30 29 30 30 29 30 30 29 29 30 29 +1535=30 29 30 29 30 29 30 30 29 30 29 30 +1536=29 30 29 30 29 30 29 30 29 30 29 30 +1537=30 29 30 30 29 29 30 29 29 30 29 30 +1538=30 30 29 30 30 29 29 30 29 29 30 29 +1539=30 30 30 29 30 30 29 29 30 29 29 30 +1540=29 30 30 29 30 30 29 30 29 29 30 29 +1541=30 29 30 29 30 30 30 29 30 29 29 30 +1542=29 30 29 30 29 30 30 29 30 29 30 30 +1543=29 30 29 29 30 29 30 29 30 29 30 30 +1544=30 29 30 29 29 30 29 30 29 30 29 30 +1545=30 30 29 30 29 29 30 29 30 29 29 30 +1546=30 30 29 30 29 30 29 30 29 30 29 29 +1547=30 30 29 30 30 29 30 29 30 29 30 29 +1548=30 29 29 30 30 29 30 30 29 30 29 30 +1549=29 30 29 29 30 29 30 30 30 29 30 29 +1550=30 29 30 29 29 29 30 30 30 29 30 30 +1551=29 30 29 29 30 29 29 30 30 29 30 30 +1552=30 29 30 29 29 30 29 29 30 30 29 30 +1553=30 29 30 29 30 29 30 29 30 29 30 29 +1554=30 29 30 29 30 30 29 30 29 30 29 30 +1555=29 29 30 29 30 30 29 30 30 29 30 29 +1556=30 29 29 30 29 30 29 30 30 30 29 30 +1557=29 30 29 29 29 30 29 30 30 30 30 29 +1558=30 29 30 29 29 29 30 29 30 30 30 29 +1559=30 30 29 29 30 29 29 30 30 29 30 29 +1560=30 30 29 30 29 30 29 30 29 30 29 30 +1561=29 30 30 29 30 29 30 30 29 29 30 29 +1562=29 30 30 29 30 29 30 30 30 29 29 30 +1563=29 30 29 29 30 29 30 30 30 29 30 29 +1564=30 29 30 29 29 30 29 30 30 30 29 30 +1565=29 30 29 30 29 29 30 29 30 30 29 30 +1566=30 29 30 29 30 29 29 30 29 30 29 30 +1567=30 29 30 30 29 30 29 30 29 29 30 29 +1568=30 29 30 30 30 29 30 29 30 29 29 29 +1569=30 29 30 30 30 29 30 30 29 30 29 29 +1570=29 30 29 30 30 29 30 30 30 29 29 30 +1571=29 29 30 29 30 30 29 30 30 29 30 29 +1572=30 29 29 30 29 30 29 30 30 29 30 29 +1573=30 29 30 30 29 30 29 29 30 29 30 29 +1574=30 30 29 30 30 29 30 29 29 30 29 29 +1575=30 30 30 29 30 30 29 30 29 29 29 30 +1576=29 30 30 29 30 30 30 29 30 29 29 29 +1577=30 29 30 30 29 30 30 29 30 29 30 29 +1578=29 30 29 30 29 30 30 29 30 30 29 30 +1579=29 30 29 30 29 29 30 30 29 30 29 30 +1580=29 30 30 29 30 29 29 30 29 30 29 30 +1581=30 30 29 30 29 30 29 29 30 29 30 29 +1582=30 30 29 30 30 29 30 29 30 29 29 29 +1583=30 30 29 30 30 30 29 30 29 30 29 29 +1584=29 30 30 29 30 30 29 30 30 29 30 29 +1585=29 30 29 30 29 30 29 30 30 29 30 30 +1586=29 29 30 29 30 29 29 30 30 30 29 30 +1587=29 30 30 29 29 29 30 29 30 29 30 30 +1588=30 29 30 30 29 29 29 30 29 30 29 30 +1589=30 29 30 30 29 30 29 29 30 29 30 29 +1590=30 29 30 30 30 29 29 30 29 30 29 30 +1591=29 30 29 30 30 29 30 29 30 29 30 29 +1592=30 29 30 29 30 29 30 29 30 30 30 29 +1593=30 29 29 30 29 29 30 29 30 30 30 29 +1594=30 30 29 29 30 29 29 29 30 30 30 30 +1595=29 30 29 30 29 29 30 29 29 30 30 30 +1596=29 30 30 29 30 29 29 30 29 30 29 30 +1597=29 30 30 29 30 29 30 29 30 29 30 29 +1598=30 29 30 29 30 30 29 30 29 30 30 29 +1599=29 30 29 30 29 30 29 30 30 30 29 30 +1600=29 29 30 29 30 29 29 30 30 30 29 30
--- a/jdk/src/java.base/share/classes/java/util/Collection.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/util/Collection.java Fri Oct 31 12:01:27 2014 -1000 @@ -518,7 +518,7 @@ * <p>The default implementation should be overridden by subclasses that * can return a more efficient spliterator. In order to * preserve expected laziness behavior for the {@link #stream()} and - * {@link #parallelStream()}} methods, spliterators should either have the + * {@link #parallelStream()} methods, spliterators should either have the * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be * <em><a href="Spliterator.html#binding">late-binding</a></em>. * If none of these is practical, the overriding class should describe the
--- a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java Fri Oct 31 12:01:27 2014 -1000 @@ -97,8 +97,7 @@ * * This implementation uses * sun.util.calendar.LocalGregorianCalendar to perform most of the - * calendar calculations. LocalGregorianCalendar is configurable - * and reads <JRE_HOME>/lib/calendars.properties at the start-up. + * calendar calculations. */ /**
--- a/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/misc/JavaIOFileDescriptorAccess.java Fri Oct 31 12:01:27 2014 -1000 @@ -33,6 +33,8 @@ public interface JavaIOFileDescriptorAccess { public void set(FileDescriptor obj, int fd); public int get(FileDescriptor fd); + public void setAppend(FileDescriptor obj, boolean append); + public boolean getAppend(FileDescriptor obj); // Only valid on Windows public void setHandle(FileDescriptor obj, long handle);
--- a/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -44,6 +44,8 @@ import java.util.List; import sun.misc.Cleaner; +import sun.misc.JavaIOFileDescriptorAccess; +import sun.misc.SharedSecrets; import sun.security.action.GetPropertyAction; public class FileChannelImpl @@ -52,6 +54,10 @@ // Memory allocation size for mapping buffers private static final long allocationGranularity; + // Access to FileDispatcher internals + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + // Used to make native read and write calls private final FileDispatcher nd; @@ -61,7 +67,6 @@ // File access mode (immutable) private final boolean writable; private final boolean readable; - private final boolean append; // Required to prevent finalization of creating stream (immutable) private final Object parent; @@ -77,31 +82,23 @@ private final Object positionLock = new Object(); private FileChannelImpl(FileDescriptor fd, String path, boolean readable, - boolean writable, boolean append, Object parent) + boolean writable, Object parent) { this.fd = fd; this.readable = readable; this.writable = writable; - this.append = append; this.parent = parent; this.path = path; - this.nd = new FileDispatcherImpl(append); + this.nd = new FileDispatcherImpl(); } - // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel() + // Used by FileInputStream.getChannel(), FileOutputStream.getChannel + // and RandomAccessFile.getChannel() public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, path, readable, writable, false, parent); - } - - // Used by FileOutputStream.getChannel - public static FileChannel open(FileDescriptor fd, String path, - boolean readable, boolean writable, - boolean append, Object parent) - { - return new FileChannelImpl(fd, path, readable, writable, append, parent); + return new FileChannelImpl(fd, path, readable, writable, parent); } private void ensureOpen() throws IOException { @@ -109,7 +106,6 @@ throw new ClosedChannelException(); } - // -- Standard channel operations -- protected void implCloseChannel() throws IOException { @@ -258,6 +254,7 @@ ti = threads.add(); if (!isOpen()) return 0; + boolean append = fdAccess.getAppend(fd); do { // in append-mode then position is advanced to end before writing p = (append) ? nd.size(fd) : position0(fd, -1); @@ -284,7 +281,7 @@ if (!isOpen()) return null; do { - p = position0(fd, newPosition); + p = position0(fd, newPosition); } while ((p == IOStatus.INTERRUPTED) && isOpen()); return this; } finally {
--- a/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -247,7 +247,7 @@ return null; thread = NativeThread.current(); for (;;) { - n = accept0(this.fd, newfd, isaa); + n = accept(this.fd, newfd, isaa); if ((n == IOStatus.INTERRUPTED) && isOpen()) continue; break; @@ -410,6 +410,18 @@ return sb.toString(); } + /** + * Accept a connection on a socket. + * + * @implNote Wrap native call to allow instrumentation. + */ + private int accept(FileDescriptor ssfd, FileDescriptor newfd, + InetSocketAddress[] isaa) + throws IOException + { + return accept0(ssfd, newfd, isaa); + } + // -- Native methods -- // Accepts a new connection, setting the given file descriptor to refer to
--- a/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/CipherBox.java Fri Oct 31 12:01:27 2014 -1000 @@ -560,7 +560,7 @@ + newLen); hd.encodeBuffer( - (ByteBuffer)bb.duplicate().position(pos), System.out); + bb.duplicate().position(pos), System.out); } catch (IOException e) { } } @@ -790,7 +790,7 @@ // The padding data should be filled with the padding length value. int[] results = checkPadding( - (ByteBuffer)bb.duplicate().position(offset + newLen), + bb.duplicate().position(offset + newLen), (byte)(padLen & 0xFF)); if (protocolVersion.v >= ProtocolVersion.TLS10.v) { if (results[0] != 0) { // padding data has invalid bytes
--- a/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/EngineInputRecord.java Fri Oct 31 12:01:27 2014 -1000 @@ -349,8 +349,7 @@ /* * Copy data out of buffer, it's ready to go. */ - ByteBuffer netBB = (ByteBuffer) - (ByteBuffer.allocate(len).put(buf, 0, len).flip()); + ByteBuffer netBB = ByteBuffer.allocate(len).put(buf, 0, len).flip(); engine.writer.putOutboundDataSync(netBB); }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/ssl/EngineOutputRecord.java Fri Oct 31 12:01:27 2014 -1000 @@ -113,9 +113,7 @@ /* * Copy data out of buffer, it's ready to go. */ - ByteBuffer netBB = (ByteBuffer) - ByteBuffer.allocate(len).put(buf, off, len).flip(); - + ByteBuffer netBB = ByteBuffer.allocate(len).put(buf, off, len).flip(); writer.putOutboundData(netBB); }
--- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java Fri Oct 31 12:01:27 2014 -1000 @@ -177,44 +177,6 @@ return (cs == null) ? cal : cs; } - /** - * Returns a {@link Properties} loaded from lib/calendars.properties. - * - * @return a {@link Properties} loaded from lib/calendars.properties - * @throws IOException if an error occurred when reading from the input stream - * @throws IllegalArgumentException if the input stream contains any malformed - * Unicode escape sequences - */ - public static Properties getCalendarProperties() throws IOException { - Properties calendarProps = null; - try { - String homeDir = AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("java.home")); - final String fname = homeDir + File.separator + "lib" + File.separator - + "calendars.properties"; - calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() { - @Override - public Properties run() throws IOException { - Properties props = new Properties(); - try (FileInputStream fis = new FileInputStream(fname)) { - props.load(fis); - } - return props; - } - }); - } catch (PrivilegedActionException e) { - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } else if (cause instanceof IllegalArgumentException) { - throw (IllegalArgumentException) cause; - } - // Should not happen - throw new InternalError(cause); - } - return calendarProps; - } - //////////////////////////////// Calendar API ////////////////////////////////// /**
--- a/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/classes/sun/util/resources/TimeZoneNames.java Fri Oct 31 12:01:27 2014 -1000 @@ -829,7 +829,7 @@ {"Europe/Madrid", CET}, {"Europe/Malta", CET}, {"Europe/Mariehamn", EET}, - {"Europe/Minsk", FET}, + {"Europe/Minsk", MSK}, {"Europe/Monaco", CET}, {"Europe/Moscow", MSK}, {"Europe/Nicosia", EET}, @@ -917,6 +917,9 @@ {"PRT", AST}, {"Pacific/Apia", WST_SAMOA}, {"Pacific/Auckland", NZST}, + {"Pacific/Bougainville", new String[] {"Bougainville Standard Time", "BST", + "Bougainville Daylight Time", "BST", + "Bougainville Time", "BT"}}, {"Pacific/Chatham", CHAST}, {"Pacific/Chuuk", CHUT}, {"Pacific/Easter", EASTER},
--- a/jdk/src/java.base/share/conf/calendars.properties Fri Oct 31 11:31:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -# Copyright (c) 2005, 2014, 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. -# - -# -# Hijrah calendars -# -calendar.hijrah.Hijrah-umalqura: hijrah-config-umalqura.properties -calendar.hijrah.Hijrah-umalqura.type: islamic-umalqura
--- a/jdk/src/java.base/share/conf/hijrah-config-umalqura.properties Fri Oct 31 11:31:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +0,0 @@ -# Copyright (c) 2013, 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. -# -# This properties file defines a Hijrah calendar variant. -# -# Fields: -# -# <version> ::= 'version' '=' <version string> -# <id> ::= 'id' '=' <id string> -# <type> ::= 'type' '=' <type string> -# <iso-start> ::= 'iso-start' '=' <start date in the ISO calendar> -# <year> ::= <yyyy> '=' <nn nn nn nn nn nn nn nn nn nn nn nn> -# -# version ... (Required) -# -# id ... (Required) -# Identifies the Java Chronology -# -# type ... (Required) -# Identifies the type of calendar in the standard calendar ID scheme -# iso-start ... (Required) -# Specifies the corresponding ISO date to the first Hijrah day -# in the defined range of dates -# -# year ... (Required) -# Number of days for each month of a Hijrah year -# * Each line defines a year. The years must be in chronological -# order and no gap is allowed. -# * Each line is in the form indicated above. <yyyy> is a Hijrah year and -# nn is the number of days for a month listed in the order of the months. -# * Each year must have 12 months. -# * Each month should be 29 or 30 days long. -# * There must be one or more space characters between the months. -# - -# Version of this definition -version=1.8.0_1 - -# Java chronology ID -id=Hijrah-umalqura - -# Standard calendar type specification -type=islamic-umalqura - -# defines the corresponding ISO date to the earliest Hijrah date -iso-start=1882-11-12 - -# 1 2 3 4 5 6 7 8 9 10 11 12 -1300=30 29 30 29 30 29 30 29 30 29 30 29 -1301=30 30 29 30 29 30 29 30 29 30 29 29 -1302=30 30 30 29 30 30 29 29 30 29 29 30 -1303=29 30 30 29 30 30 29 30 29 30 29 29 -1304=29 30 30 29 30 30 30 29 30 29 30 29 -1305=29 29 30 30 29 30 30 29 30 30 29 29 -1306=30 29 30 29 30 29 30 29 30 30 29 30 -1307=29 30 29 30 29 30 29 30 29 30 29 30 -1308=29 30 30 29 30 29 30 29 30 29 29 30 -1309=29 30 30 30 30 29 29 30 29 29 30 29 -1310=30 29 30 30 30 29 30 29 30 29 29 30 -1311=29 30 29 30 30 30 29 30 29 30 29 29 -1312=30 29 30 29 30 30 29 30 30 29 30 29 -1313=29 30 29 30 29 30 29 30 30 30 29 29 -1314=30 30 29 30 29 29 30 29 30 30 29 30 -1315=29 30 30 29 30 29 29 30 29 30 29 30 -1316=29 30 30 30 29 30 29 29 30 29 30 29 -1317=30 29 30 30 29 30 29 30 29 30 29 29 -1318=30 29 30 30 29 30 30 29 30 29 30 29 -1319=29 30 29 30 30 29 30 29 30 30 29 30 -1320=29 30 29 29 30 29 30 29 30 30 30 29 -1321=30 29 30 29 29 30 29 29 30 30 30 30 -1322=29 30 29 30 29 29 29 30 29 30 30 30 -1323=29 30 30 29 30 29 29 29 30 29 30 30 -1324=29 30 30 29 30 29 30 29 29 30 29 30 -1325=30 29 30 29 30 30 29 30 29 30 29 30 -1326=29 29 30 29 30 30 29 30 29 30 30 29 -1327=30 29 29 30 29 30 29 30 30 29 30 30 -1328=29 30 29 29 30 29 29 30 30 30 29 30 -1329=30 29 30 29 29 30 29 29 30 30 29 30 -1330=30 30 29 30 29 29 30 29 29 30 30 29 -1331=30 30 29 30 30 29 29 30 29 30 29 30 -1332=29 30 29 30 30 29 30 29 30 30 29 29 -1333=30 29 29 30 30 29 30 30 29 30 30 29 -1334=29 29 30 29 30 29 30 30 30 29 30 29 -1335=30 29 30 29 29 30 29 30 30 29 30 30 -1336=29 30 29 30 29 29 30 29 30 29 30 30 -1337=30 29 30 29 30 29 29 30 29 30 29 30 -1338=29 30 30 29 30 30 29 29 30 29 30 29 -1339=30 29 30 29 30 30 30 29 30 29 29 30 -1340=29 29 30 29 30 30 30 30 29 30 29 29 -1341=30 29 29 30 29 30 30 30 29 30 30 29 -1342=29 29 30 29 30 29 30 30 29 30 30 29 -1343=30 29 29 30 29 30 29 30 29 30 30 29 -1344=30 29 30 29 30 30 29 29 30 29 30 29 -1345=30 29 30 30 30 29 30 29 29 30 29 29 -1346=30 29 30 30 30 30 29 30 29 29 30 29 -1347=29 30 29 30 30 30 29 30 30 29 29 30 -1348=29 29 30 29 30 30 29 30 30 30 29 29 -1349=30 29 29 30 29 30 30 29 30 30 29 30 -1350=29 30 29 30 29 30 29 29 30 30 29 30 -1351=30 29 30 29 30 29 30 29 29 30 29 30 -1352=30 29 30 30 29 30 29 30 29 29 30 29 -1353=30 29 30 30 30 29 30 29 29 30 29 30 -1354=29 30 29 30 30 29 30 30 29 30 29 29 -1355=30 29 29 30 30 29 30 30 29 30 30 29 -1356=29 30 29 30 29 30 29 30 29 30 30 30 -1357=29 29 30 29 30 29 29 30 29 30 30 30 -1358=29 30 29 30 29 30 29 29 30 29 30 30 -1359=29 30 30 29 30 29 30 29 29 29 30 30 -1360=29 30 30 30 29 30 29 30 29 29 30 29 -1361=30 29 30 30 29 30 30 29 29 30 29 30 -1362=29 30 29 30 29 30 30 29 30 29 30 29 -1363=30 29 30 29 30 29 30 29 30 29 30 30 -1364=29 30 29 30 29 29 30 29 30 29 30 30 -1365=30 30 29 29 30 29 29 30 29 30 29 30 -1366=30 30 29 30 29 30 29 29 30 29 30 29 -1367=30 30 29 30 30 29 30 29 29 30 29 30 -1368=29 30 29 30 30 30 29 29 30 29 30 29 -1369=30 29 30 29 30 30 29 30 29 30 30 29 -1370=30 29 29 30 29 30 29 30 29 30 30 30 -1371=29 30 29 29 30 29 30 29 30 29 30 30 -1372=30 29 29 30 29 30 29 29 30 29 30 30 -1373=30 29 30 29 30 29 30 29 29 30 29 30 -1374=30 29 30 30 29 30 29 30 29 29 30 29 -1375=30 29 30 30 29 30 30 29 30 29 30 29 -1376=29 30 29 30 29 30 30 30 29 30 29 30 -1377=29 29 30 29 29 30 30 30 29 30 30 29 -1378=30 29 29 29 30 29 30 30 29 30 30 30 -1379=29 30 29 29 29 30 29 30 30 29 30 30 -1380=29 30 29 30 29 30 29 30 29 30 29 30 -1381=29 30 29 30 30 29 30 29 30 29 29 30 -1382=29 30 29 30 30 29 30 30 29 30 29 29 -1383=30 29 29 30 30 30 29 30 30 29 30 29 -1384=29 30 29 29 30 30 29 30 30 30 29 30 -1385=29 29 30 29 29 30 30 29 30 30 30 29 -1386=30 29 29 30 29 29 30 30 29 30 30 29 -1387=30 29 30 29 30 29 30 29 30 29 30 29 -1388=30 30 29 30 29 30 29 30 29 30 29 29 -1389=30 30 29 30 30 29 30 30 29 29 30 29 -1390=29 30 29 30 30 30 29 30 29 30 29 30 -1391=29 29 30 29 30 30 29 30 30 29 30 29 -1392=30 29 29 30 29 30 29 30 30 29 30 30 -1393=29 30 29 29 30 29 30 29 30 29 30 30 -1394=30 29 30 29 29 30 29 30 29 30 29 30 -1395=30 29 30 30 29 30 29 29 30 29 29 30 -1396=30 29 30 30 29 30 30 29 29 30 29 29 -1397=30 29 30 30 29 30 30 30 29 29 29 30 -1398=29 30 29 30 30 29 30 30 29 30 29 29 -1399=30 29 30 29 30 29 30 30 29 30 29 30 -1400=30 29 30 29 29 30 29 30 29 30 29 30 -1401=30 30 29 30 29 29 30 29 29 30 29 30 -1402=30 30 30 29 30 29 29 30 29 29 30 29 -1403=30 30 30 29 30 30 29 29 30 29 29 30 -1404=29 30 30 29 30 30 29 30 29 30 29 29 -1405=30 29 30 29 30 30 30 29 30 29 29 30 -1406=30 29 29 30 29 30 30 29 30 29 30 30 -1407=29 30 29 29 30 29 30 29 30 29 30 30 -1408=30 29 30 29 30 29 29 30 29 29 30 30 -1409=30 30 29 30 29 30 29 29 30 29 29 30 -1410=30 30 29 30 30 29 30 29 29 30 29 29 -1411=30 30 29 30 30 29 30 30 29 29 30 29 -1412=30 29 30 29 30 29 30 30 30 29 29 30 -1413=29 30 29 29 30 29 30 30 30 29 30 29 -1414=30 29 30 29 29 30 29 30 30 29 30 30 -1415=29 30 29 30 29 29 30 29 30 29 30 30 -1416=30 29 30 29 30 29 29 30 29 30 29 30 -1417=30 29 30 30 29 29 30 29 30 29 30 29 -1418=30 29 30 30 29 30 29 30 29 30 29 30 -1419=29 30 29 30 29 30 29 30 30 30 29 29 -1420=29 30 29 29 30 29 30 30 30 30 29 30 -1421=29 29 30 29 29 29 30 30 30 30 29 30 -1422=30 29 29 30 29 29 29 30 30 30 29 30 -1423=30 29 30 29 30 29 29 30 29 30 29 30 -1424=30 29 30 30 29 30 29 29 30 29 30 29 -1425=30 29 30 30 29 30 29 30 30 29 30 29 -1426=29 30 29 30 29 30 30 29 30 30 29 30 -1427=29 29 30 29 30 29 30 30 29 30 30 29 -1428=30 29 29 30 29 29 30 30 30 29 30 30 -1429=29 30 29 29 30 29 29 30 30 29 30 30 -1430=29 30 30 29 29 30 29 30 29 30 29 30 -1431=29 30 30 29 30 29 30 29 30 29 29 30 -1432=29 30 30 30 29 30 29 30 29 30 29 29 -1433=30 29 30 30 29 30 30 29 30 29 30 29 -1434=29 30 29 30 29 30 30 29 30 30 29 29 -1435=30 29 30 29 30 29 30 29 30 30 29 30 -1436=29 30 29 30 29 30 29 30 29 30 29 30 -1437=30 29 30 30 29 29 30 29 30 29 29 30 -1438=30 29 30 30 30 29 29 30 29 29 30 29 -1439=30 29 30 30 30 29 30 29 30 29 29 30 -1440=29 30 29 30 30 30 29 30 29 30 29 29 -1441=30 29 30 29 30 30 29 30 30 29 30 29 -1442=29 30 29 30 29 30 29 30 30 29 30 29 -1443=30 29 30 29 30 29 30 29 30 29 30 30 -1444=29 30 29 30 30 29 29 30 29 30 29 30 -1445=29 30 30 30 29 30 29 29 30 29 29 30 -1446=29 30 30 30 29 30 30 29 29 30 29 29 -1447=30 29 30 30 30 29 30 29 30 29 30 29 -1448=29 30 29 30 30 29 30 30 29 30 29 30 -1449=29 29 30 29 30 29 30 30 29 30 30 29 -1450=30 29 30 29 29 30 29 30 29 30 30 29 -1451=30 30 30 29 29 30 29 29 30 30 29 30 -1452=30 29 30 30 29 29 30 29 29 30 29 30 -1453=30 29 30 30 29 30 29 30 29 29 30 29 -1454=30 29 30 30 29 30 30 29 30 29 30 29 -1455=29 30 29 30 30 29 30 29 30 30 29 30 -1456=29 29 30 29 30 29 30 29 30 30 30 29 -1457=30 29 29 30 29 29 30 29 30 30 30 30 -1458=29 30 29 29 30 29 29 30 29 30 30 30 -1459=29 30 30 29 29 30 29 29 30 29 30 30 -1460=29 30 30 29 30 29 30 29 29 30 29 30 -1461=29 30 30 29 30 29 30 29 30 30 29 29 -1462=30 29 30 29 30 30 29 30 29 30 30 29 -1463=29 30 29 30 29 30 29 30 30 30 29 30 -1464=29 30 29 29 30 29 29 30 30 30 29 30 -1465=30 29 30 29 29 30 29 29 30 30 29 30 -1466=30 30 29 30 29 29 29 30 29 30 30 29 -1467=30 30 29 30 30 29 29 30 29 30 29 30 -1468=29 30 29 30 30 29 30 29 30 29 30 29 -1469=29 30 29 30 30 29 30 30 29 30 29 30 -1470=29 29 30 29 30 30 29 30 30 29 30 29 -1471=30 29 29 30 29 30 29 30 30 29 30 30 -1472=29 30 29 29 30 29 30 29 30 30 29 30 -1473=29 30 29 30 30 29 29 30 29 30 29 30 -1474=29 30 30 29 30 30 29 29 30 29 30 29 -1475=29 30 30 29 30 30 30 29 29 30 29 29 -1476=30 29 30 29 30 30 30 29 30 29 30 29 -1477=29 30 29 29 30 30 30 30 29 30 29 30 -1478=29 29 30 29 30 29 30 30 29 30 30 29 -1479=30 29 29 30 29 30 29 30 29 30 30 29 -1480=30 29 30 29 30 29 30 29 30 29 30 29 -1481=30 29 30 30 29 30 29 30 29 30 29 29 -1482=30 29 30 30 30 30 29 30 29 29 30 29 -1483=29 30 29 30 30 30 29 30 30 29 29 30 -1484=29 29 30 29 30 30 30 29 30 29 30 29 -1485=30 29 29 30 29 30 30 29 30 30 29 30 -1486=29 30 29 29 30 29 30 29 30 30 29 30 -1487=30 29 30 29 30 29 29 30 29 30 29 30 -1488=30 29 30 30 29 30 29 29 30 29 30 29 -1489=30 29 30 30 30 29 30 29 29 30 29 30 -1490=29 30 29 30 30 29 30 30 29 29 30 29 -1491=30 29 29 30 30 29 30 30 29 30 29 30 -1492=29 30 29 29 30 30 29 30 29 30 30 29 -1493=30 29 30 29 30 29 29 30 29 30 30 30 -1494=29 30 29 30 29 30 29 29 29 30 30 30 -1495=29 30 30 29 30 29 29 30 29 29 30 30 -1496=29 30 30 30 29 30 29 29 30 29 29 30 -1497=30 29 30 30 29 30 29 30 29 30 29 30 -1498=29 30 29 30 29 30 30 29 30 29 30 29 -1499=30 29 30 29 29 30 30 29 30 29 30 30 -1500=29 30 29 30 29 29 30 29 30 29 30 30 -1501=30 29 30 29 30 29 29 29 30 29 30 30 -1502=30 30 29 30 29 30 29 29 29 30 30 29 -1503=30 30 29 30 30 29 30 29 29 29 30 30 -1504=29 30 29 30 30 30 29 29 30 29 30 29 -1505=30 29 30 29 30 30 29 30 29 30 30 29 -1506=29 30 29 29 30 30 29 30 30 29 30 30 -1507=29 29 30 29 29 30 30 29 30 29 30 30 -1508=30 29 29 30 29 30 29 29 30 29 30 30 -1509=30 29 30 29 30 29 30 29 29 30 29 30 -1510=30 29 30 30 29 30 29 30 29 29 30 29 -1511=30 29 30 30 29 30 30 29 30 29 29 30 -1512=29 30 29 30 29 30 30 30 29 30 29 30 -1513=29 29 29 30 29 30 30 30 29 30 30 29 -1514=30 29 29 29 30 29 30 30 29 30 30 30 -1515=29 29 30 29 29 30 29 30 30 29 30 30 -1516=29 30 29 30 29 29 30 29 30 29 30 30 -1517=29 30 29 30 29 30 30 29 29 30 29 30 -1518=29 30 29 30 30 29 30 30 29 30 29 29 -1519=30 29 29 30 30 30 29 30 30 29 30 29 -1520=29 30 29 29 30 30 30 29 30 30 29 30 -1521=29 29 29 30 29 30 30 29 30 30 29 30 -1522=30 29 29 29 30 29 30 30 29 30 30 29 -1523=30 29 30 29 30 29 30 29 29 30 30 29 -1524=30 30 29 30 29 30 29 30 29 29 30 29 -1525=30 30 29 30 30 29 30 29 30 29 29 30 -1526=29 30 29 30 30 30 29 30 29 30 29 29 -1527=30 29 30 29 30 30 29 30 30 29 30 29 -1528=30 29 29 30 29 30 29 30 30 29 30 30 -1529=29 30 29 29 30 29 30 29 30 29 30 30 -1530=29 30 30 29 29 30 29 30 29 29 30 30 -1531=29 30 30 30 29 29 30 29 30 29 29 30 -1532=29 30 30 30 29 30 30 29 29 29 30 29 -1533=30 29 30 30 30 29 30 29 30 29 29 30 -1534=29 30 29 30 30 29 30 30 29 29 30 29 -1535=30 29 30 29 30 29 30 30 29 30 29 30 -1536=29 30 29 30 29 30 29 30 29 30 29 30 -1537=30 29 30 30 29 29 30 29 29 30 29 30 -1538=30 30 29 30 30 29 29 30 29 29 30 29 -1539=30 30 30 29 30 30 29 29 30 29 29 30 -1540=29 30 30 29 30 30 29 30 29 29 30 29 -1541=30 29 30 29 30 30 30 29 30 29 29 30 -1542=29 30 29 30 29 30 30 29 30 29 30 30 -1543=29 30 29 29 30 29 30 29 30 29 30 30 -1544=30 29 30 29 29 30 29 30 29 30 29 30 -1545=30 30 29 30 29 29 30 29 30 29 29 30 -1546=30 30 29 30 29 30 29 30 29 30 29 29 -1547=30 30 29 30 30 29 30 29 30 29 30 29 -1548=30 29 29 30 30 29 30 30 29 30 29 30 -1549=29 30 29 29 30 29 30 30 30 29 30 29 -1550=30 29 30 29 29 29 30 30 30 29 30 30 -1551=29 30 29 29 30 29 29 30 30 29 30 30 -1552=30 29 30 29 29 30 29 29 30 30 29 30 -1553=30 29 30 29 30 29 30 29 30 29 30 29 -1554=30 29 30 29 30 30 29 30 29 30 29 30 -1555=29 29 30 29 30 30 29 30 30 29 30 29 -1556=30 29 29 30 29 30 29 30 30 30 29 30 -1557=29 30 29 29 29 30 29 30 30 30 30 29 -1558=30 29 30 29 29 29 30 29 30 30 30 29 -1559=30 30 29 29 30 29 29 30 30 29 30 29 -1560=30 30 29 30 29 30 29 30 29 30 29 30 -1561=29 30 30 29 30 29 30 30 29 29 30 29 -1562=29 30 30 29 30 29 30 30 30 29 29 30 -1563=29 30 29 29 30 29 30 30 30 29 30 29 -1564=30 29 30 29 29 30 29 30 30 30 29 30 -1565=29 30 29 30 29 29 30 29 30 30 29 30 -1566=30 29 30 29 30 29 29 30 29 30 29 30 -1567=30 29 30 30 29 30 29 30 29 29 30 29 -1568=30 29 30 30 30 29 30 29 30 29 29 29 -1569=30 29 30 30 30 29 30 30 29 30 29 29 -1570=29 30 29 30 30 29 30 30 30 29 29 30 -1571=29 29 30 29 30 30 29 30 30 29 30 29 -1572=30 29 29 30 29 30 29 30 30 29 30 29 -1573=30 29 30 30 29 30 29 29 30 29 30 29 -1574=30 30 29 30 30 29 30 29 29 30 29 29 -1575=30 30 30 29 30 30 29 30 29 29 29 30 -1576=29 30 30 29 30 30 30 29 30 29 29 29 -1577=30 29 30 30 29 30 30 29 30 29 30 29 -1578=29 30 29 30 29 30 30 29 30 30 29 30 -1579=29 30 29 30 29 29 30 30 29 30 29 30 -1580=29 30 30 29 30 29 29 30 29 30 29 30 -1581=30 30 29 30 29 30 29 29 30 29 30 29 -1582=30 30 29 30 30 29 30 29 30 29 29 29 -1583=30 30 29 30 30 30 29 30 29 30 29 29 -1584=29 30 30 29 30 30 29 30 30 29 30 29 -1585=29 30 29 30 29 30 29 30 30 29 30 30 -1586=29 29 30 29 30 29 29 30 30 30 29 30 -1587=29 30 30 29 29 29 30 29 30 29 30 30 -1588=30 29 30 30 29 29 29 30 29 30 29 30 -1589=30 29 30 30 29 30 29 29 30 29 30 29 -1590=30 29 30 30 30 29 29 30 29 30 29 30 -1591=29 30 29 30 30 29 30 29 30 29 30 29 -1592=30 29 30 29 30 29 30 29 30 30 30 29 -1593=30 29 29 30 29 29 30 29 30 30 30 29 -1594=30 30 29 29 30 29 29 29 30 30 30 30 -1595=29 30 29 30 29 29 30 29 29 30 30 30 -1596=29 30 30 29 30 29 29 30 29 30 29 30 -1597=29 30 30 29 30 29 30 29 30 29 30 29 -1598=30 29 30 29 30 30 29 30 29 30 30 29 -1599=29 30 29 30 29 30 29 30 30 30 29 30 -1600=29 29 30 29 30 29 29 30 30 30 29 30
--- a/jdk/src/java.base/share/native/libjava/io_util.h Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/share/native/libjava/io_util.h Fri Oct 31 12:01:27 2014 -1000 @@ -28,6 +28,7 @@ extern jfieldID IO_fd_fdID; extern jfieldID IO_handle_fdID; +extern jfieldID IO_append_fdID; #ifdef _ALLBSD_SOURCE #include <fcntl.h>
--- a/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/classes/java/io/FileDescriptor.java Fri Oct 31 12:01:27 2014 -1000 @@ -52,15 +52,21 @@ private boolean closed; /** + * true, if file is opened for appending. + */ + private boolean append; + + /** * Constructs an (invalid) FileDescriptor * object. */ - public /**/ FileDescriptor() { + public FileDescriptor() { fd = -1; } - private /* */ FileDescriptor(int fd) { + private FileDescriptor(int fd) { this.fd = fd; + this.append = getAppend(fd); } /** @@ -149,6 +155,14 @@ return obj.fd; } + public void setAppend(FileDescriptor obj, boolean append) { + obj.append = append; + } + + public boolean getAppend(FileDescriptor obj) { + return obj.append; + } + public void setHandle(FileDescriptor obj, long handle) { throw new UnsupportedOperationException(); } @@ -160,6 +174,11 @@ ); } + /** + * Returns true, if the file was opened for appending. + */ + private static native boolean getAppend(int fd); + /* * Package private methods to track referents. * If multiple streams point to the same FileDescriptor, we cycle
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/FileDispatcherImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -35,10 +35,6 @@ init(); } - FileDispatcherImpl(boolean append) { - /* append is ignored */ - } - FileDispatcherImpl() { }
--- a/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -141,7 +141,7 @@ Throwable exc = null; try { begin(); - int n = accept0(this.fd, newfd, isaa); + int n = accept(this.fd, newfd, isaa); // spurious wakeup, is this possible? if (n == IOStatus.UNAVAILABLE) { @@ -277,7 +277,7 @@ try { begin(); - int n = accept0(this.fd, newfd, isaa); + int n = accept(this.fd, newfd, isaa); if (n == IOStatus.UNAVAILABLE) { // need calling context when there is security manager as @@ -332,6 +332,18 @@ } } + /** + * Accept a connection on a socket. + * + * @implNote Wrap native call to allow instrumentation. + */ + private int accept(FileDescriptor ssfd, FileDescriptor newfd, + InetSocketAddress[] isaa) + throws IOException + { + return accept0(ssfd, newfd, isaa); + } + // -- Native methods -- private static native void initIDs();
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java Fri Oct 31 12:01:27 2014 -1000 @@ -134,7 +134,7 @@ throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode); - return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, flags.append, null); + return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, null); } /** @@ -288,6 +288,7 @@ // create java.io.FileDescriptor FileDescriptor fdObj = new FileDescriptor(); fdAccess.set(fdObj, fd); + fdAccess.setAppend(fdObj, flags.append); return fdObj; } }
--- a/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/native/libjava/FileDescriptor_md.c Fri Oct 31 12:01:27 2014 -1000 @@ -23,6 +23,9 @@ * questions. */ +#include <unistd.h> +#include <fcntl.h> + #include "jvm.h" #include "io_util_md.h" @@ -35,6 +38,9 @@ /* field id for jint 'fd' in java.io.FileDescriptor */ jfieldID IO_fd_fdID; +/* field id for jboolean 'append' in java.io.FileDescriptor */ +jfieldID IO_append_fdID; + /************************************************************** * static methods to store field ID's in initializers */ @@ -42,6 +48,7 @@ JNIEXPORT void JNICALL Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) { IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I"); + IO_append_fdID = (*env)->GetFieldID(env, fdClass, "append", "Z"); } /************************************************************** @@ -55,3 +62,9 @@ JNU_ThrowByName(env, "java/io/SyncFailedException", "sync failed"); } } + +JNIEXPORT jboolean JNICALL +Java_java_io_FileDescriptor_getAppend(JNIEnv *env, jclass fdClass, jint fd) { + int flags = fcntl(fd, F_GETFL); + return ((flags & O_APPEND) == 0) ? JNI_FALSE : JNI_TRUE; +}
--- a/jdk/src/java.base/unix/native/libjava/io_util_md.c Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/unix/native/libjava/io_util_md.c Fri Oct 31 12:01:27 2014 -1000 @@ -107,7 +107,15 @@ #endif fd = handleOpen(ps, flags, 0666); if (fd != -1) { + jobject fdobj; + jboolean append; SET_FD(this, fd, fid); + + fdobj = (*env)->GetObjectField(env, this, fid); + if (fdobj != NULL) { + append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; + (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); + } } else { throwFileNotFoundException(env, path); }
--- a/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/windows/classes/java/io/FileDescriptor.java Fri Oct 31 12:01:27 2014 -1000 @@ -51,6 +51,11 @@ private boolean closed; /** + * true, if file is opened for appending. + */ + private boolean append; + + /** * Constructs an (invalid) FileDescriptor * object. */ @@ -75,6 +80,14 @@ return obj.fd; } + public void setAppend(FileDescriptor obj, boolean append) { + obj.append = append; + } + + public boolean getAppend(FileDescriptor obj) { + return obj.append; + } + public void setHandle(FileDescriptor obj, long handle) { obj.handle = handle; }
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Fri Oct 31 12:01:27 2014 -1000 @@ -31,22 +31,14 @@ class FileDispatcherImpl extends FileDispatcher { + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + static { IOUtil.load(); } - /** - * Indicates if the dispatcher should first advance the file position - * to the end of file when writing. - */ - private final boolean append; - - FileDispatcherImpl(boolean append) { - this.append = append; - } - FileDispatcherImpl() { - this(false); } @Override @@ -71,7 +63,7 @@ } int write(FileDescriptor fd, long address, int len) throws IOException { - return write0(fd, address, len, append); + return write0(fd, address, len, fdAccess.getAppend(fd)); } int pwrite(FileDescriptor fd, long address, int len, long position) @@ -81,7 +73,7 @@ } long writev(FileDescriptor fd, long address, int len) throws IOException { - return writev0(fd, address, len, append); + return writev0(fd, address, len, fdAccess.getAppend(fd)); } int force(FileDescriptor fd, boolean metaData) throws IOException { @@ -112,8 +104,6 @@ FileDescriptor duplicateForMapping(FileDescriptor fd) throws IOException { // on Windows we need to keep a handle to the file - JavaIOFileDescriptorAccess fdAccess = - SharedSecrets.getJavaIOFileDescriptorAccess(); FileDescriptor result = new FileDescriptor(); long handle = duplicateHandle(fdAccess.getHandle(fd)); fdAccess.setHandle(result, handle);
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java Fri Oct 31 12:01:27 2014 -1000 @@ -160,7 +160,7 @@ throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor); - return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, flags.append, null); + return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, null); } /** @@ -339,6 +339,7 @@ // create FileDescriptor and return FileDescriptor fdObj = new FileDescriptor(); fdAccess.setHandle(fdObj, handle); + fdAccess.setAppend(fdObj, flags.append); return fdObj; } }
--- a/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/windows/native/libjava/FileDescriptor_md.c Fri Oct 31 12:01:27 2014 -1000 @@ -42,6 +42,9 @@ /* field id for jlong 'handle' in java.io.FileDescriptor */ jfieldID IO_handle_fdID; +/* field id for jboolean 'append' in java.io.FileDescriptor */ +jfieldID IO_append_fdID; + /************************************************************** * static methods to store field IDs in initializers */ @@ -50,6 +53,7 @@ Java_java_io_FileDescriptor_initIDs(JNIEnv *env, jclass fdClass) { CHECK_NULL(IO_fd_fdID = (*env)->GetFieldID(env, fdClass, "fd", "I")); CHECK_NULL(IO_handle_fdID = (*env)->GetFieldID(env, fdClass, "handle", "J")); + CHECK_NULL(IO_append_fdID = (*env)->GetFieldID(env, fdClass, "append", "Z")); } JNIEXPORT jlong JNICALL
--- a/jdk/src/java.base/windows/native/libjava/io_util_md.c Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.base/windows/native/libjava/io_util_md.c Fri Oct 31 12:01:27 2014 -1000 @@ -275,7 +275,15 @@ { FD h = winFileHandleOpen(env, path, flags); if (h >= 0) { + jobject fdobj; + jboolean append; SET_FD(this, h, fid); + + fdobj = (*env)->GetObjectField(env, this, fid); + if (fdobj != NULL) { + append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; + (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); + } } }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaIcon.java Fri Oct 31 12:01:27 2014 -1000 @@ -62,7 +62,7 @@ if (w <= 0 || h <= 0) return null; // This could be any kind of icon, so we need to make a buffer for it, draw it and then pass the new image off to appkit. - final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); i.paintIcon(null, g, 0, 0); g.dispose();
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java Fri Oct 31 12:01:27 2014 -1000 @@ -129,7 +129,7 @@ }; final BufferedImage image = new BufferedImage(scaledAlertIconSize, - scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB); + scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = image.getGraphics(); g.drawImage(background, 0, 0, scaledAlertIconSize, scaledAlertIconSize, null);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java Fri Oct 31 12:01:27 2014 -1000 @@ -67,11 +67,12 @@ } static BufferedImage getRadioButtonSizerImage() { - final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB); + final BufferedImage img = new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB_PRE); Graphics g = img.getGraphics(); g.setColor(Color.pink); g.fillRect(0, 0, 20, 20); + g.dispose(); return img; }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Oct 31 12:01:27 2014 -1000 @@ -676,6 +676,13 @@ @Override // PlatformWindow public void toFront() { final long nsWindowPtr = getNSWindowPtr(); + LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit(); + Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); + if( w != null + && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME + && !lwcToolkit.isApplicationActive()) { + lwcToolkit.activateApplicationIgnoringOtherApps(); + } updateFocusabilityForAutoRequestFocus(false); nativePushNSWindowToFront(nsWindowPtr); updateFocusabilityForAutoRequestFocus(true);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Oct 31 12:01:27 2014 -1000 @@ -811,6 +811,11 @@ */ public static native boolean isEmbedded(); + /* + * Activates application ignoring other apps. + */ + public native void activateApplicationIgnoringOtherApps(); + /************************ * Native methods section ************************/
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Fri Oct 31 12:01:27 2014 -1000 @@ -606,6 +606,23 @@ return active; } +/* + * Class: sun_lwawt_macosx_LWCToolkit + * Method: activateApplicationIgnoringOtherApps + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_activateApplicationIgnoringOtherApps +(JNIEnv *env, jclass clazz) +{ + JNF_COCOA_ENTER(env); + [ThreadUtilities performOnMainThreadWaiting:NO block:^(){ + if(![NSApp isActive]){ + [NSApp activateIgnoringOtherApps:YES]; + } + }]; + JNF_COCOA_EXIT(env); +} + /* * Class: sun_awt_SunToolkit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.PrintServiceLookup Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,2 @@ +# Provider for Java Print Service +sun.print.PrintServiceLookupProvider
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.desktop/share/classes/META-INF/services/javax.print.StreamPrintServiceFactory Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,2 @@ +# Provider for Java 2D Stream print services. +sun.print.PSStreamPrinterFactory
--- a/jdk/src/java.desktop/share/classes/java/awt/Container.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java Fri Oct 31 12:01:27 2014 -1000 @@ -3696,7 +3696,7 @@ private void writeObject(ObjectOutputStream s) throws IOException { ObjectOutputStream.PutField f = s.putFields(); f.put("ncomponents", component.size()); - f.put("component", getComponentsSync()); + f.put("component", component.toArray(EMPTY_ARRAY)); f.put("layoutMgr", layoutMgr); f.put("dispatcher", dispatcher); f.put("maxSize", maxSize);
--- a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java Fri Oct 31 12:01:27 2014 -1000 @@ -48,6 +48,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -1857,7 +1858,13 @@ * returns null. */ private static InputStream getStandardProfileInputStream(String fileName) { - return PCMM.class.getResourceAsStream("profiles/" + fileName); + return AccessController.doPrivileged( + new PrivilegedAction<InputStream>() { + public InputStream run () { + return + PCMM.class.getResourceAsStream("profiles/" + fileName); + } + }, null, new FilePermission("<<ALL FILES>>", "read")); } /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/BorderFactory.java Fri Oct 31 12:01:27 2014 -1000 @@ -35,7 +35,7 @@ * possible, this factory will hand out references to shared * <code>Border</code> instances. * For further information and examples see - * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How to Use Borders</a>, * a section in <em>The Java Tutorial</em>. *
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Fri Oct 31 12:01:27 2014 -1000 @@ -126,7 +126,7 @@ * that includes double buffering and support for borders. * For more information see <a * href="http://www.oracle.com/technetwork/java/painting-140037.html#swing">Painting</a> and - * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How * to Use Borders</a>, * both of which are sections in <em>The Java Tutorial</em>. * </ul>
--- a/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JInternalFrame.java Fri Oct 31 12:01:27 2014 -1000 @@ -1141,14 +1141,15 @@ /** * Sets an image to be displayed in the titlebar of this internal frame (usually * in the top-left corner). + * Some look and feels might not support displaying an icon in the titlebar. + * * This image is not the <code>desktopIcon</code> object, which * is the image displayed in the <code>JDesktop</code> when * this internal frame is iconified. * * Passing <code>null</code> to this function is valid, - * but the look and feel - * can choose the - * appropriate behavior for that situation, such as displaying no icon + * but the look and feel can choose the appropriate behavior + * for that situation, such as displaying no icon * or a default icon for the look and feel. * * @param icon the <code>Icon</code> to display in the title bar
--- a/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Fri Oct 31 12:01:27 2014 -1000 @@ -325,24 +325,38 @@ } /** - * A non-{@code null} border, or non-zero insets, isn't supported, to prevent the geometry - * of this component from becoming complex enough to inhibit - * subclassing of {@code LayerUI} class. To create a {@code JLayer} with a border, - * add it to a {@code JPanel} that has a border. - * <p>Note: If {@code border} is non-{@code null}, this - * method will throw an exception as borders are not supported on - * a {@code JLayer}. + * Delegates its functionality to the {@code getView().setBorder(Border)} method, + * if the view component is an instance of {@code javax.swing.JComponent}, + * otherwise this method is a no-op. * - * @param border the {@code Border} to set - * @exception IllegalArgumentException this method is not supported + * @param border the border to be rendered for the {@code view} component + * @see #getView() + * @see javax.swing.JComponent#setBorder(Border) */ public void setBorder(Border border) { - if (border != null) { - throw new IllegalArgumentException("JLayer.setBorder() not supported"); + if (view instanceof JComponent) { + ((JComponent)view).setBorder(border); } } /** + * Delegates its functionality to the {@code getView().getBorder()} method, + * if the view component is an instance of {@code javax.swing.JComponent}, + * otherwise returns {@code null}. + * + * @return the border object for the {@code view} component + * @see #getView() + * @see #setBorder + * @see javax.swing.JComponent#getBorder() + */ + public Border getBorder() { + if (view instanceof JComponent) { + return ((JComponent) view).getBorder(); + } + return null; + } + + /** * This method is not supported by {@code JLayer} * and always throws {@code UnsupportedOperationException} *
--- a/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/border/Border.java Fri Oct 31 12:01:27 2014 -1000 @@ -33,7 +33,7 @@ * Interface describing an object capable of rendering a border * around the edges of a swing component. * For examples of using borders see - * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.htmll">How to Use Borders</a>, + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html">How to Use Borders</a>, * a section in <em>The Java Tutorial.</em> * <p> * In the Swing component set, borders supercede Insets as the
--- a/jdk/src/java.desktop/share/classes/javax/swing/border/package.html Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/border/package.html Fri Oct 31 12:01:27 2014 -1000 @@ -40,10 +40,10 @@ Most of the Swing API is <em>not</em> thread safe. For details, see <a -href="http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html" -target="_top">Threads and Swing</a>, +href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html" +target="_top">Concurrency in Swing</a>, a section in -<em><a href="http://java.sun.com/docs/books/tutorial/" +<em><a href="http://docs.oracle.com/javase/tutorial/" target="_top">The Java Tutorial</a></em>. @@ -51,7 +51,7 @@ For overviews, tutorials, examples, guides, and tool documentation, please see: <ul> - <li><a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html" + <li><a href="http://docs.oracle.com/javase/tutorial/uiswing/components/border.html" target="_top">How to Use Borders</a>, a section in <em>The Java Tutorial</em> </ul>
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicRadioButtonUI.java Fri Oct 31 12:01:27 2014 -1000 @@ -33,7 +33,8 @@ import javax.swing.text.View; import sun.swing.SwingUtilities2; import sun.awt.AppContext; - +import java.util.Enumeration; +import java.util.HashSet; /** * RadioButtonUI implementation for BasicRadioButtonUI @@ -53,6 +54,8 @@ private final static String propertyPrefix = "RadioButton" + "."; + private KeyListener keyListener = null; + // ******************************** // Create PLAF // ******************************** @@ -74,6 +77,7 @@ return radioButtonUI; } + @Override protected String getPropertyPrefix() { return propertyPrefix; } @@ -81,7 +85,8 @@ // ******************************** // Install PLAF // ******************************** - protected void installDefaults(AbstractButton b){ + @Override + protected void installDefaults(AbstractButton b) { super.installDefaults(b); if(!defaults_initialized) { icon = UIManager.getIcon(getPropertyPrefix() + "icon"); @@ -92,7 +97,8 @@ // ******************************** // Uninstall PLAF // ******************************** - protected void uninstallDefaults(AbstractButton b){ + @Override + protected void uninstallDefaults(AbstractButton b) { super.uninstallDefaults(b); defaults_initialized = false; } @@ -106,6 +112,65 @@ return icon; } + // ******************************** + // Install Listeners + // ******************************** + @Override + protected void installListeners(AbstractButton button) { + super.installListeners(button); + + // Only for JRadioButton + if (!(button instanceof JRadioButton)) + return; + + keyListener = createKeyListener(); + button.addKeyListener(keyListener); + + // Need to get traversal key event + button.setFocusTraversalKeysEnabled(false); + + // Map actions to the arrow keys + button.getActionMap().put("Previous", new SelectPreviousBtn()); + button.getActionMap().put("Next", new SelectNextBtn()); + + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("UP"), "Previous"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("DOWN"), "Next"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("LEFT"), "Previous"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT). + put(KeyStroke.getKeyStroke("RIGHT"), "Next"); + } + + // ******************************** + // UnInstall Listeners + // ******************************** + @Override + protected void uninstallListeners(AbstractButton button) { + super.uninstallListeners(button); + + // Only for JRadioButton + if (!(button instanceof JRadioButton)) + return; + + // Unmap actions from the arrow keys + button.getActionMap().remove("Previous"); + button.getActionMap().remove("Next"); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("UP")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("DOWN")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("LEFT")); + button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .remove(KeyStroke.getKeyStroke("RIGHT")); + + if (keyListener != null) { + button.removeKeyListener(keyListener); + keyListener = null; + } + } /* These Dimensions/Rectangles are allocated once for all * RadioButtonUI.paint() calls. Re-using rectangles @@ -121,6 +186,7 @@ /** * paint the radio button */ + @Override public synchronized void paint(Graphics g, JComponent c) { AbstractButton b = (AbstractButton) c; ButtonModel model = b.getModel(); @@ -217,7 +283,7 @@ * @param textRect bounds * @param size the size of radio button */ - protected void paintFocus(Graphics g, Rectangle textRect, Dimension size){ + protected void paintFocus(Graphics g, Rectangle textRect, Dimension size) { } @@ -235,6 +301,7 @@ /** * The preferred size of the radio button */ + @Override public Dimension getPreferredSize(JComponent c) { if(c.getComponentCount() > 0) { return null; @@ -280,4 +347,262 @@ height += prefInsets.top + prefInsets.bottom; return new Dimension(width, height); } + + /////////////////////////// Private functions //////////////////////// + /** + * Creates the key listener to handle tab navigation in JRadioButton Group. + */ + private KeyListener createKeyListener() { + if (keyListener == null) { + keyListener = new KeyHandler(); + } + return keyListener; + } + + + private boolean isValidRadioButtonObj(Object obj) { + return ((obj instanceof JRadioButton) && + ((JRadioButton) obj).isVisible() && + ((JRadioButton) obj).isEnabled()); + } + + /** + * Select radio button based on "Previous" or "Next" operation + * + * @param event, the event object. + * @param next, indicate if it's next one + */ + private void selectRadioButton(ActionEvent event, boolean next) { + // Get the source of the event. + Object eventSrc = event.getSource(); + + // Check whether the source is JRadioButton, it so, whether it is visible + if (!isValidRadioButtonObj(eventSrc)) + return; + + ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc); + btnGroupInfo.selectNewButton(next); + } + + /////////////////////////// Inner Classes //////////////////////// + @SuppressWarnings("serial") + private class SelectPreviousBtn extends AbstractAction { + public SelectPreviousBtn() { + super("Previous"); + } + + public void actionPerformed(ActionEvent e) { + BasicRadioButtonUI.this.selectRadioButton(e, false); + } + } + + @SuppressWarnings("serial") + private class SelectNextBtn extends AbstractAction{ + public SelectNextBtn() { + super("Next"); + } + + public void actionPerformed(ActionEvent e) { + BasicRadioButtonUI.this.selectRadioButton(e, true); + } + } + + /** + * ButtonGroupInfo, used to get related info in button group + * for given radio button + */ + private class ButtonGroupInfo { + + JRadioButton activeBtn = null; + + JRadioButton firstBtn = null; + JRadioButton lastBtn = null; + + JRadioButton previousBtn = null; + JRadioButton nextBtn = null; + + HashSet<JRadioButton> btnsInGroup = null; + + boolean srcFound = false; + public ButtonGroupInfo(JRadioButton btn) { + activeBtn = btn; + btnsInGroup = new HashSet<JRadioButton>(); + } + + // Check if given object is in the button group + boolean containsInGroup(Object obj){ + return btnsInGroup.contains(obj); + } + + // Check if the next object to gain focus belongs + // to the button group or not + Component getFocusTransferBaseComponent(boolean next){ + Component focusBaseComp = activeBtn; + Window container = SwingUtilities.getWindowAncestor(activeBtn); + if (container != null) { + FocusTraversalPolicy policy = container.getFocusTraversalPolicy(); + Component comp = next ? policy.getComponentAfter(container, activeBtn) + : policy.getComponentBefore(container, activeBtn); + + // If next component in the button group, use last/first button as base focus + // otherwise, use the activeBtn as the base focus + if (containsInGroup(comp)) { + focusBaseComp = next ? lastBtn : firstBtn; + } + } + + return focusBaseComp; + } + + boolean getButtonGroupInfo() { + if (activeBtn == null) + return false; + + btnsInGroup.clear(); + + // Get the button model from the source. + ButtonModel model = activeBtn.getModel(); + if (!(model instanceof DefaultButtonModel)) + return false; + + // If the button model is DefaultButtonModel, and use it, otherwise return. + DefaultButtonModel bm = (DefaultButtonModel) model; + + // get the ButtonGroup of the button from the button model + ButtonGroup group = bm.getGroup(); + if (group == null) + return false; + + // Get all the buttons in the group + Enumeration<AbstractButton> e = group.getElements(); + if (e == null) + return false; + + while (e.hasMoreElements()) { + AbstractButton curElement = e.nextElement(); + if (!isValidRadioButtonObj(curElement)) + continue; + + btnsInGroup.add((JRadioButton) curElement); + + // If firstBtn is not set yet, curElement is that first button + if (null == firstBtn) + firstBtn = (JRadioButton) curElement; + + if (activeBtn == curElement) + srcFound = true; + else if (!srcFound) { + // The source has not been yet found and the current element + // is the last previousBtn + previousBtn = (JRadioButton) curElement; + } else if (nextBtn == null) { + // The source has been found and the current element + // is the next valid button of the list + nextBtn = (JRadioButton) curElement; + } + + // Set new last "valid" JRadioButton of the list + lastBtn = (JRadioButton) curElement; + } + + return true; + } + + /** + * Find the new radio button that focus needs to be + * moved to in the group, select the button + * + * @param next, indicate if it's arrow up/left or down/right + */ + void selectNewButton(boolean next) { + if (!getButtonGroupInfo()) + return; + + if (srcFound) { + JRadioButton newSelectedBtn = null; + if (next) { + // Select Next button. Cycle to the first button if the source + // button is the last of the group. + newSelectedBtn = (null == nextBtn) ? firstBtn : nextBtn; + } else { + // Select previous button. Cycle to the last button if the source + // button is the first button of the group. + newSelectedBtn = (null == previousBtn) ? lastBtn : previousBtn; + } + if (newSelectedBtn != null && + (newSelectedBtn != activeBtn)) { + newSelectedBtn.requestFocusInWindow(); + newSelectedBtn.setSelected(true); + } + } + } + + /** + * Find the button group the passed in JRadioButton belongs to, and + * move focus to next component of the last button in the group + * or previous component of first button + * + * @param next, indicate if jump to next component or previous + */ + void jumpToNextComponent(boolean next) { + if (!getButtonGroupInfo()){ + // In case the button does not belong to any group, it needs + // to be treated as a component + if (activeBtn != null){ + lastBtn = activeBtn; + firstBtn = activeBtn; + } + else + return; + } + + // Update the component we will use as base to transfer + // focus from + JComponent compTransferFocusFrom = activeBtn; + + // If next component in the parent window is not in + // the button group, current active button will be + // base, otherwise, the base will be first or last + // button in the button group + Component focusBase = getFocusTransferBaseComponent(next); + if (focusBase != null){ + if (next) { + KeyboardFocusManager. + getCurrentKeyboardFocusManager().focusNextComponent(focusBase); + } else { + KeyboardFocusManager. + getCurrentKeyboardFocusManager().focusPreviousComponent(focusBase); + } + } + } + } + + /** + * Radiobutton KeyListener + */ + private class KeyHandler implements KeyListener { + + // This listener checks if the key event is a KeyEvent.VK_TAB + // or shift + KeyEvent.VK_TAB event on a radio button, consume the event + // if so and move the focus to next/previous component + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_TAB) { + // Get the source of the event. + Object eventSrc = e.getSource(); + + // Check whether the source is a visible and enabled JRadioButton + if (isValidRadioButtonObj(eventSrc)) { + e.consume(); + ButtonGroupInfo btnGroupInfo = new ButtonGroupInfo((JRadioButton)eventSrc); + btnGroupInfo.jumpToNextComponent(!e.isShiftDown()); + } + } + } + + public void keyReleased(KeyEvent e) { + } + + public void keyTyped(KeyEvent e) { + } + } }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java Fri Oct 31 12:01:27 2014 -1000 @@ -3249,6 +3249,7 @@ } } tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight)); + tabScroller.tabPanel.invalidate(); } } @@ -3622,6 +3623,7 @@ setFocusIndex(tabPane.getSelectedIndex(), false); if (scrollableTabLayoutEnabled()) { + ensureCurrentLayout(); int index = tabPane.getSelectedIndex(); if (index < rects.length && index != -1) { tabScroller.tabPanel.scrollRectToVisible(
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java Fri Oct 31 12:01:27 2014 -1000 @@ -1400,8 +1400,13 @@ Element parent = elem.getParentElement(); if (parent != null) { + // If we are going to insert the string into the body + // section, it is necessary to set the corrsponding flag. + if (HTML.Tag.BODY.name.equals(parent.getName())) { + insertInBody = true; + } int offset = elem.getEndOffset(); - if (offset > getLength()) { + if (offset > (getLength() + 1)) { offset--; } else if (elem.isLeaf() && getText(offset - 1, 1). @@ -1409,6 +1414,10 @@ offset--; } insertHTML(parent, offset, htmlText, false); + // Cleanup the flag, if any. + if (insertInBody) { + insertInBody = false; + } } } } @@ -1847,6 +1856,11 @@ private static char[] NEWLINE; /** + * Indicates that direct insertion to body section takes place. + */ + private boolean insertInBody = false; + + /** * I18N property key. * * @see AbstractDocument#I18NProperty @@ -2610,7 +2624,9 @@ // Assume content should be added. foundInsertTag(false); foundInsertTag = true; - inParagraph = impliedP = true; + // If content is added directly to the body, it should + // be wrapped by p-implied. + inParagraph = impliedP = !insertInBody; } if (data.length >= 1) { addContent(data, 0, data.length);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLBlitLoops.java Fri Oct 31 12:01:27 2014 -1000 @@ -47,7 +47,7 @@ import static sun.java2d.pipe.BufferedOpCodes.*; import java.lang.annotation.Native; -class OGLBlitLoops { +final class OGLBlitLoops { static void register() { Blit blitIntArgbPreToSurface = @@ -56,7 +56,9 @@ Blit blitIntArgbPreToTexture = new OGLSwToTextureBlit(SurfaceType.IntArgbPre, OGLSurfaceData.PF_INT_ARGB_PRE); - + TransformBlit transformBlitIntArgbPreToSurface = + new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, + OGLSurfaceData.PF_INT_ARGB_PRE); GraphicsPrimitive[] primitives = { // surface->surface ops new OGLSurfaceToSurfaceBlit(), @@ -100,7 +102,7 @@ CompositeType.AnyAlpha, blitIntArgbPreToSurface), - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface), + new OGLAnyCompositeBlit(), new OGLSwToSurfaceScale(SurfaceType.IntRgb, OGLSurfaceData.PF_INT_RGB), @@ -145,8 +147,9 @@ OGLSurfaceData.PF_BYTE_GRAY), new OGLSwToSurfaceTransform(SurfaceType.UshortGray, OGLSurfaceData.PF_USHORT_GRAY), - new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, - OGLSurfaceData.PF_INT_ARGB_PRE), + transformBlitIntArgbPreToSurface, + + new OGLGeneralTransformedBlit(transformBlitIntArgbPreToSurface), // texture->surface ops new OGLTextureToSurfaceBlit(), @@ -178,9 +181,6 @@ new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, CompositeType.SrcNoEa, blitIntArgbPreToTexture), - - new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture), - }; GraphicsPrimitiveMgr.register(primitives); } @@ -781,11 +781,11 @@ * This general Blit implementation converts any source surface to an * intermediate IntArgbPre surface, and then uses the more specific * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate - * (premultiplied) surface down to OpenGL. + * (premultiplied) surface down to OpenGL using simple blit. */ class OGLGeneralBlit extends Blit { - private Blit performop; + private final Blit performop; private WeakReference<SurfaceData> srcTmp; OGLGeneralBlit(SurfaceType dstType, @@ -826,12 +826,56 @@ } } -class OGLAnyCompositeBlit extends Blit { +/** + * This general TransformedBlit implementation converts any source surface to an + * intermediate IntArgbPre surface, and then uses the more specific + * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate + * (premultiplied) surface down to OpenGL using simple transformBlit. + */ +final class OGLGeneralTransformedBlit extends TransformBlit { + + private final TransformBlit performop; + private WeakReference<SurfaceData> srcTmp; + + OGLGeneralTransformedBlit(final TransformBlit performop) { + super(SurfaceType.Any, CompositeType.AnyAlpha, + OGLSurfaceData.OpenGLSurface); + this.performop = performop; + } + + @Override + public synchronized void Transform(SurfaceData src, SurfaceData dst, + Composite comp, Region clip, + AffineTransform at, int hint, int srcx, + int srcy, int dstx, int dsty, int width, + int height){ + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), + CompositeType.SrcNoEa, + SurfaceType.IntArgbPre); + // use cached intermediate surface, if available + final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null; + // convert source to IntArgbPre + src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc, + BufferedImage.TYPE_INT_ARGB_PRE); + + // transform IntArgbPre intermediate surface to OpenGL surface + performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty, + width, height); + + if (src != cachedSrc) { + // cache the intermediate surface + srcTmp = new WeakReference<>(src); + } + } +} + +final class OGLAnyCompositeBlit extends Blit { private WeakReference<SurfaceData> dstTmp; - public OGLAnyCompositeBlit(SurfaceType dstType) { - super(SurfaceType.Any, CompositeType.Any, dstType); + OGLAnyCompositeBlit() { + super(SurfaceType.Any, CompositeType.Any, OGLSurfaceData.OpenGLSurface); } + public synchronized void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, @@ -848,15 +892,15 @@ cachedDst = dstTmp.get(); } - // convert source to IntArgbPre + // convert destination to IntArgbPre SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); + Region bufferClip = + clip == null ? null : clip.getTranslatedRegion(-dx, -dy); Blit performop = Blit.getFromCache(src.getSurfaceType(), CompositeType.Any, dstBuffer.getSurfaceType()); - - performop.Blit(src, dstBuffer, comp, clip, - sx, sy, 0, 0, w, h); + performop.Blit(src, dstBuffer, comp, bufferClip, sx, sy, 0, 0, w, h); if (dstBuffer != cachedDst) { // cache the intermediate surface
--- a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.PrintServiceLookup Fri Oct 31 11:31:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -# Provider for Java Print Service -sun.print.UnixPrintServiceLookup
--- a/jdk/src/java.desktop/unix/classes/META-INF/services/javax.print.StreamPrintServiceFactory Fri Oct 31 11:31:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -# Provider for Java 2D Stream print services. -sun.print.PSStreamPrinterFactory
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Fri Oct 31 12:01:27 2014 -1000 @@ -595,8 +595,13 @@ return isNetWMName("Mutter") || isNetWMName("GNOME Shell"); } + static int awtWMNonReparenting = -1; static boolean isNonReparentingWM() { - return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); + if (awtWMNonReparenting == -1) { + awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0; + } + return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM + || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM); } /*
--- a/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java Fri Oct 31 12:01:27 2014 -1000 @@ -324,8 +324,8 @@ * reported, exec lpstat -d which has all the Apple * special behaviour for this built in. */ - if (UnixPrintServiceLookup.isMac()) { - printerInfo[0] = UnixPrintServiceLookup. + if (PrintServiceLookupProvider.isMac()) { + printerInfo[0] = PrintServiceLookupProvider. getDefaultPrinterNameSysV(); printerInfo[1] = null; return printerInfo.clone();
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Fri Oct 31 12:01:27 2014 -1000 @@ -1047,7 +1047,7 @@ setting like collation. Therefore, we temporarily exclude Linux. */ - if (!UnixPrintServiceLookup.isLinux()) { + if (!PrintServiceLookupProvider.isLinux()) { catList.add(SheetCollate.class); } } @@ -1641,7 +1641,7 @@ * Mac is using printer-info IPP attribute for its human-readable printer * name and is also the identifier used in NSPrintInfo:setPrinter. */ - if (UnixPrintServiceLookup.isMac()) { + if (PrintServiceLookupProvider.isMac()) { PrintServiceAttributeSet psaSet = this.getAttributes(); if (psaSet != null) { PrinterInfo pName = (PrinterInfo)psaSet.get(PrinterInfo.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java Fri Oct 31 12:01:27 2014 -1000 @@ -0,0 +1,964 @@ +/* + * Copyright (c) 2000, 2014, 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 sun.print; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Vector; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import javax.print.DocFlavor; +import javax.print.MultiDocPrintService; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.HashPrintServiceAttributeSet; +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.PrintServiceAttributeSet; +import javax.print.attribute.standard.PrinterName; +import javax.print.attribute.standard.PrinterURI; +import java.io.File; +import java.io.FileReader; +import java.net.URL; +import java.nio.file.Files; + +/* + * Remind: This class uses solaris commands. We also need a linux + * version + */ +public class PrintServiceLookupProvider extends PrintServiceLookup + implements BackgroundServiceLookup, Runnable { + + /* Remind: the current implementation is static, as its assumed + * its preferable to minimize creation of PrintService instances. + * Later we should add logic to add/remove services on the fly which + * will take a hit of needing to regather the list of services. + */ + private String defaultPrinter; + private PrintService defaultPrintService; + private PrintService[] printServices; /* includes the default printer */ + private Vector<BackgroundLookupListener> lookupListeners = null; + private static String debugPrefix = "PrintServiceLookupProvider>> "; + private static boolean pollServices = true; + private static final int DEFAULT_MINREFRESH = 120; // 2 minutes + private static int minRefreshTime = DEFAULT_MINREFRESH; + + + static String osname; + + // List of commands used to deal with the printer queues on AIX + String[] lpNameComAix = { + "/usr/bin/lsallq", + "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '", + "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '", + "/usr/bin/lpstat -W -v" + }; + private static final int aix_lsallq = 0; + private static final int aix_lpstat_p = 1; + private static final int aix_lpstat_d = 2; + private static final int aix_lpstat_v = 3; + private static int aix_defaultPrinterEnumeration = aix_lsallq; + + static { + /* The system property "sun.java2d.print.polling" + * can be used to force the printing code to poll or not poll + * for PrintServices. + */ + String pollStr = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.java2d.print.polling")); + + if (pollStr != null) { + if (pollStr.equalsIgnoreCase("true")) { + pollServices = true; + } else if (pollStr.equalsIgnoreCase("false")) { + pollServices = false; + } + } + + /* The system property "sun.java2d.print.minRefreshTime" + * can be used to specify minimum refresh time (in seconds) + * for polling PrintServices. The default is 120. + */ + String refreshTimeStr = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "sun.java2d.print.minRefreshTime")); + + if (refreshTimeStr != null) { + try { + minRefreshTime = (new Integer(refreshTimeStr)).intValue(); + } catch (NumberFormatException e) { + } + if (minRefreshTime < DEFAULT_MINREFRESH) { + minRefreshTime = DEFAULT_MINREFRESH; + } + } + + osname = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("os.name")); + + /* The system property "sun.java2d.print.aix.lpstat" + * can be used to force the usage of 'lpstat -p' to enumerate all + * printer queues. By default we use 'lsallq', because 'lpstat -p' can + * take lots of time if thousands of printers are attached to a server. + */ + if (isAIX()) { + String aixPrinterEnumerator = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat")); + + if (aixPrinterEnumerator != null) { + if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) { + aix_defaultPrinterEnumeration = aix_lpstat_p; + } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) { + aix_defaultPrinterEnumeration = aix_lsallq; + } + } + } + } + + static boolean isMac() { + return osname.startsWith("Mac"); + } + + static boolean isSysV() { + return osname.equals("SunOS"); + } + + static boolean isLinux() { + return (osname.equals("Linux")); + } + + static boolean isBSD() { + return (osname.equals("Linux") || + osname.contains("OS X")); + } + + static boolean isAIX() { + return osname.equals("AIX"); + } + + static final int UNINITIALIZED = -1; + static final int BSD_LPD = 0; + static final int BSD_LPD_NG = 1; + + static int cmdIndex = UNINITIALIZED; + + String[] lpcFirstCom = { + "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'", + "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'" + }; + + String[] lpcAllCom = { + "/usr/sbin/lpc status all | grep : | sed -e 's/://'", + "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort" + }; + + String[] lpcNameCom = { + "| grep : | sed -ne 's/://p'", + "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'" + }; + + + static int getBSDCommandIndex() { + String command = "/usr/sbin/lpc status all"; + String[] names = execCmd(command); + + if ((names == null) || (names.length == 0)) { + return BSD_LPD_NG; + } + + for (int i=0; i<names.length; i++) { + if (names[i].indexOf('@') != -1) { + return BSD_LPD_NG; + } + } + + return BSD_LPD; + } + + + public PrintServiceLookupProvider() { + // start the printer listener thread + if (pollServices) { + PrinterChangeListener thr = new PrinterChangeListener(); + thr.setDaemon(true); + thr.start(); + IPPPrintService.debug_println(debugPrefix+"polling turned on"); + } + } + + /* Want the PrintService which is default print service to have + * equality of reference with the equivalent in list of print services + * This isn't required by the API and there's a risk doing this will + * lead people to assume its guaranteed. + */ + public synchronized PrintService[] getPrintServices() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPrintJobAccess(); + } + + if (printServices == null || !pollServices) { + refreshServices(); + } + if (printServices == null) { + return new PrintService[0]; + } else { + return printServices.clone(); + } + } + + private int addPrintServiceToList(ArrayList<PrintService> printerList, PrintService ps) { + int index = printerList.indexOf(ps); + // Check if PrintService with same name is already in the list. + if (CUPSPrinter.isCupsRunning() && index != -1) { + // Bug in Linux: Duplicate entry of a remote printer + // and treats it as local printer but it is returning wrong + // information when queried using IPP. Workaround is to remove it. + // Even CUPS ignores these entries as shown in lpstat or using + // their web configuration. + PrinterURI uri = ps.getAttribute(PrinterURI.class); + if (uri.getURI().getHost().equals("localhost")) { + IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps); + return index; // Do not add this. + } + PrintService oldPS = printerList.get(index); + uri = oldPS.getAttribute(PrinterURI.class); + if (uri.getURI().getHost().equals("localhost")) { + IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS); + printerList.remove(oldPS); + } else { + return index; + } + } + printerList.add(ps); + return (printerList.size() - 1); + } + + + // refreshes "printServices" + public synchronized void refreshServices() { + /* excludes the default printer */ + String[] printers = null; // array of printer names + String[] printerURIs = null; //array of printer URIs + + try { + getDefaultPrintService(); + } catch (Throwable t) { + IPPPrintService.debug_println(debugPrefix+ + "Exception getting default printer : " + t); + } + if (CUPSPrinter.isCupsRunning()) { + try { + printerURIs = CUPSPrinter.getAllPrinters(); + IPPPrintService.debug_println("CUPS URIs = " + printerURIs); + if (printerURIs != null) { + for (int p = 0; p < printerURIs.length; p++) { + IPPPrintService.debug_println("URI="+printerURIs[p]); + } + } + } catch (Throwable t) { + IPPPrintService.debug_println(debugPrefix+ + "Exception getting all CUPS printers : " + t); + } + if ((printerURIs != null) && (printerURIs.length > 0)) { + printers = new String[printerURIs.length]; + for (int i=0; i<printerURIs.length; i++) { + int lastIndex = printerURIs[i].lastIndexOf("/"); + printers[i] = printerURIs[i].substring(lastIndex+1); + } + } + } else { + if (isMac() || isSysV()) { + printers = getAllPrinterNamesSysV(); + } else if (isAIX()) { + printers = getAllPrinterNamesAIX(); + } else { //BSD + printers = getAllPrinterNamesBSD(); + } + } + + if (printers == null) { + if (defaultPrintService != null) { + printServices = new PrintService[1]; + printServices[0] = defaultPrintService; + } else { + printServices = null; + } + return; + } + + ArrayList<PrintService> printerList = new ArrayList<>(); + int defaultIndex = -1; + for (int p=0; p<printers.length; p++) { + if (printers[p] == null) { + continue; + } + if ((defaultPrintService != null) + && printers[p].equals(getPrinterDestName(defaultPrintService))) { + defaultIndex = addPrintServiceToList(printerList, defaultPrintService); + } else { + if (printServices == null) { + IPPPrintService.debug_println(debugPrefix+ + "total# of printers = "+printers.length); + + if (CUPSPrinter.isCupsRunning()) { + try { + addPrintServiceToList(printerList, + new IPPPrintService(printers[p], + printerURIs[p], + true)); + } catch (Exception e) { + IPPPrintService.debug_println(debugPrefix+ + " getAllPrinters Exception "+ + e); + + } + } else { + printerList.add(new UnixPrintService(printers[p])); + } + } else { + int j; + for (j=0; j<printServices.length; j++) { + if (printServices[j] != null) { + if (printers[p].equals(getPrinterDestName(printServices[j]))) { + printerList.add(printServices[j]); + printServices[j] = null; + break; + } + } + } + + if (j == printServices.length) { // not found? + if (CUPSPrinter.isCupsRunning()) { + try { + addPrintServiceToList(printerList, + new IPPPrintService(printers[p], + printerURIs[p], + true)); + } catch (Exception e) { + IPPPrintService.debug_println(debugPrefix+ + " getAllPrinters Exception "+ + e); + + } + } else { + printerList.add(new UnixPrintService(printers[p])); + } + } + } + } + } + + // Look for deleted services and invalidate these + if (printServices != null) { + for (int j=0; j < printServices.length; j++) { + if ((printServices[j] instanceof UnixPrintService) && + (!printServices[j].equals(defaultPrintService))) { + ((UnixPrintService)printServices[j]).invalidateService(); + } + } + } + + //if defaultService is not found in printerList + if (defaultIndex == -1 && defaultPrintService != null) { + defaultIndex = addPrintServiceToList(printerList, defaultPrintService); + } + + printServices = printerList.toArray(new PrintService[] {}); + + // swap default with the first in the list + if (defaultIndex > 0) { + PrintService saveService = printServices[0]; + printServices[0] = printServices[defaultIndex]; + printServices[defaultIndex] = saveService; + } + } + + private boolean matchesAttributes(PrintService service, + PrintServiceAttributeSet attributes) { + + Attribute [] attrs = attributes.toArray(); + for (int i=0; i<attrs.length; i++) { + @SuppressWarnings("unchecked") + Attribute serviceAttr + = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory()); + if (serviceAttr == null || !serviceAttr.equals(attrs[i])) { + return false; + } + } + return true; + } + + /* This checks for validity of the printer name before passing as + * parameter to a shell command. + */ + private boolean checkPrinterName(String s) { + char c; + + for (int i=0; i < s.length(); i++) { + c = s.charAt(i); + if (Character.isLetterOrDigit(c) || + c == '-' || c == '_' || c == '.' || c == '/') { + continue; + } else { + return false; + } + } + return true; + } + + /* + * Gets the printer name compatible with the list of printers returned by + * the system when we query default or all the available printers. + */ + private String getPrinterDestName(PrintService ps) { + if (isMac()) { + return ((IPPPrintService)ps).getDest(); + } + return ps.getName(); + } + + /* On a network with many (hundreds) of network printers, it + * can save several seconds if you know all you want is a particular + * printer, to ask for that printer rather than retrieving all printers. + */ + private PrintService getServiceByName(PrinterName nameAttr) { + String name = nameAttr.getValue(); + if (name == null || name.equals("") || !checkPrinterName(name)) { + return null; + } + /* check if all printers are already available */ + if (printServices != null) { + for (PrintService printService : printServices) { + PrinterName printerName = printService.getAttribute(PrinterName.class); + if (printerName.getValue().equals(name)) { + return printService; + } + } + } + /* take CUPS into account first */ + if (CUPSPrinter.isCupsRunning()) { + try { + return new IPPPrintService(name, + new URL("http://"+ + CUPSPrinter.getServer()+":"+ + CUPSPrinter.getPort()+"/"+ + name)); + } catch (Exception e) { + IPPPrintService.debug_println(debugPrefix+ + " getServiceByName Exception "+ + e); + } + } + /* fallback if nothing not having a printer at this point */ + PrintService printer = null; + if (isMac() || isSysV()) { + printer = getNamedPrinterNameSysV(name); + } else if (isAIX()) { + printer = getNamedPrinterNameAIX(name); + } else { + printer = getNamedPrinterNameBSD(name); + } + return printer; + } + + private PrintService[] + getPrintServices(PrintServiceAttributeSet serviceSet) { + + if (serviceSet == null || serviceSet.isEmpty()) { + return getPrintServices(); + } + + /* Typically expect that if a service attribute is specified that + * its a printer name and there ought to be only one match. + * Directly retrieve that service and confirm + * that it meets the other requirements. + * If printer name isn't mentioned then go a slow path checking + * all printers if they meet the reqiremements. + */ + PrintService[] services; + PrinterName name = (PrinterName)serviceSet.get(PrinterName.class); + PrintService defService; + if (name != null && (defService = getDefaultPrintService()) != null) { + /* To avoid execing a unix command see if the client is asking + * for the default printer by name, since we already have that + * initialised. + */ + + PrinterName defName = defService.getAttribute(PrinterName.class); + + if (defName != null && name.equals(defName)) { + if (matchesAttributes(defService, serviceSet)) { + services = new PrintService[1]; + services[0] = defService; + return services; + } else { + return new PrintService[0]; + } + } else { + /* Its not the default service */ + PrintService service = getServiceByName(name); + if (service != null && + matchesAttributes(service, serviceSet)) { + services = new PrintService[1]; + services[0] = service; + return services; + } else { + return new PrintService[0]; + } + } + } else { + /* specified service attributes don't include a name.*/ + Vector<PrintService> matchedServices = new Vector<>(); + services = getPrintServices(); + for (int i = 0; i< services.length; i++) { + if (matchesAttributes(services[i], serviceSet)) { + matchedServices.add(services[i]); + } + } + services = new PrintService[matchedServices.size()]; + for (int i = 0; i< services.length; i++) { + services[i] = matchedServices.elementAt(i); + } + return services; + } + } + + /* + * If service attributes are specified then there must be additional + * filtering. + */ + public PrintService[] getPrintServices(DocFlavor flavor, + AttributeSet attributes) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPrintJobAccess(); + } + PrintRequestAttributeSet requestSet = null; + PrintServiceAttributeSet serviceSet = null; + + if (attributes != null && !attributes.isEmpty()) { + + requestSet = new HashPrintRequestAttributeSet(); + serviceSet = new HashPrintServiceAttributeSet(); + + Attribute[] attrs = attributes.toArray(); + for (int i=0; i<attrs.length; i++) { + if (attrs[i] instanceof PrintRequestAttribute) { + requestSet.add(attrs[i]); + } else if (attrs[i] instanceof PrintServiceAttribute) { + serviceSet.add(attrs[i]); + } + } + } + + PrintService[] services = getPrintServices(serviceSet); + if (services.length == 0) { + return services; + } + + if (CUPSPrinter.isCupsRunning()) { + ArrayList<PrintService> matchingServices = new ArrayList<>(); + for (int i=0; i<services.length; i++) { + try { + if (services[i]. + getUnsupportedAttributes(flavor, requestSet) == null) { + matchingServices.add(services[i]); + } + } catch (IllegalArgumentException e) { + } + } + services = new PrintService[matchingServices.size()]; + return matchingServices.toArray(services); + + } else { + // We only need to compare 1 PrintService because all + // UnixPrintServices are the same anyway. We will not use + // default PrintService because it might be null. + PrintService service = services[0]; + if ((flavor == null || + service.isDocFlavorSupported(flavor)) && + service.getUnsupportedAttributes(flavor, requestSet) == null) + { + return services; + } else { + return new PrintService[0]; + } + } + } + + /* + * return empty array as don't support multi docs + */ + public MultiDocPrintService[] + getMultiDocPrintServices(DocFlavor[] flavors, + AttributeSet attributes) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPrintJobAccess(); + } + return new MultiDocPrintService[0]; + } + + + public synchronized PrintService getDefaultPrintService() { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkPrintJobAccess(); + } + + // clear defaultPrintService + defaultPrintService = null; + String psuri = null; + + IPPPrintService.debug_println("isRunning ? "+ + (CUPSPrinter.isCupsRunning())); + if (CUPSPrinter.isCupsRunning()) { + String[] printerInfo = CUPSPrinter.getDefaultPrinter(); + if (printerInfo != null && printerInfo.length >= 2) { + defaultPrinter = printerInfo[0]; + psuri = printerInfo[1]; + } + } else { + if (isMac() || isSysV()) { + defaultPrinter = getDefaultPrinterNameSysV(); + } else if (isAIX()) { + defaultPrinter = getDefaultPrinterNameAIX(); + } else { + defaultPrinter = getDefaultPrinterNameBSD(); + } + } + if (defaultPrinter == null) { + return null; + } + defaultPrintService = null; + if (printServices != null) { + for (int j=0; j<printServices.length; j++) { + if (defaultPrinter.equals(getPrinterDestName(printServices[j]))) { + defaultPrintService = printServices[j]; + break; + } + } + } + if (defaultPrintService == null) { + if (CUPSPrinter.isCupsRunning()) { + try { + PrintService defaultPS; + if ((psuri != null) && !psuri.startsWith("file")) { + defaultPS = new IPPPrintService(defaultPrinter, + psuri, true); + } else { + defaultPS = new IPPPrintService(defaultPrinter, + new URL("http://"+ + CUPSPrinter.getServer()+":"+ + CUPSPrinter.getPort()+"/"+ + defaultPrinter)); + } + defaultPrintService = defaultPS; + } catch (Exception e) { + } + } else { + defaultPrintService = new UnixPrintService(defaultPrinter); + } + } + + return defaultPrintService; + } + + public synchronized void + getServicesInbackground(BackgroundLookupListener listener) { + if (printServices != null) { + listener.notifyServices(printServices); + } else { + if (lookupListeners == null) { + lookupListeners = new Vector<>(); + lookupListeners.add(listener); + Thread lookupThread = new Thread(this); + lookupThread.start(); + } else { + lookupListeners.add(listener); + } + } + } + + /* This method isn't used in most cases because we rely on code in + * javax.print.PrintServiceLookup. This is needed just for the cases + * where those interfaces are by-passed. + */ + private PrintService[] copyOf(PrintService[] inArr) { + if (inArr == null || inArr.length == 0) { + return inArr; + } else { + PrintService []outArr = new PrintService[inArr.length]; + System.arraycopy(inArr, 0, outArr, 0, inArr.length); + return outArr; + } + } + + public void run() { + PrintService[] services = getPrintServices(); + synchronized (this) { + BackgroundLookupListener listener; + for (int i=0; i<lookupListeners.size(); i++) { + listener = lookupListeners.elementAt(i); + listener.notifyServices(copyOf(services)); + } + lookupListeners = null; + } + } + + private String getDefaultPrinterNameBSD() { + if (cmdIndex == UNINITIALIZED) { + cmdIndex = getBSDCommandIndex(); + } + String[] names = execCmd(lpcFirstCom[cmdIndex]); + if (names == null || names.length == 0) { + return null; + } + + if ((cmdIndex==BSD_LPD_NG) && + (names[0].startsWith("missingprinter"))) { + return null; + } + return names[0]; + } + + private PrintService getNamedPrinterNameBSD(String name) { + if (cmdIndex == UNINITIALIZED) { + cmdIndex = getBSDCommandIndex(); + } + String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex]; + String[] result = execCmd(command); + + if (result == null || !(result[0].equals(name))) { + return null; + } + return new UnixPrintService(name); + } + + private String[] getAllPrinterNamesBSD() { + if (cmdIndex == UNINITIALIZED) { + cmdIndex = getBSDCommandIndex(); + } + String[] names = execCmd(lpcAllCom[cmdIndex]); + if (names == null || names.length == 0) { + return null; + } + return names; + } + + static String getDefaultPrinterNameSysV() { + String defaultPrinter = "lp"; + String command = "/usr/bin/lpstat -d"; + + String [] names = execCmd(command); + if (names == null || names.length == 0) { + return defaultPrinter; + } else { + int index = names[0].indexOf(":"); + if (index == -1 || (names[0].length() <= index+1)) { + return null; + } else { + String name = names[0].substring(index+1).trim(); + if (name.length() == 0) { + return null; + } else { + return name; + } + } + } + } + + private PrintService getNamedPrinterNameSysV(String name) { + + String command = "/usr/bin/lpstat -v " + name; + String []result = execCmd(command); + + if (result == null || result[0].indexOf("unknown printer") > 0) { + return null; + } else { + return new UnixPrintService(name); + } + } + + private String[] getAllPrinterNamesSysV() { + String defaultPrinter = "lp"; + String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort"; + + String [] names = execCmd(command); + ArrayList<String> printerNames = new ArrayList<>(); + for (int i=0; i < names.length; i++) { + if (!names[i].equals("_default") && + !names[i].equals(defaultPrinter) && + !names[i].equals("")) { + printerNames.add(names[i]); + } + } + return printerNames.toArray(new String[printerNames.size()]); + } + + private String getDefaultPrinterNameAIX() { + String[] names = execCmd(lpNameComAix[aix_lpstat_d]); + // Remove headers and bogus entries added by remote printers. + names = UnixPrintService.filterPrinterNamesAIX(names); + if (names == null || names.length != 1) { + // No default printer found + return null; + } else { + return names[0]; + } + } + + private PrintService getNamedPrinterNameAIX(String name) { + // On AIX there should be no blank after '-v'. + String[] result = execCmd(lpNameComAix[aix_lpstat_v] + name); + // Remove headers and bogus entries added by remote printers. + result = UnixPrintService.filterPrinterNamesAIX(result); + if (result == null || result.length != 1) { + return null; + } else { + return new UnixPrintService(name); + } + } + + private String[] getAllPrinterNamesAIX() { + // Determine all printers of the system. + String [] names = execCmd(lpNameComAix[aix_defaultPrinterEnumeration]); + + // Remove headers and bogus entries added by remote printers. + names = UnixPrintService.filterPrinterNamesAIX(names); + + ArrayList<String> printerNames = new ArrayList<String>(); + for ( int i=0; i < names.length; i++) { + printerNames.add(names[i]); + } + return printerNames.toArray(new String[printerNames.size()]); + } + + static String[] execCmd(final String command) { + ArrayList<String> results = null; + try { + final String[] cmd = new String[3]; + if (isSysV() || isAIX()) { + cmd[0] = "/usr/bin/sh"; + cmd[1] = "-c"; + cmd[2] = "env LC_ALL=C " + command; + } else { + cmd[0] = "/bin/sh"; + cmd[1] = "-c"; + cmd[2] = "LC_ALL=C " + command; + } + + results = AccessController.doPrivileged( + new PrivilegedExceptionAction<ArrayList<String>>() { + public ArrayList<String> run() throws IOException { + + Process proc; + BufferedReader bufferedReader = null; + File f = Files.createTempFile("prn","xc").toFile(); + cmd[2] = cmd[2]+">"+f.getAbsolutePath(); + + proc = Runtime.getRuntime().exec(cmd); + try { + boolean done = false; // in case of interrupt. + while (!done) { + try { + proc.waitFor(); + done = true; + } catch (InterruptedException e) { + } + } + + if (proc.exitValue() == 0) { + FileReader reader = new FileReader(f); + bufferedReader = new BufferedReader(reader); + String line; + ArrayList<String> results = new ArrayList<>(); + while ((line = bufferedReader.readLine()) + != null) { + results.add(line); + } + return results; + } + } finally { + f.delete(); + // promptly close all streams. + if (bufferedReader != null) { + bufferedReader.close(); + } + proc.getInputStream().close(); + proc.getErrorStream().close(); + proc.getOutputStream().close(); + } + return null; + } + }); + } catch (PrivilegedActionException e) { + } + if (results == null) { + return new String[0]; + } else { + return results.toArray(new String[results.size()]); + } + } + + private class PrinterChangeListener extends Thread { + + public void run() { + int refreshSecs; + while (true) { + try { + refreshServices(); + } catch (Exception se) { + IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread."); + break; + } + + if ((printServices != null) && + (printServices.length > minRefreshTime)) { + // compute new refresh time 1 printer = 1 sec + refreshSecs = printServices.length; + } else { + refreshSecs = minRefreshTime; + } + try { + sleep(refreshSecs * 1000); + } catch (InterruptedException e) { + break; + } + } + } + } +}
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java Fri Oct 31 12:01:27 2014 -1000 @@ -122,7 +122,7 @@ UnixPrintJob(PrintService service) { this.service = service; mDestination = service.getName(); - if (UnixPrintServiceLookup.isMac()) { + if (PrintServiceLookupProvider.isMac()) { mDestination = ((IPPPrintService)service).getDest(); } mDestType = UnixPrintJob.DESTPRINTER; @@ -880,7 +880,7 @@ pFlags |= NOSHEET; ncomps+=1; } - if (UnixPrintServiceLookup.osname.equals("SunOS")) { + if (PrintServiceLookupProvider.osname.equals("SunOS")) { ncomps+=1; // lp uses 1 more arg than lpr (make a copy) execCmd = new String[ncomps]; execCmd[n++] = "/usr/bin/lp";
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Fri Oct 31 11:31:30 2014 +0000 +++ b/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintService.java Fri Oct 31 12:01:27 2014 -1000 @@ -220,7 +220,7 @@ private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsSysV() { String command = "/usr/bin/lpstat -a " + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { if (results[0].startsWith(printer + " accepting requests")) { @@ -244,20 +244,20 @@ } private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsBSD() { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.UNINITIALIZED) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { - UnixPrintServiceLookup.cmdIndex = - UnixPrintServiceLookup.getBSDCommandIndex(); + PrintServiceLookupProvider.cmdIndex = + PrintServiceLookupProvider.getBSDCommandIndex(); } String command = "/usr/sbin/lpc status " + printer - + lpcStatusCom[UnixPrintServiceLookup.cmdIndex]; - String results[]= UnixPrintServiceLookup.execCmd(command); + + lpcStatusCom[PrintServiceLookupProvider.cmdIndex]; + String results[]= PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.BSD_LPD_NG) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.BSD_LPD_NG) { if (results[0].startsWith("enabled enabled")) { return PrinterIsAcceptingJobs.ACCEPTING_JOBS ; } @@ -276,7 +276,7 @@ // Filter the list of possible AIX Printers and remove header lines // and extra lines which have been added for remote printers. - // 'protected' because this method is also used from UnixPrintServiceLookup. + // 'protected' because this method is also used from PrintServiceLookupProvider. protected static String[] filterPrinterNamesAIX(String[] posPrinters) { ArrayList<String> printers = new ArrayList<>(); String [] splitPart; @@ -301,7 +301,7 @@ private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsAIX() { // On AIX there should not be a blank after '-a'. String command = "/usr/bin/lpstat -a" + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); // Remove headers and bogus entries added by remote printers. results = filterPrinterNamesAIX(results); @@ -320,11 +320,11 @@ } private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getPrinterIsAcceptingJobsSysV(); - } else if (UnixPrintServiceLookup.isBSD()) { + } else if (PrintServiceLookupProvider.isBSD()) { return getPrinterIsAcceptingJobsBSD(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getPrinterIsAcceptingJobsAIX(); } else { return PrinterIsAcceptingJobs.ACCEPTING_JOBS; @@ -351,29 +351,29 @@ private QueuedJobCount getQueuedJobCountSysV() { String command = "/usr/bin/lpstat -R " + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); int qlen = (results == null) ? 0 : results.length; return new QueuedJobCount(qlen); } private QueuedJobCount getQueuedJobCountBSD() { - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.UNINITIALIZED) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { - UnixPrintServiceLookup.cmdIndex = - UnixPrintServiceLookup.getBSDCommandIndex(); + PrintServiceLookupProvider.cmdIndex = + PrintServiceLookupProvider.getBSDCommandIndex(); } int qlen = 0; String command = "/usr/sbin/lpc status " + printer - + lpcQueueCom[UnixPrintServiceLookup.cmdIndex]; - String results[] = UnixPrintServiceLookup.execCmd(command); + + lpcQueueCom[PrintServiceLookupProvider.cmdIndex]; + String results[] = PrintServiceLookupProvider.execCmd(command); if (results != null && results.length > 0) { String queued; - if (UnixPrintServiceLookup.cmdIndex == - UnixPrintServiceLookup.BSD_LPD_NG) { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.BSD_LPD_NG) { queued = results[0]; } else { queued = results[3].trim(); @@ -396,7 +396,7 @@ private QueuedJobCount getQueuedJobCountAIX() { // On AIX there should not be a blank after '-a'. String command = "/usr/bin/lpstat -a" + printer; - String results[]= UnixPrintServiceLookup.execCmd(command); + String results[]= PrintServiceLookupProvider.execCmd(command); // Remove headers and bogus entries added by remote printers. results = filterPrinterNamesAIX(results); @@ -413,11 +413,11 @@ } private QueuedJobCount getQueuedJobCount() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getQueuedJobCountSysV(); - } else if (UnixPrintServiceLookup.isBSD()) { + } else if (PrintServiceLookupProvider.isBSD()) { return getQueuedJobCountBSD(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getQueuedJobCountAIX(); } else { return new QueuedJobCount(0); @@ -468,9 +468,9 @@ } private PrintServiceAttributeSet getDynamicAttributes() { - if (UnixPrintServiceLookup.isSysV()) { + if (PrintServiceLookupProvider.isSysV()) { return getSysVServiceAttributes(); - } else if (UnixPrintServiceLookup.isAIX()) { + } else if (PrintServiceLookupProvider.isAIX()) { return getAIXServiceAttributes(); } else { return getBSDServiceAttributes();
--- a/jdk/src/java.desktop/unix/classes/sun/print/UnixPrintServiceLookup.java Fri Oct 31 11:31:30 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,964 +0,0 @@ -/* - * Copyright (c) 2000, 2014, 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 sun.print; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Vector; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import javax.print.DocFlavor; -import javax.print.MultiDocPrintService; -import javax.print.PrintService; -import javax.print.PrintServiceLookup; -import javax.print.attribute.Attribute; -import javax.print.attribute.AttributeSet; -import javax.print.attribute.HashPrintRequestAttributeSet; -import javax.print.attribute.HashPrintServiceAttributeSet; -import javax.print.attribute.PrintRequestAttribute; -import javax.print.attribute.PrintRequestAttributeSet; -import javax.print.attribute.PrintServiceAttribute; -import javax.print.attribute.PrintServiceAttributeSet; -import javax.print.attribute.standard.PrinterName; -import javax.print.attribute.standard.PrinterURI; -import java.io.File; -import java.io.FileReader; -import java.net.URL; -import java.nio.file.Files; - -/* - * Remind: This class uses solaris commands. We also need a linux - * version - */ -public class UnixPrintServiceLookup extends PrintServiceLookup - implements BackgroundServiceLookup, Runnable { - - /* Remind: the current implementation is static, as its assumed - * its preferable to minimize creation of PrintService instances. - * Later we should add logic to add/remove services on the fly which - * will take a hit of needing to regather the list of services. - */ - private String defaultPrinter; - private PrintService defaultPrintService; - private PrintService[] printServices; /* includes the default printer */ - private Vector<BackgroundLookupListener> lookupListeners = null; - private static String debugPrefix = "UnixPrintServiceLookup>> "; - private static boolean pollServices = true; - private static final int DEFAULT_MINREFRESH = 120; // 2 minutes - private static int minRefreshTime = DEFAULT_MINREFRESH; - - - static String osname; - - // List of commands used to deal with the printer queues on AIX - String[] lpNameComAix = { - "/usr/bin/lsallq", - "/usr/bin/lpstat -W -p|/usr/bin/expand|/usr/bin/cut -f1 -d' '", - "/usr/bin/lpstat -W -d|/usr/bin/expand|/usr/bin/cut -f1 -d' '", - "/usr/bin/lpstat -W -v" - }; - private static final int aix_lsallq = 0; - private static final int aix_lpstat_p = 1; - private static final int aix_lpstat_d = 2; - private static final int aix_lpstat_v = 3; - private static int aix_defaultPrinterEnumeration = aix_lsallq; - - static { - /* The system property "sun.java2d.print.polling" - * can be used to force the printing code to poll or not poll - * for PrintServices. - */ - String pollStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.print.polling")); - - if (pollStr != null) { - if (pollStr.equalsIgnoreCase("true")) { - pollServices = true; - } else if (pollStr.equalsIgnoreCase("false")) { - pollServices = false; - } - } - - /* The system property "sun.java2d.print.minRefreshTime" - * can be used to specify minimum refresh time (in seconds) - * for polling PrintServices. The default is 120. - */ - String refreshTimeStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.print.minRefreshTime")); - - if (refreshTimeStr != null) { - try { - minRefreshTime = (new Integer(refreshTimeStr)).intValue(); - } catch (NumberFormatException e) { - } - if (minRefreshTime < DEFAULT_MINREFRESH) { - minRefreshTime = DEFAULT_MINREFRESH; - } - } - - osname = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("os.name")); - - /* The system property "sun.java2d.print.aix.lpstat" - * can be used to force the usage of 'lpstat -p' to enumerate all - * printer queues. By default we use 'lsallq', because 'lpstat -p' can - * take lots of time if thousands of printers are attached to a server. - */ - if (isAIX()) { - String aixPrinterEnumerator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat")); - - if (aixPrinterEnumerator != null) { - if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) { - aix_defaultPrinterEnumeration = aix_lpstat_p; - } else if (aixPrinterEnumerator.equalsIgnoreCase("lsallq")) { - aix_defaultPrinterEnumeration = aix_lsallq; - } - } - } - } - - static boolean isMac() { - return osname.startsWith("Mac"); - } - - static boolean isSysV() { - return osname.equals("SunOS"); - } - - static boolean isLinux() { - return (osname.equals("Linux")); - } - - static boolean isBSD() { - return (osname.equals("Linux") || - osname.contains("OS X")); - } - - static boolean isAIX() { - return osname.equals("AIX"); - } - - static final int UNINITIALIZED = -1; - static final int BSD_LPD = 0; - static final int BSD_LPD_NG = 1; - - static int cmdIndex = UNINITIALIZED; - - String[] lpcFirstCom = { - "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'", - "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'" - }; - - String[] lpcAllCom = { - "/usr/sbin/lpc status all | grep : | sed -e 's/://'", - "/usr/sbin/lpc status all | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort" - }; - - String[] lpcNameCom = { - "| grep : | sed -ne 's/://p'", - "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'" - }; - - - static int getBSDCommandIndex() { - String command = "/usr/sbin/lpc status all"; - String[] names = execCmd(command); - - if ((names == null) || (names.length == 0)) { - return BSD_LPD_NG; - } - - for (int i=0; i<names.length; i++) { - if (names[i].indexOf('@') != -1) { - return BSD_LPD_NG; - } - } - - return BSD_LPD; - } - - - public UnixPrintServiceLookup() { - // start the printer listener thread - if (pollServices) { - PrinterChangeListener thr = new PrinterChangeListener(); - thr.setDaemon(true); - thr.start(); - IPPPrintService.debug_println(debugPrefix+"polling turned on"); - } - } - - /* Want the PrintService which is default print service to have - * equality of reference with the equivalent in list of print services - * This isn't required by the API and there's a risk doing this will - * lead people to assume its guaranteed. - */ - public synchronized PrintService[] getPrintServices() { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPrintJobAccess(); - } - - if (printServices == null || !pollServices) { - refreshServices(); - } - if (printServices == null) { - return new PrintService[0]; - } else { - return printServices.clone(); - } - } - - private int addPrintServiceToList(ArrayList<PrintService> printerList, PrintService ps) { - int index = printerList.indexOf(ps); - // Check if PrintService with same name is already in the list. - if (CUPSPrinter.isCupsRunning() && index != -1) { - // Bug in Linux: Duplicate entry of a remote printer - // and treats it as local printer but it is returning wrong - // information when queried using IPP. Workaround is to remove it. - // Even CUPS ignores these entries as shown in lpstat or using - // their web configuration. - PrinterURI uri = ps.getAttribute(PrinterURI.class); - if (uri.getURI().getHost().equals("localhost")) { - IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, ignoring the new local printer: "+ps); - return index; // Do not add this. - } - PrintService oldPS = printerList.get(index); - uri = oldPS.getAttribute(PrinterURI.class); - if (uri.getURI().getHost().equals("localhost")) { - IPPPrintService.debug_println(debugPrefix+"duplicate PrintService, removing existing local printer: "+oldPS); - printerList.remove(oldPS); - } else { - return index; - } - } - printerList.add(ps); - return (printerList.size() - 1); - } - - - // refreshes "printServices" - public synchronized void refreshServices() { - /* excludes the default printer */ - String[] printers = null; // array of printer names - String[] printerURIs = null; //array of printer URIs - - try { - getDefaultPrintService(); - } catch (Throwable t) { - IPPPrintService.debug_println(debugPrefix+ - "Exception getting default printer : " + t); - } - if (CUPSPrinter.isCupsRunning()) { - try { - printerURIs = CUPSPrinter.getAllPrinters(); - IPPPrintService.debug_println("CUPS URIs = " + printerURIs); - if (printerURIs != null) { - for (int p = 0; p < printerURIs.length; p++) { - IPPPrintService.debug_println("URI="+printerURIs[p]); - } - } - } catch (Throwable t) { - IPPPrintService.debug_println(debugPrefix+ - "Exception getting all CUPS printers : " + t); - } - if ((printerURIs != null) && (printerURIs.length > 0)) { - printers = new String[printerURIs.length]; - for (int i=0; i<printerURIs.length; i++) { - int lastIndex = printerURIs[i].lastIndexOf("/"); - printers[i] = printerURIs[i].substring(lastIndex+1); - } - } - } else { - if (isMac() || isSysV()) { - printers = getAllPrinterNamesSysV(); - } else if (isAIX()) { - printers = getAllPrinterNamesAIX(); - } else { //BSD - printers = getAllPrinterNamesBSD(); - } - } - - if (printers == null) { - if (defaultPrintService != null) { - printServices = new PrintService[1]; - printServices[0] = defaultPrintService; - } else { - printServices = null; - } - return; - } - - ArrayList<PrintService> printerList = new ArrayList<>(); - int defaultIndex = -1; - for (int p=0; p<printers.length; p++) { - if (printers[p] == null) { - continue; - } - if ((defaultPrintService != null) - && printers[p].equals(getPrinterDestName(defaultPrintService))) { - defaultIndex = addPrintServiceToList(printerList, defaultPrintService); - } else { - if (printServices == null) { - IPPPrintService.debug_println(debugPrefix+ - "total# of printers = "+printers.length); - - if (CUPSPrinter.isCupsRunning()) { - try { - addPrintServiceToList(printerList, - new IPPPrintService(printers[p], - printerURIs[p], - true)); - } catch (Exception e) { - IPPPrintService.debug_println(debugPrefix+ - " getAllPrinters Exception "+ - e); - - } - } else { - printerList.add(new UnixPrintService(printers[p])); - } - } else { - int j; - for (j=0; j<printServices.length; j++) { - if (printServices[j] != null) { - if (printers[p].equals(getPrinterDestName(printServices[j]))) { - printerList.add(printServices[j]); - printServices[j] = null; - break; - } - } - } - - if (j == printServices.length) { // not found? - if (CUPSPrinter.isCupsRunning()) { - try { - addPrintServiceToList(printerList, - new IPPPrintService(printers[p], - printerURIs[p], - true)); - } catch (Exception e) { - IPPPrintService.debug_println(debugPrefix+ - " getAllPrinters Exception "+ - e); - - } - } else { - printerList.add(new UnixPrintService(printers[p])); - } - } - } - } - } - - // Look for deleted services and invalidate these - if (printServices != null) { - for (int j=0; j < printServices.length; j++) { - if ((printServices[j] instanceof UnixPrintService) && - (!printServices[j].equals(defaultPrintService))) { - ((UnixPrintService)printServices[j]).invalidateService(); - } - } - } - - //if defaultService is not found in printerList - if (defaultIndex == -1 && defaultPrintService != null) { - defaultIndex = addPrintServiceToList(printerList, defaultPrintService); - } - - printServices = printerList.toArray(new PrintService[] {}); - - // swap default with the first in the list - if (defaultIndex > 0) { - PrintService saveService = printServices[0]; - printServices[0] = printServices[defaultIndex]; - printServices[defaultIndex] = saveService; - } - } - - private boolean matchesAttributes(PrintService service, - PrintServiceAttributeSet attributes) { - - Attribute [] attrs = attributes.toArray(); - for (int i=0; i<attrs.length; i++) { - @SuppressWarnings("unchecked") - Attribute serviceAttr - = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory()); - if (serviceAttr == null || !serviceAttr.equals(attrs[i])) { - return false; - } - } - return true; - } - - /* This checks for validity of the printer name before passing as - * parameter to a shell command. - */ - private boolean checkPrinterName(String s) { - char c; - - for (int i=0; i < s.length(); i++) { - c = s.charAt(i); - if (Character.isLetterOrDigit(c) || - c == '-' || c == '_' || c == '.' || c == '/') { - continue; - } else { - return false; - } - } - return true; - } - - /* - * Gets the printer name compatible with the list of printers returned by - * the system when we query default or all the available printers. - */ - private String getPrinterDestName(PrintService ps) { - if (isMac()) { - return ((IPPPrintService)ps).getDest(); - } - return ps.getName(); - } - - /* On a network with many (hundreds) of network printers, it - * can save several seconds if you know all you want is a particular - * printer, to ask for that printer rather than retrieving all printers. - */ - private PrintService getServiceByName(PrinterName nameAttr) { - String name = nameAttr.getValue();