Mercurial > hg > release > icedtea7-forest-2.6 > jdk
changeset 7384:efc8886310cb jdk7u60-b04 jdk7u80-b00
Merge
author | lana |
---|---|
date | Mon, 20 Jan 2014 12:12:07 -0800 |
parents | 9af71eceaee6 (current diff) 628c6d46263b (diff) |
children | 19cc3b567644 2b52567922b6 |
files | src/share/classes/java/util/logging/LogManager.java |
diffstat | 18 files changed, 535 insertions(+), 168 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Jan 20 12:12:07 2014 -0800 @@ -53,7 +53,8 @@ if (!member.isResolved()) throw new InternalError(); - if (member.getDeclaringClass().isInterface() && !member.isAbstract()) { + if (member.getDeclaringClass().isInterface() && + member.isMethod() && !member.isAbstract()) { // Check for corner case: invokeinterface of Object method MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind()); m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
--- a/src/share/classes/java/nio/file/Files.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/java/nio/file/Files.java Mon Jan 20 12:12:07 2014 -0800 @@ -2978,13 +2978,13 @@ * method is invoked to check read access to the file. */ public static byte[] readAllBytes(Path path) throws IOException { - try (FileChannel fc = FileChannel.open(path); - InputStream is = Channels.newInputStream(fc)) { - long size = fc.size(); + try (SeekableByteChannel sbc = Files.newByteChannel(path); + InputStream in = Channels.newInputStream(sbc)) { + long size = sbc.size(); if (size > (long)MAX_BUFFER_SIZE) throw new OutOfMemoryError("Required array size too large"); - return read(is, (int)size); + return read(in, (int)size); } }
--- a/src/share/classes/java/util/logging/LogManager.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/java/util/logging/LogManager.java Mon Jan 20 12:12:07 2014 -0800 @@ -363,6 +363,9 @@ changes.removePropertyChangeListener(l); } + // LoggerContext maps from AppContext + private static WeakHashMap<Object, LoggerContext> contextsMap = null; + // Returns the LoggerContext for the user code (i.e. application or AppContext). // Loggers are isolated from each AppContext. private LoggerContext getUserContext() { @@ -371,33 +374,28 @@ SecurityManager sm = System.getSecurityManager(); JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); if (sm != null && javaAwtAccess != null) { + // for each applet, it has its own LoggerContext isolated from others synchronized (javaAwtAccess) { - // AppContext.getAppContext() returns the system AppContext if called - // from a system thread but Logger.getLogger might be called from - // an applet code. Instead, find the AppContext of the applet code - // from the execution stack. - Object ecx = javaAwtAccess.getExecutionContext(); - if (ecx == null) { - // fall back to thread group seach of AppContext - ecx = javaAwtAccess.getContext(); - } + // find the AppContext of the applet code + // will be null if we are in the main app context. + final Object ecx = javaAwtAccess.getAppletContext(); if (ecx != null) { - context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class); + if (contextsMap == null) { + contextsMap = new WeakHashMap<>(); + } + context = contextsMap.get(ecx); if (context == null) { - if (javaAwtAccess.isMainAppContext()) { - context = userContext; - } else { - // Create a new LoggerContext for the applet. - // The new logger context has its requiresDefaultLoggers - // flag set to true - so that these loggers will be - // lazily added when the context is firt accessed. - context = new LoggerContext(true); - } - javaAwtAccess.put(ecx, LoggerContext.class, context); + // Create a new LoggerContext for the applet. + // The new logger context has its requiresDefaultLoggers + // flag set to true - so that these loggers will be + // lazily added when the context is firt accessed. + context = new LoggerContext(true); + contextsMap.put(ecx, context); } } } } + // for standalone app, return userContext return context != null ? context : userContext; }
--- a/src/share/classes/sun/awt/AppContext.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/sun/awt/AppContext.java Mon Jan 20 12:12:07 2014 -0800 @@ -837,21 +837,68 @@ public boolean isMainAppContext() { return (numAppContexts.get() == 1 && mainAppContext != null); } - public Object getContext() { - return getAppContext(); - } - public Object getExecutionContext() { - return getExecutionAppContext(); + + private boolean hasRootThreadGroup(final AppContext ecx) { + return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + @Override + public Boolean run() { + return ecx.threadGroup.getParent() == null; + } + }); } - public Object get(Object context, Object key) { - return ((AppContext)context).get(key); + + /** + * Returns the AppContext used for applet logging isolation, or null if + * the default global context can be used. + * If there's no applet, or if the caller is a stand alone application, + * or running in the main app context, returns null. + * Otherwise, returns the AppContext of the calling applet. + * @return null if the global default context can be used, + * an AppContext otherwise. + **/ + public Object getAppletContext() { + // There's no AppContext: return null. + // No need to call getAppContext() if numAppContext == 0: + // it means that no AppContext has been created yet, and + // we don't want to trigger the creation of a main app + // context since we don't need it. + if (numAppContexts.get() == 0) return null; + + // Get the context from the security manager + AppContext ecx = getExecutionAppContext(); + + // Not sure we really need to re-check numAppContexts here. + // If all applets have gone away then we could have a + // numAppContexts coming back to 0. So we recheck + // it here because we don't want to trigger the + // creation of a main AppContext in that case. + // This is probably not 100% MT-safe but should reduce + // the window of opportunity in which that issue could + // happen. + if (numAppContexts.get() > 0) { + // Defaults to thread group caching. + // This is probably not required as we only really need + // isolation in a deployed applet environment, in which + // case ecx will not be null when we reach here + // However it helps emulate the deployed environment, + // in tests for instance. + ecx = ecx != null ? ecx : getAppContext(); + } + + // getAppletContext() may be called when initializing the main + // app context - in which case mainAppContext will still be + // null. To work around this issue we simply use + // AppContext.threadGroup.getParent() == null instead, since + // mainAppContext is the only AppContext which should have + // the root TG as its thread group. + // See: JDK-8023258 + final boolean isMainAppContext = ecx == null + || mainAppContext == ecx + || mainAppContext == null && hasRootThreadGroup(ecx); + + return isMainAppContext ? null : ecx; } - public void put(Object context, Object key, Object value) { - ((AppContext)context).put(key, value); - } - public void remove(Object context, Object key) { - ((AppContext)context).remove(key); - } + }); } }
--- a/src/share/classes/sun/misc/JavaAWTAccess.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/sun/misc/JavaAWTAccess.java Mon Jan 20 12:12:07 2014 -0800 @@ -26,14 +26,16 @@ package sun.misc; public interface JavaAWTAccess { - public Object getContext(); - public Object getExecutionContext(); - public Object get(Object context, Object key); - public void put(Object context, Object key, Object value); - public void remove(Object context, Object key); + // Returns the AppContext used for applet logging isolation, or null if + // no isolation is required. + // If there's no applet, or if the caller is a stand alone application, + // or running in the main app context, returns null. + // Otherwise, returns the AppContext of the calling applet. + public Object getAppletContext(); - // convenience methods whose context is the object returned by getContext() + // convenience methods to cache objects in the current thread group's + // AppContext public Object get(Object key); public void put(Object key, Object value); public void remove(Object key);
--- a/src/share/classes/sun/misc/SharedSecrets.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/share/classes/sun/misc/SharedSecrets.java Mon Jan 20 12:12:07 2014 -0800 @@ -197,9 +197,6 @@ public static JavaAWTAccess getJavaAWTAccess() { // this may return null in which case calling code needs to // provision for. - if (javaAWTAccess == null || javaAWTAccess.getContext() == null) { - return null; - } return javaAWTAccess; } }
--- a/src/solaris/native/sun/awt/awt_LoadLibrary.c Thu Jan 16 11:52:13 2014 -0800 +++ b/src/solaris/native/sun/awt/awt_LoadLibrary.c Mon Jan 20 12:12:07 2014 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -96,7 +96,7 @@ jvm = vm; /* Get address of this library and the directory containing it. */ - dladdr((void *)JNI_OnLoad, &dlinfo); + dladdr((void *)AWT_OnLoad, &dlinfo); realpath((char *)dlinfo.dli_fname, buf); len = strlen(buf); p = strrchr(buf, '/');
--- a/src/windows/classes/sun/nio/fs/WindowsConstants.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/windows/classes/sun/nio/fs/WindowsConstants.java Mon Jan 20 12:12:07 2014 -0800 @@ -100,6 +100,7 @@ public static final int ERROR_INVALID_LEVEL = 124; public static final int ERROR_DIR_NOT_EMPTY = 145; public static final int ERROR_ALREADY_EXISTS = 183; + public static final int ERROR_MORE_DATA = 234; public static final int ERROR_DIRECTORY = 267; public static final int ERROR_NOTIFY_ENUM_DIR = 1022; public static final int ERROR_NONE_MAPPED = 1332;
--- a/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Mon Jan 20 12:12:07 2014 -0800 @@ -973,19 +973,19 @@ * HANDLE CreateIoCompletionPort ( * HANDLE FileHandle, * HANDLE ExistingCompletionPort, - * DWORD CompletionKey, + * ULONG_PTR CompletionKey, * DWORD NumberOfConcurrentThreads * ) */ static native long CreateIoCompletionPort(long fileHandle, long existingPort, - int completionKey) throws WindowsException; + long completionKey) throws WindowsException; /** * GetQueuedCompletionStatus( * HANDLE CompletionPort, * LPDWORD lpNumberOfBytesTransferred, - * LPDWORD lpCompletionKey, + * PULONG_PTR lpCompletionKey, * LPOVERLAPPED *lpOverlapped, * DWORD dwMilliseconds */ @@ -999,12 +999,12 @@ static class CompletionStatus { private int error; private int bytesTransferred; - private int completionKey; + private long completionKey; private CompletionStatus() { } int error() { return error; } int bytesTransferred() { return bytesTransferred; } - int completionKey() { return completionKey; } + long completionKey() { return completionKey; } } private static native void GetQueuedCompletionStatus0(long completionPort, CompletionStatus status) throws WindowsException; @@ -1013,12 +1013,12 @@ * PostQueuedCompletionStatus( * HANDLE CompletionPort, * DWORD dwNumberOfBytesTransferred, - * DWORD dwCompletionKey, + * ULONG_PTR dwCompletionKey, * LPOVERLAPPED lpOverlapped * ) */ static native void PostQueuedCompletionStatus(long completionPort, - int completionKey) throws WindowsException; + long completionKey) throws WindowsException; /** * ReadDirectoryChangesW(
--- a/src/windows/classes/sun/nio/fs/WindowsWatchService.java Thu Jan 16 11:52:13 2014 -0800 +++ b/src/windows/classes/sun/nio/fs/WindowsWatchService.java Mon Jan 20 12:12:07 2014 -0800 @@ -41,6 +41,7 @@ class WindowsWatchService extends AbstractWatchService { + private final static int WAKEUP_COMPLETION_KEY = 0; private final Unsafe unsafe = Unsafe.getUnsafe(); // background thread to service I/O completion port @@ -83,7 +84,7 @@ */ private class WindowsWatchKey extends AbstractWatchKey { // file key (used to detect existing registrations) - private FileKey fileKey; + private final FileKey fileKey; // handle to directory private volatile long handle = INVALID_HANDLE_VALUE; @@ -223,8 +224,7 @@ FileKey other = (FileKey)obj; if (this.volSerialNumber != other.volSerialNumber) return false; if (this.fileIndexHigh != other.fileIndexHigh) return false; - if (this.fileIndexLow != other.fileIndexLow) return false; - return true; + return this.fileIndexLow == other.fileIndexLow; } } @@ -268,6 +268,7 @@ private static final short OFFSETOF_FILENAME = 12; // size of per-directory buffer for events (FIXME - make this configurable) + // Need to be less than 4*16384 = 65536. DWORD align. private static final int CHANGES_BUFFER_SIZE = 16 * 1024; private final WindowsFileSystem fs; @@ -275,27 +276,28 @@ private final long port; // maps completion key to WatchKey - private final Map<Integer,WindowsWatchKey> int2key; + private final Map<Integer,WindowsWatchKey> ck2key; // maps file key to WatchKey private final Map<FileKey,WindowsWatchKey> fk2key; // unique completion key for each directory + // native completion key capacity is 64 bits on Win64. private int lastCompletionKey; Poller(WindowsFileSystem fs, WindowsWatchService watcher, long port) { this.fs = fs; this.watcher = watcher; this.port = port; - this.int2key = new HashMap<Integer,WindowsWatchKey>(); - this.fk2key = new HashMap<FileKey,WindowsWatchKey>(); + this.ck2key = new HashMap<>(); + this.fk2key = new HashMap<>(); this.lastCompletionKey = 0; } @Override void wakeup() throws IOException { try { - PostQueuedCompletionStatus(port, 0); + PostQueuedCompletionStatus(port, WAKEUP_COMPLETION_KEY); } catch (WindowsException x) { throw new IOException(x.getMessage()); } @@ -322,7 +324,6 @@ for (WatchEvent.Modifier modifier: modifiers) { if (modifier == ExtendedWatchEventModifier.FILE_TREE) { watchSubtree = true; - continue; } else { if (modifier == null) return new NullPointerException(); @@ -333,7 +334,7 @@ } // open directory - long handle = -1L; + long handle; try { handle = CreateFile(dir.getPathForWin32Calls(), FILE_LIST_DIRECTORY, @@ -347,7 +348,7 @@ boolean registered = false; try { // read attributes and check file is a directory - WindowsFileAttributes attrs = null; + WindowsFileAttributes attrs; try { attrs = WindowsFileAttributes.readAttributes(handle); } catch (WindowsException x) { @@ -370,9 +371,10 @@ return existing; } - // unique completion key (skip 0) + // Can overflow the int type capacity. + // Skip WAKEUP_COMPLETION_KEY value. int completionKey = ++lastCompletionKey; - if (completionKey == 0) + if (completionKey == WAKEUP_COMPLETION_KEY) completionKey = ++lastCompletionKey; // associate handle with completion port @@ -418,13 +420,13 @@ // 1. remove mapping from old completion key to existing watch key // 2. release existing key's resources (handle/buffer) // 3. re-initialize key with new handle/buffer - int2key.remove(existing.completionKey()); + ck2key.remove(existing.completionKey()); existing.releaseResources(); watchKey = existing.init(handle, events, watchSubtree, buffer, countAddress, overlappedAddress, completionKey); } // map completion map to watch key - int2key.put(completionKey, watchKey); + ck2key.put(completionKey, watchKey); registered = true; return watchKey; @@ -440,7 +442,7 @@ WindowsWatchKey key = (WindowsWatchKey)obj; if (key.isValid()) { fk2key.remove(key.fileKey()); - int2key.remove(key.completionKey()); + ck2key.remove(key.completionKey()); key.invalidate(); } } @@ -449,11 +451,11 @@ @Override void implCloseAll() { // cancel all keys - for (Map.Entry<Integer,WindowsWatchKey> entry: int2key.entrySet()) { + for (Map.Entry<Integer, WindowsWatchKey> entry: ck2key.entrySet()) { entry.getValue().invalidate(); } fk2key.clear(); - int2key.clear(); + ck2key.clear(); // close I/O completion port CloseHandle(port); @@ -517,7 +519,7 @@ @Override public void run() { for (;;) { - CompletionStatus info = null; + CompletionStatus info; try { info = GetQueuedCompletionStatus(port); } catch (WindowsException x) { @@ -527,7 +529,7 @@ } // wakeup - if (info.completionKey() == 0) { + if (info.completionKey() == WAKEUP_COMPLETION_KEY) { boolean shutdown = processRequests(); if (shutdown) { return; @@ -536,7 +538,7 @@ } // map completionKey to get WatchKey - WindowsWatchKey key = int2key.get(info.completionKey()); + WindowsWatchKey key = ck2key.get((int)info.completionKey()); if (key == null) { // We get here when a registration is changed. In that case // the directory is closed which causes an event with the @@ -544,38 +546,44 @@ continue; } - // ReadDirectoryChangesW failed - if (info.error() != 0) { + boolean criticalError = false; + int errorCode = info.error(); + int messageSize = info.bytesTransferred(); + if (errorCode == ERROR_NOTIFY_ENUM_DIR) { // buffer overflow - if (info.error() == ERROR_NOTIFY_ENUM_DIR) { - key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); - } else { - // other error so cancel key - implCancelKey(key); - key.signal(); - } - continue; - } + key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); + } else if (errorCode != 0 && errorCode != ERROR_MORE_DATA) { + // ReadDirectoryChangesW failed + criticalError = true; + } else { + // ERROR_MORE_DATA is a warning about incomplite + // data transfer over TCP/UDP stack. For the case + // [messageSize] is zero in the most of cases. - // process the events - if (info.bytesTransferred() > 0) { - processEvents(key, info.bytesTransferred()); - } else { - // insufficient buffer size - key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); - } + if (messageSize > 0) { + // process non-empty events. + processEvents(key, messageSize); + } else if (errorCode == 0) { + // insufficient buffer size + // not described, but can happen. + key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); + } - // start read for next batch of changes - try { - ReadDirectoryChangesW(key.handle(), - key.buffer().address(), - CHANGES_BUFFER_SIZE, - key.watchSubtree(), - ALL_FILE_NOTIFY_EVENTS, - key.countAddress(), - key.overlappedAddress()); - } catch (WindowsException x) { - // no choice but to cancel key + // start read for next batch of changes + try { + ReadDirectoryChangesW(key.handle(), + key.buffer().address(), + CHANGES_BUFFER_SIZE, + key.watchSubtree(), + ALL_FILE_NOTIFY_EVENTS, + key.countAddress(), + key.overlappedAddress()); + } catch (WindowsException x) { + // no choice but to cancel key + criticalError = true; + } + } + if (criticalError) { implCancelKey(key); key.signal(); }
--- a/src/windows/native/sun/nio/ch/SocketDispatcher.c Thu Jan 16 11:52:13 2014 -0800 +++ b/src/windows/native/sun/nio/ch/SocketDispatcher.c Mon Jan 20 12:12:07 2014 -0800 @@ -192,45 +192,66 @@ jobject fdo, jlong address, jint len) { /* set up */ - int i = 0; + int next_index, next_offset, ret=0; DWORD written = 0; jint fd = fdval(env, fdo); struct iovec *iovp = (struct iovec *)address; WSABUF *bufs = malloc(len * sizeof(WSABUF)); - jint rem = MAX_BUFFER_SIZE; + jlong count = 0; if (bufs == 0) { JNU_ThrowOutOfMemoryError(env, 0); return IOS_THROWN; } - /* copy iovec into WSABUF */ - for(i=0; i<len; i++) { - jint iov_len = iovp[i].iov_len; - if (iov_len > rem) - iov_len = rem; - bufs[i].buf = (char *)iovp[i].iov_base; - bufs[i].len = (u_long)iov_len; - rem -= iov_len; - if (rem == 0) { - len = i+1; + // next buffer and offset to consume + next_index = 0; + next_offset = 0; + + while (next_index < len) { + DWORD buf_count = 0; + + /* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */ + jint rem = MAX_BUFFER_SIZE; + while (next_index < len && rem > 0) { + jint iov_len = iovp[next_index].iov_len - next_offset; + char* ptr = (char *)iovp[next_index].iov_base; + ptr += next_offset; + if (iov_len > rem) { + iov_len = rem; + next_offset += rem; + } else { + next_index ++; + next_offset = 0; + } + + bufs[buf_count].buf = ptr; + bufs[buf_count].len = (u_long)iov_len; + buf_count++; + + rem -= iov_len; + } + + /* write the buffers */ + ret = WSASend((SOCKET)fd, /* Socket */ + bufs, /* pointers to the buffers */ + buf_count, /* number of buffers to process */ + &written, /* receives number of bytes written */ + 0, /* no flags */ + 0, /* no overlapped sockets */ + 0); /* no completion routine */ + + if (ret == SOCKET_ERROR) { break; } + + count += written; } - /* read into the buffers */ - i = WSASend((SOCKET)fd, /* Socket */ - bufs, /* pointers to the buffers */ - (DWORD)len, /* number of buffers to process */ - &written, /* receives number of bytes written */ - 0, /* no flags */ - 0, /* no overlapped sockets */ - 0); /* no completion routine */ - /* clean up */ free(bufs); - if (i != 0) { + if (ret == SOCKET_ERROR && count == 0) { int theErr = (jint)WSAGetLastError(); if (theErr == WSAEWOULDBLOCK) { return IOS_UNAVAILABLE; @@ -239,7 +260,7 @@ return IOS_THROWN; } - return convertLongReturnVal(env, (jlong)written, JNI_FALSE); + return convertLongReturnVal(env, count, JNI_FALSE); } JNIEXPORT void JNICALL
--- a/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Thu Jan 16 11:52:13 2014 -0800 +++ b/src/windows/native/sun/nio/fs/WindowsNativeDispatcher.c Mon Jan 20 12:12:07 2014 -0800 @@ -162,7 +162,7 @@ } completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I"); completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I"); - completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I"); + completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "J"); clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult"); if (clazz == NULL) { @@ -1169,12 +1169,11 @@ JNIEXPORT jlong JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this, - jlong fileHandle, jlong existingPort, jint completionKey) + jlong fileHandle, jlong existingPort, jlong completionKey) { - ULONG_PTR ck = completionKey; HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle), (HANDLE)jlong_to_ptr(existingPort), - ck, + (ULONG_PTR)completionKey, 0); if (port == NULL) { throwWindowsException(env, GetLastError()); @@ -1203,21 +1202,20 @@ (*env)->SetIntField(env, obj, completionStatus_error, ioResult); (*env)->SetIntField(env, obj, completionStatus_bytesTransferred, (jint)bytesTransferred); - (*env)->SetIntField(env, obj, completionStatus_completionKey, - (jint)completionKey); - + (*env)->SetLongField(env, obj, completionStatus_completionKey, + (jlong)completionKey); } } JNIEXPORT void JNICALL Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv* env, jclass this, - jlong completionPort, jint completionKey) + jlong completionPort, jlong completionKey) { BOOL res; res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort), (DWORD)0, /* dwNumberOfBytesTransferred */ - (DWORD)completionKey, + (ULONG_PTR)completionKey, NULL); /* lpOverlapped */ if (res == 0) { throwWindowsException(env, GetLastError()); @@ -1232,7 +1230,17 @@ BOOL res; BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE; - ((LPOVERLAPPED)jlong_to_ptr(pOverlapped))->hEvent = NULL; + /* Any unused members of [OVERLAPPED] structure should always be initialized to zero + before the structure is used in a function call. + Otherwise, the function may fail and return ERROR_INVALID_PARAMETER. + http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx + + The [Offset] and [OffsetHigh] members of this structure are not used. + http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx + + [hEvent] should be zero, other fields are the return values. */ + ZeroMemory((LPOVERLAPPED)jlong_to_ptr(pOverlapped), sizeof(OVERLAPPED)); + res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory), (LPVOID)jlong_to_ptr(bufferAddress), (DWORD)bufferLength,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/invoke/8009222/Test8009222.java Mon Jan 20 12:12:07 2014 -0800 @@ -0,0 +1,49 @@ +/* + * 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. + * + * 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 8009222 + * @summary java.lang.IllegalArgumentException: not invocable, no method type + * when attempting to get getter method handle for a static field + * + * @run main/othervm Test8009222 + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +interface Intf { + static int i = 0; +} + +public class Test8009222 { + public static void main(String[] args) throws Exception { + MethodHandles.lookup() + .findStaticGetter(Intf.class, "i", int.class) + .getClass(); // null check + + System.out.println("TEST PASSED"); + } +}
--- a/test/java/nio/channels/SocketChannel/ShortWrite.java Thu Jan 16 11:52:13 2014 -0800 +++ b/test/java/nio/channels/SocketChannel/ShortWrite.java Mon Jan 20 12:12:07 2014 -0800 @@ -22,7 +22,7 @@ */ /* @test - * @bug 7176630 + * @bug 7176630 7074436 * @summary Check for short writes on SocketChannels configured in blocking mode */ @@ -40,9 +40,10 @@ /** * Returns a checksum on the remaining bytes in the given buffer. */ - static long computeChecksum(ByteBuffer bb) { + static long computeChecksum(ByteBuffer... bufs) { CRC32 crc32 = new CRC32(); - crc32.update(bb.array()); + for (int i=0; i<bufs.length; i++) + crc32.update(bufs[i].array()); return crc32.getValue(); } @@ -71,15 +72,15 @@ } /** - * Run test with a write of the given number of bytes. + * Exercise write(ByteBuffer) with given number of bytes. */ - static void test(ExecutorService pool, - SocketChannel source, - SocketChannel sink, - int size) + static void test1(ExecutorService pool, + SocketChannel source, + SocketChannel sink, + int size) throws Exception { - System.out.println(size); + System.out.println("write(ByteBuffer), size=" + size); // random bytes in the buffer ByteBuffer buf = ByteBuffer.allocate(size); @@ -101,6 +102,47 @@ throw new RuntimeException("Checksum did not match"); } + /** + * Exercise write(ByteBuffer[]) with buffers of the given sizes. + */ + static void testN(ExecutorService pool, + SocketChannel source, + SocketChannel sink, + int... sizes) + throws Exception + { + System.out.print("write(ByteBuffer[]), sizes="); + for (int size: sizes) + System.out.print(size + " "); + System.out.println(); + + int total = 0; + int len = sizes.length; + ByteBuffer[] bufs = new ByteBuffer[len]; + for (int i=0; i<len; i++) { + int size = sizes[i]; + ByteBuffer buf = ByteBuffer.allocate(size); + rand.nextBytes(buf.array()); + bufs[i] = buf; + total += size; + } + + // submit task to read the bytes + Future<Long> result = pool.submit(new Reader(sink, total)); + + // write the bytes + long n = source.write(bufs); + if (n != total) + throw new RuntimeException("Short write detected"); + + // check the bytes that were received match + for (int i=0; i<len; i++) + bufs[i].rewind(); + long expected = computeChecksum(bufs); + long actual = result.get(); + if (actual != expected) + throw new RuntimeException("Checksum did not match"); + } public static void main(String[] args) throws Exception { ExecutorService pool = Executors.newSingleThreadExecutor(); @@ -114,17 +156,47 @@ try (SocketChannel source = SocketChannel.open(sa); SocketChannel sink = ssc.accept()) { - // run tests on sizes around 128k as that is the problem - // area on Windows. + // Exercise write(BufferBuffer) on sizes around 128k int BOUNDARY = 128 * 1024; for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) { - test(pool, source, sink, size); + test1(pool, source, sink, size); + } + + // Exercise write(BufferBuffer) on random sizes + for (int i=0; i<20; i++) { + int size = rand.nextInt(1024*1024); + test1(pool, source, sink, size); } - // run tests on random sizes + // Exercise write(BufferBuffer[]) on sizes around 128k + for (int i=BOUNDARY-2; i<=BOUNDARY+2; i++) { + testN(pool, source, sink, i); + testN(pool, source, sink, 0, i); + testN(pool, source, sink, i, 0); + for (int j=BOUNDARY-2; j<=BOUNDARY+2; j++) { + testN(pool, source, sink, i, j); + testN(pool, source, sink, 0, i, j); + testN(pool, source, sink, i, 0, j); + testN(pool, source, sink, i, j, 0); + for (int k=BOUNDARY-2; k<=BOUNDARY+2; k++) { + testN(pool, source, sink, i, j, k); + testN(pool, source, sink, 0, i, j, k); + testN(pool, source, sink, i, 0, j, k); + testN(pool, source, sink, i, j, 0, k); + testN(pool, source, sink, i, j, k, 0); + } + } + } + + // Exercise write(BufferBuffer[]) on random sizes + // (assumes IOV_MAX >= 8) for (int i=0; i<20; i++) { - int size = rand.nextInt(1024*1024); - test(pool, source, sink, size); + int n = rand.nextInt(9); + int[] sizes = new int[n]; + for (int j=0; j<n; j++) { + sizes[j] = rand.nextInt(1024*1024); + } + testN(pool, source, sink, sizes); } } }
--- a/test/java/nio/file/Files/BytesAndLines.java Thu Jan 16 11:52:13 2014 -0800 +++ b/test/java/nio/file/Files/BytesAndLines.java Mon Jan 20 12:12:07 2014 -0800 @@ -22,7 +22,9 @@ */ /* @test - * @bug 7006126 8020669 + * @bug 7006126 8020669 8024788 + * @build BytesAndLines PassThroughFileSystem + * @run main BytesAndLines * @summary Unit test for methods for Files readAllBytes, readAllLines and * and write methods. */ @@ -92,6 +94,16 @@ byte[] data = Files.readAllBytes(pathStat); assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read"); } + + // test readAllBytes on custom file system + Path myfile = PassThroughFileSystem.create().getPath(file.toString()); + for (int size=0; size<=1024; size+=512) { + byte[] b1 = new byte[size]; + rand.nextBytes(b1); + Files.write(myfile, b1); + byte[] b2 = Files.readAllBytes(myfile); + assertTrue(Arrays.equals(b1, b2), "bytes not equal"); + } }
--- a/test/java/util/logging/TestAppletLoggerContext.java Thu Jan 16 11:52:13 2014 -0800 +++ b/test/java/util/logging/TestAppletLoggerContext.java Mon Jan 20 12:12:07 2014 -0800 @@ -110,28 +110,19 @@ } TestExc exc; - TestExc global = new TestExc(); @Override - public Object getContext() { return active ? global : null; } - @Override - public Object getExecutionContext() { return active ? exc : null; } + public Object getAppletContext() { return active ? exc : null; } @Override - public Object get(Object o, Object o1) { return TestExc.exc(o).get(o1); } - @Override - public void put(Object o, Object o1, Object o2) { TestExc.exc(o).put(o1, o2); } + public Object get(Object o) { return exc.get(o); } @Override - public void remove(Object o, Object o1) { TestExc.exc(o).remove(o1); } - @Override - public Object get(Object o) { return global.get(o); } + public void put(Object o, Object o1) { exc.put(o, o1); } @Override - public void put(Object o, Object o1) { global.put(o, o1); } - @Override - public void remove(Object o) { global.remove(o); } + public void remove(Object o) { exc.remove(o); } @Override public boolean isDisposed() { return false; } @Override - public boolean isMainAppContext() { return exc == null; } + public boolean isMainAppContext() { return !active || exc == null; } } final static JavaAWTAccessStub javaAwtAccess = new JavaAWTAccessStub();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestLoggingWithMainAppContext.java Mon Jan 20 12:12:07 2014 -0800 @@ -0,0 +1,75 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.logging.Logger; +import javax.imageio.ImageIO; + +/** + * @test + * @bug 8019853 8023258 + * @summary Test that the default user context is used when in the main + * application context. This test must not be run in same VM or agent + * VM mode: it would not test the intended behavior. + * @run main/othervm TestLoggingWithMainAppContext + */ +public class TestLoggingWithMainAppContext { + + public static void main(String[] args) throws IOException { + System.out.println("Creating loggers."); + + // These loggers will be created in the default user context. + final Logger foo1 = Logger.getLogger( "foo" ); + final Logger bar1 = Logger.getLogger( "foo.bar" ); + if (bar1.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar1 "+bar1+" is not "+foo1); + } + System.out.println("bar1.getParent() is the same as foo1"); + + // Set a security manager + System.setSecurityManager(new SecurityManager()); + System.out.println("Now running with security manager"); + + // Triggers the creation of the main AppContext + ByteArrayInputStream is = new ByteArrayInputStream(new byte[] { 0, 1 }); + ImageIO.read(is); // triggers calls to system loggers & creation of main AppContext + + // verify that we're still using the default user context + final Logger bar2 = Logger.getLogger( "foo.bar" ); + if (bar1 != bar2) { + throw new RuntimeException("bar2 "+bar2+" is not the same as bar1 "+bar1); + } + System.out.println("bar2 is the same as bar1"); + if (bar2.getParent() != foo1) { + throw new RuntimeException("Parent logger of bar2 "+bar2+" is not foo1 "+foo1); + } + System.out.println("bar2.getParent() is the same as foo1"); + final Logger foo2 = Logger.getLogger("foo"); + if (foo1 != foo2) { + throw new RuntimeException("foo2 "+foo2+" is not the same as foo1 "+foo1); + } + System.out.println("foo2 is the same as foo1"); + + System.out.println("Test passed."); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/TestMainAppContext.java Mon Jan 20 12:12:07 2014 -0800 @@ -0,0 +1,85 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.logging.Logger; +import sun.awt.AppContext; +import sun.awt.SunToolkit; + + +/** + * @test + * @bug 8026404 + * @summary checks that calling getLogger() from a Thread whose ThreadGroup is + * a child of the main root group doesn't throw an exception. + * @build TestMainAppContext + * @run main/othervm TestMainAppContext + * @author danielfuchs + */ +public class TestMainAppContext { + + static volatile Throwable thrown = null; + + public static void main(String... args) throws Exception { + ThreadGroup rootTG = Thread.currentThread().getThreadGroup(); + while (rootTG.getParent() != null) { + rootTG = rootTG.getParent(); + } + + ThreadGroup tg = new ThreadGroup(rootTG, "FakeApplet"); + final Thread t1 = new Thread(tg, "createNewAppContext") { + @Override + public void run() { + try { + AppContext context = SunToolkit.createNewAppContext(); + } catch(Throwable t) { + thrown = t; + } + } + }; + t1.start(); + t1.join(); + if (thrown != null) { + throw new RuntimeException("Unexpected exception: " + thrown, thrown); + } + Thread t2 = new Thread(tg, "BugDetector") { + + @Override + public void run() { + try { + Logger.getLogger("foo").info("Done"); + } catch (Throwable x) { + thrown = x; + } + } + + }; + + System.setSecurityManager(new SecurityManager()); + t2.start(); + t2.join(); + if (thrown != null) { + throw new RuntimeException("Test failed: " + thrown, thrown); + } + + } + +}