changeset 17361:34edf4a843e9

Merge
author acorn
date Wed, 27 Jul 2016 13:33:55 +0000
parents a2db48b68fa1 c484a3509a54
children 52b9765c780e dd56fbbb2527
files
diffstat 32 files changed, 1508 insertions(+), 404 deletions(-) [+]
line wrap: on
line diff
--- a/make/lib/Awt2dLibraries.gmk	Wed Jul 27 08:33:15 2016 -0400
+++ b/make/lib/Awt2dLibraries.gmk	Wed Jul 27 13:33:55 2016 +0000
@@ -350,8 +350,6 @@
       BUILD_LIBAWT_XAWT_awt_Font.c_CFLAGS := -w
       # initializing a declared 'extern'
       BUILD_LIBAWT_XAWT_debug_mem.c_CFLAGS := -w
-      # decimal constant is unsigned only in ISO C90 (JAVASE_EMBEDDED)
-      BUILD_LIBAWT_XAWT_XToolkit.c_CFLAGS := -w
    endif
 
     $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_XAWT, \
--- a/src/java.base/share/classes/java/lang/VersionProps.java.template	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/lang/VersionProps.java.template	Wed Jul 27 13:33:55 2016 +0000
@@ -166,10 +166,6 @@
 
         ps.print(java_runtime_name + " (" + jdk_debug_level + "build " + java_runtime_version);
 
-        if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) {
-            // embedded builds report headless state
-            ps.print(", headless");
-        }
         ps.println(')');
 
         /* Third line: JVM information. */
--- a/src/java.base/share/classes/java/net/URLPermission.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/net/URLPermission.java	Wed Jul 27 13:33:55 2016 +0000
@@ -461,11 +461,10 @@
     }
 
     private String actions() {
-        String b = String.join(",", methods);
-        if (!requestHeaders.isEmpty()) {
-            b += ":" + String.join(",", requestHeaders);
-        }
-        return b;
+        // The colon separator is optional when the request headers list is
+        // empty.This implementation chooses to include it even when the request
+        // headers list is empty.
+        return String.join(",", methods) + ":" + String.join(",", requestHeaders);
     }
 
     /**
--- a/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Wed Jul 27 13:33:55 2016 +0000
@@ -221,7 +221,10 @@
      *   across both while pushing actions.  The second completion is
      *   a CoCompletion pointing to the first, shared so that at most
      *   one performs the action.  The multiple-arity methods allOf
-     *   and anyOf do this pairwise to form trees of completions.
+     *   does this pairwise to form trees of completions.  Method
+     *   anyOf is handled differently from allOf because completion of
+     *   any source should trigger a cleanStack of other sources.
+     *   Each AnyOf completion can reach others via a shared array.
      *
      * Note that the generic type parameters of methods vary according
      * to whether "this" is a source, dependent, or completion.
@@ -588,9 +591,9 @@
     }
 
     /**
-     * Post-processing by dependent after successful UniCompletion
-     * tryFire.  Tries to clean stack of source a, and then either runs
-     * postComplete or returns this to caller, depending on mode.
+     * Post-processing by dependent after successful UniCompletion tryFire.
+     * Tries to clean stack of source a, and then either runs postComplete
+     * or returns this to caller, depending on mode.
      */
     final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
         if (a != null && a.stack != null) {
@@ -1003,12 +1006,12 @@
     }
 
     @SuppressWarnings("serial")
-    static final class UniRelay<T> extends UniCompletion<T,T> {
-        UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
+    static final class UniRelay<U, T extends U> extends UniCompletion<T,U> {
+        UniRelay(CompletableFuture<U> dep, CompletableFuture<T> src) {
             super(null, dep, src);
         }
-        final CompletableFuture<T> tryFire(int mode) {
-            CompletableFuture<T> d; CompletableFuture<T> a; Object r;
+        final CompletableFuture<U> tryFire(int mode) {
+            CompletableFuture<U> d; CompletableFuture<T> a; Object r;
             if ((d = dep) == null
                 || (a = src) == null || (r = a.result) == null)
                 return null;
@@ -1019,13 +1022,14 @@
         }
     }
 
-    private CompletableFuture<T> uniCopyStage() {
+    private static <U, T extends U> CompletableFuture<U> uniCopyStage(
+        CompletableFuture<T> src) {
         Object r;
-        CompletableFuture<T> d = newIncompleteFuture();
-        if ((r = result) != null)
+        CompletableFuture<U> d = src.newIncompleteFuture();
+        if ((r = src.result) != null)
             d.result = encodeRelay(r);
         else
-            unipush(new UniRelay<T>(d, this));
+            src.unipush(new UniRelay<U,T>(d, src));
         return d;
     }
 
@@ -1034,7 +1038,7 @@
         if ((r = result) != null)
             return new MinimalStage<T>(encodeRelay(r));
         MinimalStage<T> d = new MinimalStage<T>();
-        unipush(new UniRelay<T>(d, this));
+        unipush(new UniRelay<T,T>(d, this));
         return d;
     }
 
@@ -1069,7 +1073,7 @@
                     if ((r = g.result) != null)
                         d.completeRelay(r);
                     else {
-                        g.unipush(new UniRelay<V>(d, g));
+                        g.unipush(new UniRelay<V,V>(d, g));
                         if (d.result == null)
                             return null;
                     }
@@ -1103,7 +1107,7 @@
                 if ((s = g.result) != null)
                     d.result = encodeRelay(s);
                 else {
-                    g.unipush(new UniRelay<V>(d, g));
+                    g.unipush(new UniRelay<V,V>(d, g));
                 }
             } catch (Throwable ex) {
                 d.result = encodeThrowable(ex);
@@ -1637,45 +1641,40 @@
         return d;
     }
 
+    /** Completion for an anyOf input future. */
     @SuppressWarnings("serial")
-    static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
-        OrRelay(CompletableFuture<Object> dep,
-                CompletableFuture<T> src, CompletableFuture<U> snd) {
-            super(null, dep, src, snd);
+    static class AnyOf extends Completion {
+        CompletableFuture<Object> dep; CompletableFuture<?> src;
+        CompletableFuture<?>[] srcs;
+        AnyOf(CompletableFuture<Object> dep, CompletableFuture<?> src,
+              CompletableFuture<?>[] srcs) {
+            this.dep = dep; this.src = src; this.srcs = srcs;
         }
         final CompletableFuture<Object> tryFire(int mode) {
-            CompletableFuture<Object> d;
-            CompletableFuture<T> a;
-            CompletableFuture<U> b;
+            // assert mode != ASYNC;
+            CompletableFuture<Object> d; CompletableFuture<?> a;
+            CompletableFuture<?>[] as;
             Object r;
             if ((d = dep) == null
-                || (a = src) == null || (b = snd) == null
-                || ((r = a.result) == null && (r = b.result) == null))
+                || (a = src) == null || (r = a.result) == null
+                || (as = srcs) == null)
                 return null;
-            d.completeRelay(r);
-            src = null; snd = null; dep = null;
-            return d.postFire(a, b, mode);
+            dep = null; src = null; srcs = null;
+            if (d.completeRelay(r)) {
+                for (CompletableFuture<?> b : as)
+                    if (b != a)
+                        b.cleanStack();
+                if (mode < 0)
+                    return d;
+                else
+                    d.postComplete();
+            }
+            return null;
         }
-    }
-
-    /** Recursively constructs a tree of completions. */
-    static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
-                                            int lo, int hi) {
-        CompletableFuture<Object> d = new CompletableFuture<Object>();
-        if (lo <= hi) {
-            CompletableFuture<?> a, b; Object r;
-            int mid = (lo + hi) >>> 1;
-            if ((a = (lo == mid ? cfs[lo] :
-                      orTree(cfs, lo, mid))) == null ||
-                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
-                      orTree(cfs, mid+1, hi))) == null)
-                throw new NullPointerException();
-            if ((r = a.result) != null && (r = b.result) != null)
-                d.result = encodeRelay(r);
-            else
-                a.orpush(b, new OrRelay<>(d, a, b));
+        final boolean isLive() {
+            CompletableFuture<Object> d;
+            return (d = dep) != null && d.result == null;
         }
-        return d;
     }
 
     /* ------------- Zero-input Async forms -------------- */
@@ -2354,7 +2353,28 @@
      * {@code null}
      */
     public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
-        return orTree(cfs, 0, cfs.length - 1);
+        int n; Object r;
+        if ((n = cfs.length) <= 1)
+            return (n == 0)
+                ? new CompletableFuture<Object>()
+                : uniCopyStage(cfs[0]);
+        for (CompletableFuture<?> cf : cfs)
+            if ((r = cf.result) != null)
+                return new CompletableFuture<Object>(encodeRelay(r));
+        cfs = cfs.clone();
+        CompletableFuture<Object> d = new CompletableFuture<>();
+        for (CompletableFuture<?> cf : cfs)
+            cf.unipush(new AnyOf(d, cf, cfs));
+        // If d was completed while we were adding completions, we should
+        // clean the stack of any sources that may have had completions
+        // pushed on their stack after d was completed.
+        if (d.result != null)
+            for (int i = 0, len = cfs.length; i < len; i++)
+                if (cfs[i].result != null)
+                    for (i++; i < len; i++)
+                        if (cfs[i].result == null)
+                            cfs[i].cleanStack();
+        return d;
     }
 
     /* ------------- Control and status methods -------------- */
@@ -2526,7 +2546,7 @@
      * @since 9
      */
     public CompletableFuture<T> copy() {
-        return uniCopyStage();
+        return uniCopyStage(this);
     }
 
     /**
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1023,7 +1023,7 @@
         int hash = spread(key.hashCode());
         int binCount = 0;
         for (Node<K,V>[] tab = table;;) {
-            Node<K,V> f; int n, i, fh;
+            Node<K,V> f; int n, i, fh; K fk; V fv;
             if (tab == null || (n = tab.length) == 0)
                 tab = initTable();
             else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
@@ -1032,6 +1032,10 @@
             }
             else if ((fh = f.hash) == MOVED)
                 tab = helpTransfer(tab, f);
+            else if (onlyIfAbsent && fh == hash &&  // check first node
+                     ((fk = f.key) == key || fk != null && key.equals(fk)) &&
+                     (fv = f.val) != null)
+                return fv;
             else {
                 V oldVal = null;
                 synchronized (f) {
@@ -1702,7 +1706,7 @@
         V val = null;
         int binCount = 0;
         for (Node<K,V>[] tab = table;;) {
-            Node<K,V> f; int n, i, fh;
+            Node<K,V> f; int n, i, fh; K fk; V fv;
             if (tab == null || (n = tab.length) == 0)
                 tab = initTable();
             else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
@@ -1724,6 +1728,10 @@
             }
             else if ((fh = f.hash) == MOVED)
                 tab = helpTransfer(tab, f);
+            else if (fh == h &&                  // check first node
+                     ((fk = f.key) == key || fk != null && key.equals(fk)) &&
+                     (fv = f.val) != null)
+                return fv;
             else {
                 boolean added = false;
                 synchronized (f) {
@@ -4553,14 +4561,21 @@
             return true;
         }
 
-        public final boolean removeAll(Collection<?> c) {
+        public boolean removeAll(Collection<?> c) {
             if (c == null) throw new NullPointerException();
             boolean modified = false;
-            for (Iterator<E> it = iterator(); it.hasNext();) {
-                if (c.contains(it.next())) {
-                    it.remove();
-                    modified = true;
+            // Use (c instanceof Set) as a hint that lookup in c is as
+            // efficient as this view
+            if (c instanceof Set<?> && c.size() > map.table.length) {
+                for (Iterator<?> it = iterator(); it.hasNext(); ) {
+                    if (c.contains(it.next())) {
+                        it.remove();
+                        modified = true;
+                    }
                 }
+            } else {
+                for (Object e : c)
+                    modified |= remove(e);
             }
             return modified;
         }
@@ -4747,6 +4762,18 @@
             throw new UnsupportedOperationException();
         }
 
+        @Override public boolean removeAll(Collection<?> c) {
+            if (c == null) throw new NullPointerException();
+            boolean modified = false;
+            for (Iterator<V> it = iterator(); it.hasNext();) {
+                if (c.contains(it.next())) {
+                    it.remove();
+                    modified = true;
+                }
+            }
+            return modified;
+        }
+
         public boolean removeIf(Predicate<? super V> filter) {
             return map.removeValueIf(filter);
         }
--- a/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Wed Jul 27 13:33:55 2016 +0000
@@ -235,22 +235,16 @@
      * As is too common in this sort of code, methods are monolithic
      * because most of the logic relies on reads of fields that are
      * maintained as local variables so can't be nicely factored --
-     * mainly, here, bulky spin->yield->block/cancel code), and
-     * heavily dependent on intrinsics (VarHandles) to use inlined
-     * embedded CAS and related memory access operations (that tend
-     * not to be as readily inlined by dynamic compilers when they are
-     * hidden behind other methods that would more nicely name and
-     * encapsulate the intended effects). This includes the use of
-     * setRelease to clear fields of the per-thread Nodes between
-     * uses. Note that field Node.item is not declared as volatile
-     * even though it is read by releasing threads, because they only
-     * do so after CAS operations that must precede access, and all
-     * uses by the owning thread are otherwise acceptably ordered by
-     * other operations. (Because the actual points of atomicity are
-     * slot CASes, it would also be legal for the write to Node.match
-     * in a release to be weaker than a full volatile write. However,
-     * this is not done because it could allow further postponement of
-     * the write, delaying progress.)
+     * mainly, here, bulky spin->yield->block/cancel code.  Note that
+     * field Node.item is not declared as volatile even though it is
+     * read by releasing threads, because they only do so after CAS
+     * operations that must precede access, and all uses by the owning
+     * thread are otherwise acceptably ordered by other operations.
+     * (Because the actual points of atomicity are slot CASes, it
+     * would also be legal for the write to Node.match in a release to
+     * be weaker than a full volatile write. However, this is not done
+     * because it could allow further postponement of the write,
+     * delaying progress.)
      */
 
     /**
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Wed Jul 27 13:33:55 2016 +0000
@@ -35,7 +35,6 @@
 
 package java.util.concurrent.atomic;
 
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
 import java.util.function.IntBinaryOperator;
 import java.util.function.IntUnaryOperator;
@@ -54,11 +53,18 @@
  */
 public class AtomicInteger extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 6214790243416807050L;
-    private static final VarHandle VALUE;
+
+    /*
+     * This class intended to be implemented using VarHandles, but there
+     * are unresolved cyclic startup dependencies.
+     */
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
+
     static {
         try {
-            MethodHandles.Lookup l = MethodHandles.lookup();
-            VALUE = l.findVarHandle(AtomicInteger.class, "value", int.class);
+            VALUE = U.objectFieldOffset
+                (AtomicInteger.class.getDeclaredField("value"));
         } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
@@ -109,7 +115,7 @@
      * @since 1.6
      */
     public final void lazySet(int newValue) {
-        VALUE.setRelease(this, newValue);
+        U.putIntRelease(this, VALUE, newValue);
     }
 
     /**
@@ -120,7 +126,7 @@
      * @return the previous value
      */
     public final int getAndSet(int newValue) {
-        return (int)VALUE.getAndSet(this, newValue);
+        return U.getAndSetInt(this, VALUE, newValue);
     }
 
     /**
@@ -134,7 +140,7 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(int expectedValue, int newValue) {
-        return VALUE.compareAndSet(this, expectedValue, newValue);
+        return U.compareAndSwapInt(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -147,7 +153,7 @@
      * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(int expectedValue, int newValue) {
-        return VALUE.weakCompareAndSet(this, expectedValue, newValue);
+        return U.weakCompareAndSwapInt(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -159,7 +165,7 @@
      * @return the previous value
      */
     public final int getAndIncrement() {
-        return (int)VALUE.getAndAdd(this, 1);
+        return U.getAndAddInt(this, VALUE, 1);
     }
 
     /**
@@ -171,7 +177,7 @@
      * @return the previous value
      */
     public final int getAndDecrement() {
-        return (int)VALUE.getAndAdd(this, -1);
+        return U.getAndAddInt(this, VALUE, -1);
     }
 
     /**
@@ -182,7 +188,7 @@
      * @return the previous value
      */
     public final int getAndAdd(int delta) {
-        return (int)VALUE.getAndAdd(this, delta);
+        return U.getAndAddInt(this, VALUE, delta);
     }
 
     /**
@@ -194,7 +200,7 @@
      * @return the updated value
      */
     public final int incrementAndGet() {
-        return (int)VALUE.addAndGet(this, 1);
+        return U.getAndAddInt(this, VALUE, 1) + 1;
     }
 
     /**
@@ -206,7 +212,7 @@
      * @return the updated value
      */
     public final int decrementAndGet() {
-        return (int)VALUE.addAndGet(this, -1);
+        return U.getAndAddInt(this, VALUE, -1) - 1;
     }
 
     /**
@@ -217,7 +223,7 @@
      * @return the updated value
      */
     public final int addAndGet(int delta) {
-        return (int)VALUE.addAndGet(this, delta);
+        return U.getAndAddInt(this, VALUE, delta) + delta;
     }
 
     /**
@@ -373,7 +379,7 @@
      * @since 9
      */
     public final int getPlain() {
-        return (int)VALUE.get(this);
+        return U.getInt(this, VALUE);
     }
 
     /**
@@ -385,7 +391,7 @@
      * @since 9
      */
     public final void setPlain(int newValue) {
-        VALUE.set(this, newValue);
+        U.putInt(this, VALUE, newValue);
     }
 
     /**
@@ -396,7 +402,7 @@
      * @since 9
      */
     public final int getOpaque() {
-        return (int)VALUE.getOpaque(this);
+        return U.getIntOpaque(this, VALUE);
     }
 
     /**
@@ -407,7 +413,7 @@
      * @since 9
      */
     public final void setOpaque(int newValue) {
-        VALUE.setOpaque(this, newValue);
+        U.putIntOpaque(this, VALUE, newValue);
     }
 
     /**
@@ -418,7 +424,7 @@
      * @since 9
      */
     public final int getAcquire() {
-        return (int)VALUE.getAcquire(this);
+        return U.getIntAcquire(this, VALUE);
     }
 
     /**
@@ -429,7 +435,7 @@
      * @since 9
      */
     public final void setRelease(int newValue) {
-        VALUE.setRelease(this, newValue);
+        U.putIntRelease(this, VALUE, newValue);
     }
 
     /**
@@ -445,7 +451,7 @@
      * @since 9
      */
     public final int compareAndExchange(int expectedValue, int newValue) {
-        return (int)VALUE.compareAndExchange(this, expectedValue, newValue);
+        return U.compareAndExchangeIntVolatile(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -461,7 +467,7 @@
      * @since 9
      */
     public final int compareAndExchangeAcquire(int expectedValue, int newValue) {
-        return (int)VALUE.compareAndExchangeAcquire(this, expectedValue, newValue);
+        return U.compareAndExchangeIntAcquire(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -477,7 +483,7 @@
      * @since 9
      */
     public final int compareAndExchangeRelease(int expectedValue, int newValue) {
-        return (int)VALUE.compareAndExchangeRelease(this, expectedValue, newValue);
+        return U.compareAndExchangeIntRelease(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -492,7 +498,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetVolatile(int expectedValue, int newValue) {
-        return VALUE.weakCompareAndSetVolatile(this, expectedValue, newValue);
+        return U.weakCompareAndSwapIntVolatile(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -507,7 +513,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetAcquire(int expectedValue, int newValue) {
-        return VALUE.weakCompareAndSetAcquire(this, expectedValue, newValue);
+        return U.weakCompareAndSwapIntAcquire(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -522,7 +528,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetRelease(int expectedValue, int newValue) {
-        return VALUE.weakCompareAndSetRelease(this, expectedValue, newValue);
+        return U.weakCompareAndSwapIntRelease(this, VALUE, expectedValue, newValue);
     }
 
 }
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java	Wed Jul 27 13:33:55 2016 +0000
@@ -35,7 +35,6 @@
 
 package java.util.concurrent.atomic;
 
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
 import java.util.function.LongBinaryOperator;
 import java.util.function.LongUnaryOperator;
@@ -54,7 +53,6 @@
  */
 public class AtomicLong extends Number implements java.io.Serializable {
     private static final long serialVersionUID = 1927816293512124184L;
-    private static final VarHandle VALUE;
 
     /**
      * Records whether the underlying JVM supports lockless
@@ -70,10 +68,17 @@
      */
     private static native boolean VMSupportsCS8();
 
+    /*
+     * This class intended to be implemented using VarHandles, but there
+     * are unresolved cyclic startup dependencies.
+     */
+    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
+    private static final long VALUE;
+
     static {
         try {
-            MethodHandles.Lookup l = MethodHandles.lookup();
-            VALUE = l.findVarHandle(AtomicLong.class, "value", long.class);
+            VALUE = U.objectFieldOffset
+                (AtomicLong.class.getDeclaredField("value"));
         } catch (ReflectiveOperationException e) {
             throw new Error(e);
         }
@@ -113,7 +118,9 @@
      * @param newValue the new value
      */
     public final void set(long newValue) {
-        VALUE.setVolatile(this, newValue);
+        // Use putLongVolatile instead of ordinary volatile store when
+        // using compareAndSwapLong, for sake of some 32bit systems.
+        U.putLongVolatile(this, VALUE, newValue);
     }
 
     /**
@@ -124,7 +131,7 @@
      * @since 1.6
      */
     public final void lazySet(long newValue) {
-        VALUE.setRelease(this, newValue);
+        U.putLongRelease(this, VALUE, newValue);
     }
 
     /**
@@ -135,7 +142,7 @@
      * @return the previous value
      */
     public final long getAndSet(long newValue) {
-        return (long)VALUE.getAndSet(this, newValue);
+        return U.getAndSetLong(this, VALUE, newValue);
     }
 
     /**
@@ -149,7 +156,7 @@
      * the actual value was not equal to the expected value.
      */
     public final boolean compareAndSet(long expectedValue, long newValue) {
-        return VALUE.compareAndSet(this, expectedValue, newValue);
+        return U.compareAndSwapLong(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -162,7 +169,7 @@
      * @return {@code true} if successful
      */
     public final boolean weakCompareAndSet(long expectedValue, long newValue) {
-        return VALUE.weakCompareAndSet(this, expectedValue, newValue);
+        return U.weakCompareAndSwapLong(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -174,7 +181,7 @@
      * @return the previous value
      */
     public final long getAndIncrement() {
-        return (long)VALUE.getAndAdd(this, 1L);
+        return U.getAndAddLong(this, VALUE, 1L);
     }
 
     /**
@@ -186,7 +193,7 @@
      * @return the previous value
      */
     public final long getAndDecrement() {
-        return (long)VALUE.getAndAdd(this, -1L);
+        return U.getAndAddLong(this, VALUE, -1L);
     }
 
     /**
@@ -197,7 +204,7 @@
      * @return the previous value
      */
     public final long getAndAdd(long delta) {
-        return (long)VALUE.getAndAdd(this, delta);
+        return U.getAndAddLong(this, VALUE, delta);
     }
 
     /**
@@ -209,7 +216,7 @@
      * @return the updated value
      */
     public final long incrementAndGet() {
-        return (long)VALUE.addAndGet(this, 1L);
+        return U.getAndAddLong(this, VALUE, 1L) + 1L;
     }
 
     /**
@@ -221,7 +228,7 @@
      * @return the updated value
      */
     public final long decrementAndGet() {
-        return (long)VALUE.addAndGet(this, -1L);
+        return U.getAndAddLong(this, VALUE, -1L) - 1L;
     }
 
     /**
@@ -232,7 +239,7 @@
      * @return the updated value
      */
     public final long addAndGet(long delta) {
-        return (long)VALUE.addAndGet(this, delta);
+        return U.getAndAddLong(this, VALUE, delta) + delta;
     }
 
     /**
@@ -386,7 +393,7 @@
      * @since 9
      */
     public final long getPlain() {
-        return (long)VALUE.get(this);
+        return U.getLong(this, VALUE);
     }
 
     /**
@@ -398,7 +405,7 @@
      * @since 9
      */
     public final void setPlain(long newValue) {
-        VALUE.set(this, newValue);
+        U.putLong(this, VALUE, newValue);
     }
 
     /**
@@ -409,7 +416,7 @@
      * @since 9
      */
     public final long getOpaque() {
-        return (long)VALUE.getOpaque(this);
+        return U.getLongOpaque(this, VALUE);
     }
 
     /**
@@ -420,7 +427,7 @@
      * @since 9
      */
     public final void setOpaque(long newValue) {
-        VALUE.setOpaque(this, newValue);
+        U.putLongOpaque(this, VALUE, newValue);
     }
 
     /**
@@ -431,7 +438,7 @@
      * @since 9
      */
     public final long getAcquire() {
-        return (long)VALUE.getAcquire(this);
+        return U.getLongAcquire(this, VALUE);
     }
 
     /**
@@ -442,7 +449,7 @@
      * @since 9
      */
     public final void setRelease(long newValue) {
-        VALUE.setRelease(this, newValue);
+        U.putLongRelease(this, VALUE, newValue);
     }
 
     /**
@@ -458,7 +465,7 @@
      * @since 9
      */
     public final long compareAndExchange(long expectedValue, long newValue) {
-        return (long)VALUE.compareAndExchange(this, expectedValue, newValue);
+        return U.compareAndExchangeLongVolatile(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -474,7 +481,7 @@
      * @since 9
      */
     public final long compareAndExchangeAcquire(long expectedValue, long newValue) {
-        return (long)VALUE.compareAndExchangeAcquire(this, expectedValue, newValue);
+        return U.compareAndExchangeLongAcquire(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -490,7 +497,7 @@
      * @since 9
      */
     public final long compareAndExchangeRelease(long expectedValue, long newValue) {
-        return (long)VALUE.compareAndExchangeRelease(this, expectedValue, newValue);
+        return U.compareAndExchangeLongRelease(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -505,7 +512,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetVolatile(long expectedValue, long newValue) {
-        return VALUE.weakCompareAndSetVolatile(this, expectedValue, newValue);
+        return U.weakCompareAndSwapLongVolatile(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -520,7 +527,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetAcquire(long expectedValue, long newValue) {
-        return VALUE.weakCompareAndSetAcquire(this, expectedValue, newValue);
+        return U.weakCompareAndSwapLongAcquire(this, VALUE, expectedValue, newValue);
     }
 
     /**
@@ -535,7 +542,7 @@
      * @since 9
      */
     public final boolean weakCompareAndSetRelease(long expectedValue, long newValue) {
-        return VALUE.weakCompareAndSetRelease(this, expectedValue, newValue);
+        return U.weakCompareAndSwapLongRelease(this, VALUE, expectedValue, newValue);
     }
 
 }
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java	Wed Jul 27 13:33:55 2016 +0000
@@ -60,7 +60,7 @@
         }
     }
 
-    private volatile Object value;
+    private volatile V value;
 
     /**
      * Creates a new AtomicReference with the given initial value.
@@ -83,9 +83,8 @@
      *
      * @return the current value
      */
-    @SuppressWarnings("unchecked")
     public final V get() {
-        return (V)value;
+        return value;
     }
 
     /**
--- a/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Wed Jul 27 13:33:55 2016 +0000
@@ -256,8 +256,12 @@
      * method validate()) requires stricter ordering rules than apply
      * to normal volatile reads (of "state").  To force orderings of
      * reads before a validation and the validation itself in those
-     * cases where this is not already forced, we use
-     * VarHandle.acquireFence.
+     * cases where this is not already forced, we use acquireFence.
+     * Unlike in that paper, we allow writers to use plain writes.
+     * One would not expect reorderings of such writes with the lock
+     * acquisition CAS because there is a "control dependency", but it
+     * is theoretically possible, so we additionally add a
+     * storeStoreFence after lock acquisition CAS.
      *
      * The memory layout keeps lock state and queue pointers together
      * (normally on the same cache line). This usually works well for
@@ -355,6 +359,20 @@
         state = ORIGIN;
     }
 
+    private boolean casState(long expectedValue, long newValue) {
+        return STATE.compareAndSet(this, expectedValue, newValue);
+    }
+
+    private long tryWriteLock(long s) {
+        // assert (s & ABITS) == 0L;
+        long next;
+        if (casState(s, next = s | WBIT)) {
+            VarHandle.storeStoreFence();
+            return next;
+        }
+        return 0L;
+    }
+
     /**
      * Exclusively acquires the lock, blocking if necessary
      * until available.
@@ -363,10 +381,8 @@
      */
     @ReservedStackAccess
     public long writeLock() {
-        long s, next;  // bypass acquireWrite in fully unlocked case only
-        return ((((s = state) & ABITS) == 0L &&
-                 STATE.compareAndSet(this, s, next = s + WBIT)) ?
-                next : acquireWrite(false, 0L));
+        long next;
+        return ((next = tryWriteLock()) != 0L) ? next : acquireWrite(false, 0L);
     }
 
     /**
@@ -377,10 +393,8 @@
      */
     @ReservedStackAccess
     public long tryWriteLock() {
-        long s, next;
-        return ((((s = state) & ABITS) == 0L &&
-                 STATE.compareAndSet(this, s, next = s + WBIT)) ?
-                next : 0L);
+        long s;
+        return (((s = state) & ABITS) == 0L) ? tryWriteLock(s) : 0L;
     }
 
     /**
@@ -440,10 +454,13 @@
      */
     @ReservedStackAccess
     public long readLock() {
-        long s = state, next;  // bypass acquireRead on common uncontended case
-        return ((whead == wtail && (s & ABITS) < RFULL &&
-                 STATE.compareAndSet(this, s, next = s + RUNIT)) ?
-                next : acquireRead(false, 0L));
+        long s, next;
+        // bypass acquireRead on common uncontended case
+        return (whead == wtail
+                && ((s = state) & ABITS) < RFULL
+                && casState(s, next = s + RUNIT))
+            ? next
+            : acquireRead(false, 0L);
     }
 
     /**
@@ -457,7 +474,7 @@
         long s, m, next;
         while ((m = (s = state) & ABITS) != WBIT) {
             if (m < RFULL) {
-                if (STATE.compareAndSet(this, s, next = s + RUNIT))
+                if (casState(s, next = s + RUNIT))
                     return next;
             }
             else if ((next = tryIncReaderOverflow(s)) != 0L)
@@ -487,7 +504,7 @@
         if (!Thread.interrupted()) {
             if ((m = (s = state) & ABITS) != WBIT) {
                 if (m < RFULL) {
-                    if (STATE.compareAndSet(this, s, next = s + RUNIT))
+                    if (casState(s, next = s + RUNIT))
                         return next;
                 }
                 else if ((next = tryIncReaderOverflow(s)) != 0L)
@@ -514,10 +531,15 @@
      * before acquiring the lock
      */
     @ReservedStackAccess
-    public long readLockInterruptibly() throws InterruptedException {
-        long next;
-        if (!Thread.interrupted() &&
-            (next = acquireRead(true, 0L)) != INTERRUPTED)
+        public long readLockInterruptibly() throws InterruptedException {
+        long s, next;
+        if (!Thread.interrupted()
+            // bypass acquireRead on common uncontended case
+            && ((whead == wtail
+                 && ((s = state) & ABITS) < RFULL
+                 && casState(s, next = s + RUNIT))
+                ||
+                (next = acquireRead(true, 0L)) != INTERRUPTED))
             return next;
         throw new InterruptedException();
     }
@@ -598,7 +620,7 @@
                && (stamp & RBITS) > 0L
                && ((m = s & RBITS) > 0L)) {
             if (m < RFULL) {
-                if (STATE.compareAndSet(this, s, s - RUNIT)) {
+                if (casState(s, s - RUNIT)) {
                     if (m == RUNIT && (h = whead) != null && h.status != 0)
                         release(h);
                     return;
@@ -620,7 +642,7 @@
      */
     @ReservedStackAccess
     public void unlock(long stamp) {
-        if ((stamp & WBIT) != 0)
+        if ((stamp & WBIT) != 0L)
             unlockWrite(stamp);
         else
             unlockRead(stamp);
@@ -644,7 +666,7 @@
             if ((m = s & ABITS) == 0L) {
                 if (a != 0L)
                     break;
-                if (STATE.compareAndSet(this, s, next = s + WBIT))
+                if ((next = tryWriteLock(s)) != 0L)
                     return next;
             }
             else if (m == WBIT) {
@@ -653,8 +675,10 @@
                 return stamp;
             }
             else if (m == RUNIT && a != 0L) {
-                if (STATE.compareAndSet(this, s, next = s - RUNIT + WBIT))
+                if (casState(s, next = s - RUNIT + WBIT)) {
+                    VarHandle.storeStoreFence();
                     return next;
+                }
             }
             else
                 break;
@@ -688,7 +712,7 @@
             else if (a == 0L) {
                 // optimistic read stamp
                 if ((s & ABITS) < RFULL) {
-                    if (STATE.compareAndSet(this, s, next = s + RUNIT))
+                    if (casState(s, next = s + RUNIT))
                         return next;
                 }
                 else if ((next = tryIncReaderOverflow(s)) != 0L)
@@ -730,7 +754,7 @@
             else if ((m = s & ABITS) == 0L) // invalid read stamp
                 break;
             else if (m < RFULL) {
-                if (STATE.compareAndSet(this, s, next = s - RUNIT)) {
+                if (casState(s, next = s - RUNIT)) {
                     if (m == RUNIT && (h = whead) != null && h.status != 0)
                         release(h);
                     return next & SBITS;
@@ -771,7 +795,7 @@
         long s, m; WNode h;
         while ((m = (s = state) & ABITS) != 0L && m < WBIT) {
             if (m < RFULL) {
-                if (STATE.compareAndSet(this, s, s - RUNIT)) {
+                if (casState(s, s - RUNIT)) {
                     if (m == RUNIT && (h = whead) != null && h.status != 0)
                         release(h);
                     return true;
@@ -940,7 +964,7 @@
         long s, m; WNode h;
         while ((m = (s = state) & RBITS) > 0L) {
             if (m < RFULL) {
-                if (STATE.compareAndSet(this, s, s - RUNIT)) {
+                if (casState(s, s - RUNIT)) {
                     if (m == RUNIT && (h = whead) != null && h.status != 0)
                         release(h);
                     return;
@@ -971,7 +995,7 @@
     private long tryIncReaderOverflow(long s) {
         // assert (s & ABITS) >= RFULL;
         if ((s & ABITS) == RFULL) {
-            if (STATE.compareAndSet(this, s, s | RBITS)) {
+            if (casState(s, s | RBITS)) {
                 ++readerOverflow;
                 STATE.setVolatile(this, s);
                 return s;
@@ -993,7 +1017,7 @@
     private long tryDecReaderOverflow(long s) {
         // assert (s & ABITS) >= RFULL;
         if ((s & ABITS) == RFULL) {
-            if (STATE.compareAndSet(this, s, s | RBITS)) {
+            if (casState(s, s | RBITS)) {
                 int r; long next;
                 if ((r = readerOverflow) > 0) {
                     readerOverflow = r - 1;
@@ -1047,7 +1071,7 @@
         for (int spins = -1;;) { // spin while enqueuing
             long m, s, ns;
             if ((m = (s = state) & ABITS) == 0L) {
-                if (STATE.compareAndSet(this, s, ns = s + WBIT))
+                if ((ns = tryWriteLock(s)) != 0L)
                     return ns;
             }
             else if (spins < 0)
@@ -1082,7 +1106,7 @@
                 for (int k = spins; k > 0; --k) { // spin at head
                     long s, ns;
                     if (((s = state) & ABITS) == 0L) {
-                        if (STATE.compareAndSet(this, s, ns = s + WBIT)) {
+                        if ((ns = tryWriteLock(s)) != 0L) {
                             whead = node;
                             node.prev = null;
                             if (wasInterrupted)
@@ -1158,7 +1182,7 @@
             if ((h = whead) == (p = wtail)) {
                 for (long m, s, ns;;) {
                     if ((m = (s = state) & ABITS) < RFULL ?
-                        STATE.compareAndSet(this, s, ns = s + RUNIT) :
+                        casState(s, ns = s + RUNIT) :
                         (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
                         if (wasInterrupted)
                             Thread.currentThread().interrupt();
@@ -1208,7 +1232,7 @@
                         long m, s, ns;
                         do {
                             if ((m = (s = state) & ABITS) < RFULL ?
-                                STATE.compareAndSet(this, s, ns = s + RUNIT) :
+                                casState(s, ns = s + RUNIT) :
                                 (m < WBIT &&
                                  (ns = tryIncReaderOverflow(s)) != 0L)) {
                                 if (wasInterrupted)
@@ -1260,7 +1284,7 @@
                 for (int k = spins;;) { // spin at head
                     long m, s, ns;
                     if ((m = (s = state) & ABITS) < RFULL ?
-                        STATE.compareAndSet(this, s, ns = s + RUNIT) :
+                        casState(s, ns = s + RUNIT) :
                         (m < WBIT && (ns = tryIncReaderOverflow(s)) != 0L)) {
                         WNode c; Thread w;
                         whead = node;
--- a/src/java.base/share/classes/java/util/zip/ZipEntry.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/zip/ZipEntry.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -568,9 +568,18 @@
                     int pos = off + 4;               // reserved 4 bytes
                     if (get16(extra, pos) !=  0x0001 || get16(extra, pos + 2) != 24)
                         break;
-                    mtime = winTimeToFileTime(get64(extra, pos + 4));
-                    atime = winTimeToFileTime(get64(extra, pos + 12));
-                    ctime = winTimeToFileTime(get64(extra, pos + 20));
+                    long wtime = get64(extra, pos + 4);
+                    if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
+                        mtime = winTimeToFileTime(wtime);
+                    }
+                    wtime = get64(extra, pos + 12);
+                    if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
+                        atime = winTimeToFileTime(wtime);
+                    }
+                    wtime = get64(extra, pos + 20);
+                    if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
+                        ctime = winTimeToFileTime(wtime);
+                    }
                     break;
                 case EXTID_EXTT:
                     int flag = Byte.toUnsignedInt(extra[off]);
--- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -421,22 +421,36 @@
         byte[] nameBytes = zc.getBytes(e.name);
         writeShort(nameBytes.length);
 
-        int elenEXTT = 0;               // info-zip extended timestamp
+        int elenEXTT = 0;         // info-zip extended timestamp
         int flagEXTT = 0;
+        long umtime = -1;
+        long uatime = -1;
+        long uctime = -1;
         if (e.mtime != null) {
             elenEXTT += 4;
             flagEXTT |= EXTT_FLAG_LMT;
+            umtime = fileTimeToUnixTime(e.mtime);
         }
         if (e.atime != null) {
             elenEXTT += 4;
             flagEXTT |= EXTT_FLAG_LAT;
+            uatime = fileTimeToUnixTime(e.atime);
         }
         if (e.ctime != null) {
             elenEXTT += 4;
             flagEXTT |= EXTT_FLAT_CT;
+            uctime = fileTimeToUnixTime(e.ctime);
         }
-        if (flagEXTT != 0)
-            elen += (elenEXTT + 5);    // headid(2) + size(2) + flag(1) + data
+        if (flagEXTT != 0) {
+            // to use ntfs time if any m/a/ctime is beyond unixtime upper bound
+            if (umtime > UPPER_UNIXTIME_BOUND ||
+                uatime > UPPER_UNIXTIME_BOUND ||
+                uctime > UPPER_UNIXTIME_BOUND) {
+                elen += 36;                // NTFS time, total 36 bytes
+            } else {
+                elen += (elenEXTT + 5);    // headid(2) + size(2) + flag(1) + data
+            }
+        }
         writeShort(elen);
         writeBytes(nameBytes, 0, nameBytes.length);
         if (hasZip64) {
@@ -446,15 +460,31 @@
             writeLong(e.csize);
         }
         if (flagEXTT != 0) {
-            writeShort(EXTID_EXTT);
-            writeShort(elenEXTT + 1);      // flag + data
-            writeByte(flagEXTT);
-            if (e.mtime != null)
-                writeInt(fileTimeToUnixTime(e.mtime));
-            if (e.atime != null)
-                writeInt(fileTimeToUnixTime(e.atime));
-            if (e.ctime != null)
-                writeInt(fileTimeToUnixTime(e.ctime));
+            if (umtime > UPPER_UNIXTIME_BOUND ||
+                uatime > UPPER_UNIXTIME_BOUND ||
+                uctime > UPPER_UNIXTIME_BOUND) {
+                writeShort(EXTID_NTFS);    // id
+                writeShort(32);            // data size
+                writeInt(0);               // reserved
+                writeShort(0x0001);        // NTFS attr tag
+                writeShort(24);
+                writeLong(e.mtime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.mtime));
+                writeLong(e.atime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.atime));
+                writeLong(e.ctime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.ctime));
+            } else {
+                writeShort(EXTID_EXTT);
+                writeShort(elenEXTT + 1);  // flag + data
+                writeByte(flagEXTT);
+                if (e.mtime != null)
+                    writeInt(umtime);
+                if (e.atime != null)
+                    writeInt(uatime);
+                if (e.ctime != null)
+                    writeInt(uctime);
+            }
         }
         writeExtra(e.extra);
         locoff = written;
@@ -528,18 +558,30 @@
         // cen info-zip extended timestamp only outputs mtime
         // but set the flag for a/ctime, if present in loc
         int flagEXTT = 0;
+        long umtime = -1;
+        long uatime = -1;
+        long uctime = -1;
         if (e.mtime != null) {
-            elen += 4;              // + mtime(4)
             flagEXTT |= EXTT_FLAG_LMT;
+            umtime = fileTimeToUnixTime(e.mtime);
         }
         if (e.atime != null) {
             flagEXTT |= EXTT_FLAG_LAT;
+            uatime = fileTimeToUnixTime(e.atime);
         }
         if (e.ctime != null) {
             flagEXTT |= EXTT_FLAT_CT;
+            uctime = fileTimeToUnixTime(e.ctime);
         }
         if (flagEXTT != 0) {
-            elen += 5;             // headid + sz + flag
+            // to use ntfs time if any m/a/ctime is beyond unixtime upper bound
+            if (umtime > UPPER_UNIXTIME_BOUND ||
+                uatime > UPPER_UNIXTIME_BOUND ||
+                uctime > UPPER_UNIXTIME_BOUND) {
+                elen += 36;         // NTFS time total 36 bytes
+            } else {
+                elen += 9;          // headid(2) + sz(2) + flag(1) + mtime (4)
+            }
         }
         writeShort(elen);
         byte[] commentBytes;
@@ -568,14 +610,30 @@
                 writeLong(xentry.offset);
         }
         if (flagEXTT != 0) {
-            writeShort(EXTID_EXTT);
-            if (e.mtime != null) {
-                writeShort(5);      // flag + mtime
-                writeByte(flagEXTT);
-                writeInt(fileTimeToUnixTime(e.mtime));
+            if (umtime > UPPER_UNIXTIME_BOUND ||
+                uatime > UPPER_UNIXTIME_BOUND ||
+                uctime > UPPER_UNIXTIME_BOUND) {
+                writeShort(EXTID_NTFS);    // id
+                writeShort(32);            // data size
+                writeInt(0);               // reserved
+                writeShort(0x0001);        // NTFS attr tag
+                writeShort(24);
+                writeLong(e.mtime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.mtime));
+                writeLong(e.atime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.atime));
+                writeLong(e.ctime == null ? WINDOWS_TIME_NOT_AVAILABLE
+                                          : fileTimeToWinTime(e.ctime));
             } else {
-                writeShort(1);      // flag only
-                writeByte(flagEXTT);
+                writeShort(EXTID_EXTT);
+                if (e.mtime != null) {
+                    writeShort(5);      // flag + mtime
+                    writeByte(flagEXTT);
+                    writeInt(umtime);
+                } else {
+                    writeShort(1);      // flag only
+                    writeByte(flagEXTT);
+                }
             }
         }
         writeExtra(e.extra);
--- a/src/java.base/share/classes/java/util/zip/ZipUtils.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/java/util/zip/ZipUtils.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,9 @@
     // used to adjust values between Windows and java epoch
     private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
 
+    // used to indicate the corresponding windows time is not available
+    public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE;
+
     /**
      * Converts Windows time (in microseconds, UTC/GMT) time to FileTime.
      */
@@ -54,6 +57,11 @@
     }
 
     /**
+     * The upper bound of the 32-bit unix time, the "year 2038 problem".
+     */
+    public static final long UPPER_UNIXTIME_BOUND = 0x7fffffff;
+
+    /**
      * Converts "standard Unix time"(in seconds, UTC/GMT) to FileTime
      */
     public static final FileTime unixTimeToFileTime(long utime) {
--- a/src/java.base/share/classes/module-info.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/share/classes/module-info.java	Wed Jul 27 13:33:55 2016 +0000
@@ -149,7 +149,6 @@
     exports jdk.internal.module to
         java.instrument,
         java.management,
-        java.xml,
         jdk.dynalink,
         jdk.jartool,
         jdk.jlink;
@@ -309,4 +308,3 @@
     provides java.nio.file.spi.FileSystemProvider with
         jdk.internal.jrtfs.JrtFileSystemProvider;
 }
-
--- a/src/java.base/unix/native/libjava/java_props_md.c	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.base/unix/native/libjava/java_props_md.c	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,11 +68,6 @@
 #endif
 #endif /* !_ALLBSD_SOURCE */
 
-#ifdef JAVASE_EMBEDDED
-#include <dlfcn.h>
-#include <sys/stat.h>
-#endif
-
 /* Take an array of string pairs (map of key->value) and a string (key).
  * Examine each pair in the map to see if the first string (key) matches the
  * string.  If so, store the second string of the pair (value) in the value and
@@ -350,36 +345,6 @@
     return 1;
 }
 
-#ifdef JAVASE_EMBEDDED
-/* Determine the default embedded toolkit based on whether libawt_xawt
- * exists in the JRE. This can still be overridden by -Dawt.toolkit=XXX
- */
-static char* getEmbeddedToolkit() {
-    Dl_info dlinfo;
-    char buf[MAXPATHLEN];
-    int32_t len;
-    char *p;
-    struct stat statbuf;
-
-    /* Get address of this library and the directory containing it. */
-    dladdr((void *)getEmbeddedToolkit, &dlinfo);
-    realpath((char *)dlinfo.dli_fname, buf);
-    len = strlen(buf);
-    p = strrchr(buf, '/');
-    /* Default AWT Toolkit on Linux and Solaris is XAWT (libawt_xawt.so). */
-    strncpy(p, "/libawt_xawt.so", MAXPATHLEN-len-1);
-    /* Check if it exists */
-    if (stat(buf, &statbuf) == -1 && errno == ENOENT) {
-        /* No - this is a reduced-headless-jre so use special HToolkit */
-        return "sun.awt.HToolkit";
-    }
-    else {
-        /* Yes - this is a headful JRE so fallback to SE defaults */
-        return NULL;
-    }
-}
-#endif
-
 /* This function gets called very early, before VM_CALLS are setup.
  * Do not use any of the VM_CALLS entries!!!
  */
@@ -424,10 +389,6 @@
     sprops.awt_headless = isInAquaSession() ? NULL : "true";
 #else
     sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
-#ifdef JAVASE_EMBEDDED
-    sprops.awt_toolkit = getEmbeddedToolkit();
-    if (sprops.awt_toolkit == NULL) // default as below
-#endif
     sprops.awt_toolkit = "sun.awt.X11.XToolkit";
 #endif
 
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,11 +122,7 @@
 JNIEXPORT jlong JNICALL Java_sun_awt_X11_XToolkit_getTrayIconDisplayTimeout
   (JNIEnv *env, jclass clazz)
 {
-#ifndef JAVASE_EMBEDDED
     return (jlong) 2000;
-#else
-    return (jlong) 10000;
-#endif
 }
 
 /*
@@ -369,12 +365,7 @@
 #define AWT_READPIPE            (awt_pipe_fds[0])
 #define AWT_WRITEPIPE           (awt_pipe_fds[1])
 
-#ifdef JAVASE_EMBEDDED
-  #define DEF_AWT_MAX_POLL_TIMEOUT ((uint32_t)4000000000) /* milliseconds */
-#else
-  #define DEF_AWT_MAX_POLL_TIMEOUT ((uint32_t)500) /* milliseconds */
-#endif
-
+#define DEF_AWT_MAX_POLL_TIMEOUT ((uint32_t)500) /* milliseconds */
 #define DEF_AWT_FLUSH_TIMEOUT ((uint32_t)100) /* milliseconds */
 #define AWT_MIN_POLL_TIMEOUT ((uint32_t)0) /* milliseconds */
 
@@ -391,11 +382,7 @@
 
 // Static fields
 
-#ifdef JAVASE_EMBEDDED
-  static int          awt_poll_alg = AWT_POLL_AGING_FAST;
-#else
-  static int          awt_poll_alg = AWT_POLL_AGING_SLOW;
-#endif
+static int          awt_poll_alg = AWT_POLL_AGING_SLOW;
 
 static uint32_t AWT_FLUSH_TIMEOUT  =  DEF_AWT_FLUSH_TIMEOUT; /* milliseconds */
 static uint32_t AWT_MAX_POLL_TIMEOUT = DEF_AWT_MAX_POLL_TIMEOUT; /* milliseconds */
--- a/src/java.desktop/unix/native/libjawt/jawt.c	Wed Jul 27 08:33:15 2016 -0400
+++ b/src/java.desktop/unix/native/libjawt/jawt.c	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,10 +39,6 @@
  */
 JNIEXPORT jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt)
 {
-#if defined(JAVASE_EMBEDDED) && defined(HEADLESS)
-    /* there are no AWT libs available at all */
-    return JNI_FALSE;
-#else
     if (awt == NULL) {
         return JNI_FALSE;
     }
@@ -62,5 +58,4 @@
     }
 
     return JNI_TRUE;
-#endif
 }
--- a/test/java/net/URLPermission/URLPermissionTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/net/URLPermission/URLPermissionTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -26,7 +26,7 @@
 
 /**
  * @test
- * @bug 8010464 8027570 8027687 8029354 8114860 8071660
+ * @bug 8010464 8027570 8027687 8029354 8114860 8071660 8161291
  */
 
 public class URLPermissionTest {
@@ -355,15 +355,16 @@
     };
 
     static Test[] actionsStringTest = {
-        actionstest("", ""),
+        actionstest("", ":"),
+        actionstest(":", ":"),
         actionstest(":X-Bar", ":X-Bar"),
-        actionstest("GET", "GET"),
-        actionstest("get", "GET"),
-        actionstest("GET,POST", "GET,POST"),
-        actionstest("GET,post", "GET,POST"),
-        actionstest("get,post", "GET,POST"),
-        actionstest("get,post,DELETE", "DELETE,GET,POST"),
-        actionstest("GET,POST:", "GET,POST"),
+        actionstest("GET", "GET:"),
+        actionstest("get", "GET:"),
+        actionstest("GET,POST", "GET,POST:"),
+        actionstest("GET,post", "GET,POST:"),
+        actionstest("get,post", "GET,POST:"),
+        actionstest("get,post,DELETE", "DELETE,GET,POST:"),
+        actionstest("GET,POST:", "GET,POST:"),
         actionstest("GET:X-Foo,X-bar", "GET:X-Bar,X-Foo"),
         actionstest("GET,POST,DELETE:X-Bar,X-Foo,X-Bar,Y-Foo", "DELETE,GET,POST:X-Bar,X-Bar,X-Foo,Y-Foo")
     };
--- a/test/java/security/Provider/SecurityProviderModularTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/security/Provider/SecurityProviderModularTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -63,8 +63,7 @@
             "TestSecurityProviderClient.java");
     private static final String C_PKG = "client";
     private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
-    private static final String MC_DEPENDS_ON_AUTO_SERVICE_JAR_NAME = MODULAR
-            + C_PKG + AUTO + JAR_EXTN;
+    private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN;
     private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
 
     private static final Path BUILD_DIR = Paths.get(".").resolve("build");
@@ -72,7 +71,7 @@
     private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
     private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve(
             S_PKG + DESCRIPTOR);
-    private static final Path C_BUILD_DIR = COMPILE_DIR.resolve(C_PKG);
+    private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
     private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
     private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
 
@@ -88,8 +87,7 @@
     private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
     private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
     private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
-    private static final Path MC_DEPENDS_ON_AUTO_SERVICE_JAR = C_ARTIFACTS_DIR
-            .resolve(MC_DEPENDS_ON_AUTO_SERVICE_JAR_NAME);
+    private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
 
     private static final String MAIN = C_PKG + ".TestSecurityProviderClient";
     private static final String S_INTERFACE = "java.security.Provider";
@@ -102,8 +100,6 @@
 
     private static final boolean WITH_S_DESCR = true;
     private static final boolean WITHOUT_S_DESCR = false;
-    private static final String CLASS_NOT_FOUND_MSG = "NoClassDefFoundError:"
-            + " provider/TestSecurityProvider";
     private static final String PROVIDER_NOT_FOUND_MSG = "Unable to find Test"
             + " Security Provider";
     private static final String CAN_NOT_ACCESS_MSG = "cannot access class";
@@ -126,10 +122,10 @@
             boolean useCLoader = CLASS_LOADER.equals(mechanism);
             boolean useSLoader = SERVICE_LOADER.equals(mechanism);
             String[] args = new String[]{mechanism};
-            //PARAMETER ORDERS -
-            //client Module Type, Service Module Type,
-            //Service META Descriptor Required,
-            //Expected Failure message, mech used to find the provider
+            // PARAMETER ORDERS -
+            // Client Module Type, Service Module Type,
+            // If Service META Descriptor Required,
+            // Expected Failure message, mechanism used to find the provider
             params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
@@ -138,7 +134,8 @@
                     WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
                             : NO_FAILURE), args));
             params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
-                    WITHOUT_S_DESCR, CLASS_NOT_FOUND_MSG, args));
+                    WITHOUT_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
+                            : PROVIDER_NOT_FOUND_MSG), args));
             params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
                     WITH_S_DESCR, ((useCLoader) ? CAN_NOT_ACCESS_MSG
                             : NO_FAILURE), args));
@@ -150,11 +147,12 @@
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
-                    WITH_S_DESCR, NO_FAILURE, args));
+                    WITHOUT_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
-                    WITHOUT_S_DESCR, CLASS_NOT_FOUND_MSG, args));
+                    WITHOUT_S_DESCR,
+                    (useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args));
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
@@ -168,7 +166,8 @@
             params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
-                    WITHOUT_S_DESCR, CLASS_NOT_FOUND_MSG, args));
+                    WITHOUT_S_DESCR,
+                    (useCLoader) ? NO_FAILURE : PROVIDER_NOT_FOUND_MSG, args));
             params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
                     WITH_S_DESCR, NO_FAILURE, args));
             params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
@@ -191,22 +190,23 @@
             done &= CompilerUtils.compile(S_SRC, S_BUILD_DIR);
             done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR);
             done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL);
-            //Generate regular/modular jars with(out) META-INF
-            //Service descriptor
+            // Generate modular/regular jars with(out) META-INF
+            // service descriptor
             generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR,
                     S_WITH_META_DESCR_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR,
                     S_WITH_META_DESCR_BUILD_DIR, false);
-            //Generate regular/modular(depends on explicit/auto Service)
-            //jars for client
-            done &= CompilerUtils.compile(C_SRC, C_BUILD_DIR, "-cp",
+            // Compile client source codes.
+            done &= CompilerUtils.compile(C_SRC, C_BLD_DIR, "-cp",
                     S_JAR.toFile().getCanonicalPath());
-            generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BUILD_DIR, true);
-            generateJar(false, MODULE_TYPE.EXPLICIT,
-                    MC_DEPENDS_ON_AUTO_SERVICE_JAR, C_BUILD_DIR, false);
-            generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BUILD_DIR, false);
+            // Generate modular client jar with explicit dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
+            // Generate modular client jar without any dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
+            // Generate regular client jar
+            generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
             System.out.format("%nArtifacts generated successfully? %s", done);
             if (!done) {
                 throw new RuntimeException("Artifacts generation failed");
@@ -244,10 +244,9 @@
 
         OutputAnalyzer output = null;
         try {
-
-            //For automated/explicit module type copy the corresponding
-            //jars to module base folder, which will be considered as
-            //module base path during execution.
+            // For automated/explicit module types, copy the corresponding
+            // jars to module base folder, which will be considered as
+            // module base path during execution.
             if (!(cModuleType == MODULE_TYPE.UNNAMED
                     && sModuletype == MODULE_TYPE.UNNAMED)) {
                 copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
@@ -262,15 +261,14 @@
             String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
                     sJarPath);
 
-            Map<String, String> VM_ARGS = getVMArgs(sModuletype, args);
+            Map<String, String> vmArgs = getVMArgs(sModuletype,
+                    getModuleName(sModuletype, sJarPath, S_PKG), args);
             output = ProcessTools.executeTestJava(
-                    getJavaCommand(cmBasePath, cPath, mName, MAIN, VM_ARGS,
+                    getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
                             args)).outputTo(System.out).errorTo(System.out);
         } finally {
-            //clean module path so that the modulepath can hold only
-            //the required jars for next run.
+            // Clean module path to hold required jars for next run.
             cleanModuleBasePath(M_BASE_PATH);
-            System.out.println("--------------------------------------------");
         }
         return output;
     }
@@ -297,11 +295,12 @@
                 }
             }
         } else {
+            // Choose corresponding client jar to use dependent module
             if (moduleType == MODULE_TYPE.EXPLICIT) {
                 if (dependsOnServiceModule) {
                     return MC_JAR;
                 } else {
-                    return MC_DEPENDS_ON_AUTO_SERVICE_JAR;
+                    return MCN_JAR;
                 }
             } else {
                 return C_JAR;
@@ -313,13 +312,16 @@
      * VM argument required for the test.
      */
     private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
-            String... args) throws IOException {
-        final Map<String, String> VM_ARGS = new LinkedHashMap<>();
-        VM_ARGS.put("-Duser.language=", "en");
-        VM_ARGS.put("-Duser.region=", "US");
-        //If mechanism selected to find the provider through
-        //Security.getProvider() then use providerName/ProviderClassName based
-        //on modular/regular provider jar in security configuration file.
+            String addModName, String... args) throws IOException {
+        final Map<String, String> vmArgs = new LinkedHashMap<>();
+        vmArgs.put("-Duser.language=", "en");
+        vmArgs.put("-Duser.region=", "US");
+        if (addModName != null && sModuletype == MODULE_TYPE.AUTO) {
+            vmArgs.put("-addmods ", addModName);
+        }
+        // If mechanism selected to find the provider through
+        // Security.getProvider() then use providerName/ProviderClassName based
+        // on modular/regular provider jar in security configuration file.
         if (args != null && args.length > 0 && SECURITY_PROP.equals(args[0])) {
             if (sModuletype == MODULE_TYPE.UNNAMED) {
                 Files.write(SECURE_PROP_EXTN, ("security.provider.10=" + S_IMPL)
@@ -328,10 +330,10 @@
                 Files.write(SECURE_PROP_EXTN, "security.provider.10=TEST"
                         .getBytes());
             }
-            VM_ARGS.put("-Djava.security.properties=", SECURE_PROP_EXTN.toFile()
+            vmArgs.put("-Djava.security.properties=", SECURE_PROP_EXTN.toFile()
                     .getCanonicalPath());
         }
-        return VM_ARGS;
+        return vmArgs;
     }
 
 }
--- a/test/java/security/modules/ModularTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/security/modules/ModularTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -82,7 +82,7 @@
 
         String testName = new StringJoiner("_").add(cModuleType.toString())
                 .add(sModuletype.toString()).add(
-                        (addMetaDesc) ? "DESCRIPTOR" : "NO_DESCRIPTOR")
+                        (addMetaDesc) ? "WITH_SERVICE" : "NO_SERVICE")
                 .toString();
 
         System.out.format("%nStarting Test case: '%s'", testName);
@@ -165,10 +165,12 @@
         if (moduleType == MODULE_TYPE.EXPLICIT) {
             System.out.format(" %nGenerating ModuleDescriptor object");
             builder = new Builder(moduleName).exports(pkg);
-            if (isService) {
+            if (isService && serviceInterface != null && serviceImpl != null) {
                 builder.provides(serviceInterface, serviceImpl);
             } else {
-                builder.uses(serviceInterface);
+                if (serviceInterface != null) {
+                    builder.uses(serviceInterface);
+                }
                 if (depends) {
                     builder.requires(serviceModuleName);
                 }
@@ -261,7 +263,7 @@
         String jarName = jarPath.toFile().getName();
         return (moduleType == MODULE_TYPE.EXPLICIT) ? mName
                 : ((moduleType == MODULE_TYPE.AUTO) ? jarName.substring(0,
-                                jarName.indexOf(JAR_EXTN)) : "");
+                                jarName.indexOf(JAR_EXTN)) : null);
     }
 
     /**
--- a/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/concurrent/BlockingQueue/PollMemoryLeak.java	Wed Jul 27 13:33:55 2016 +0000
@@ -42,6 +42,7 @@
 
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.LinkedTransferQueue;
 import java.util.concurrent.SynchronousQueue;
@@ -50,9 +51,11 @@
 public class PollMemoryLeak {
     public static void main(String[] args) throws InterruptedException {
         final BlockingQueue[] qs = {
+            new LinkedBlockingDeque(10),
             new LinkedBlockingQueue(10),
             new LinkedTransferQueue(),
             new ArrayBlockingQueue(10),
+            new ArrayBlockingQueue(10, true),
             new SynchronousQueue(),
             new SynchronousQueue(true),
         };
--- a/test/java/util/concurrent/tck/CompletableFutureTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/concurrent/tck/CompletableFutureTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -4269,12 +4269,11 @@
         }
     }
 
-    /*
-     * Tests below currently fail in stress mode due to memory retention.
-     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck
+    /**
+     * Reproduction recipe for:
+     * 8160402: Garbage retention with CompletableFuture.anyOf
+     * cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
      */
-
-    /** Checks for garbage retention with anyOf. */
     public void testAnyOfGarbageRetention() throws Throwable {
         for (Integer v : new Integer[] { 1, null })
     {
@@ -4288,7 +4287,12 @@
             checkCompletedNormally(CompletableFuture.anyOf(fs), v);
     }}
 
-    /** Checks for garbage retention with allOf. */
+    /**
+     * Checks for garbage retention with allOf.
+     *
+     * As of 2016-07, fails with OOME:
+     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledAllOfGarbageRetention tck
+     */
     public void testCancelledAllOfGarbageRetention() throws Throwable {
         final int n = expensiveTests ? 100_000 : 10;
         CompletableFuture<Integer>[] fs
@@ -4299,6 +4303,21 @@
             assertTrue(CompletableFuture.allOf(fs).cancel(false));
     }
 
+    /**
+     * Checks for garbage retention when a dependent future is
+     * cancelled and garbage-collected.
+     * 8161600: Garbage retention when source CompletableFutures are never completed
+     *
+     * As of 2016-07, fails with OOME:
+     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledGarbageRetention tck
+     */
+    public void testCancelledGarbageRetention() throws Throwable {
+        final int n = expensiveTests ? 100_000 : 10;
+        CompletableFuture<Integer> neverCompleted = new CompletableFuture<>();
+        for (int i = 0; i < n; i++)
+            assertTrue(neverCompleted.thenRun(() -> {}).cancel(true));
+    }
+
 //     static <U> U join(CompletionStage<U> stage) {
 //         CompletableFuture<U> f = new CompletableFuture<>();
 //         stage.whenComplete((v, ex) -> {
--- a/test/java/util/concurrent/tck/ConcurrentHashMapTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/concurrent/tck/ConcurrentHashMapTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -43,6 +43,8 @@
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -830,4 +832,47 @@
         }
     }
 
+    /**
+     * Tests performance of removeAll when the other collection is much smaller.
+     * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testRemoveAll_performance -Djsr166.expensiveTests=true tck
+     */
+    public void testRemoveAll_performance() {
+        final int mapSize = expensiveTests ? 1_000_000 : 100;
+        final int iterations = expensiveTests ? 500 : 2;
+        final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
+        for (int i = 0; i < mapSize; i++)
+            map.put(i, i);
+        Set<Integer> keySet = map.keySet();
+        Collection<Integer> removeMe = Arrays.asList(new Integer[] { -99, -86 });
+        for (int i = 0; i < iterations; i++)
+            assertFalse(keySet.removeAll(removeMe));
+        assertEquals(mapSize, map.size());
+    }
+
+    /**
+     * Tests performance of computeIfAbsent when the element is present.
+     * See JDK-8161372
+     * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testcomputeIfAbsent_performance -Djsr166.expensiveTests=true tck
+     */
+    public void testcomputeIfAbsent_performance() {
+        final int mapSize = 20;
+        final int iterations = expensiveTests ? (1 << 23) : mapSize * 2;
+        final int threads = expensiveTests ? 10 : 2;
+        final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
+        for (int i = 0; i < mapSize; i++)
+            map.put(i, i);
+        final ExecutorService pool = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            Runnable r = new CheckedRunnable() {
+                public void realRun() {
+                    int result = 0;
+                    for (int i = 0; i < iterations; i++)
+                        result += map.computeIfAbsent(i % mapSize, (k) -> k + k);
+                    if (result == -42) throw new Error();
+                }};
+            for (int i = 0; i < threads; i++)
+                pool.execute(r);
+        }
+    }
+
 }
--- a/test/java/util/concurrent/tck/StampedLockTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/concurrent/tck/StampedLockTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -32,11 +32,18 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
+import static java.util.concurrent.TimeUnit.DAYS;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.StampedLock;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
@@ -1078,4 +1085,121 @@
         assertThrows(IllegalMonitorStateException.class, actions);
     }
 
+    static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
+        try { return sl.writeLockInterruptibly(); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
+        try { return sl.tryWriteLock(time, unit); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long readLockInterruptiblyUninterrupted(StampedLock sl) {
+        try { return sl.readLockInterruptibly(); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
+        try { return sl.tryReadLock(time, unit); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    /**
+     * Invalid write stamps result in IllegalMonitorStateException
+     */
+    public void testInvalidWriteStampsThrowIllegalMonitorStateException() {
+        List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
+        writeLockers.add((sl) -> sl.writeLock());
+        writeLockers.add((sl) -> writeLockInterruptiblyUninterrupted(sl));
+        writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
+        writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, 0, DAYS));
+
+        List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
+        writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
+        writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
+        writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
+        writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
+
+        List<Consumer<StampedLock>> mutaters = new ArrayList<>();
+        mutaters.add((sl) -> {});
+        mutaters.add((sl) -> sl.readLock());
+        for (Function<StampedLock, Long> writeLocker : writeLockers)
+            mutaters.add((sl) -> writeLocker.apply(sl));
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers)
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers)
+        for (Consumer<StampedLock> mutater : mutaters) {
+            final StampedLock sl = new StampedLock();
+            final long stamp = writeLocker.apply(sl);
+            assertTrue(stamp != 0L);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlockRead(stamp));
+            writeUnlocker.accept(sl, stamp);
+            mutater.accept(sl);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlock(stamp),
+                         () -> sl.unlockRead(stamp),
+                         () -> sl.unlockWrite(stamp));
+        }
+    }
+
+    /**
+     * Invalid read stamps result in IllegalMonitorStateException
+     */
+    public void testInvalidReadStampsThrowIllegalMonitorStateException() {
+        List<Function<StampedLock, Long>> readLockers = new ArrayList<>();
+        readLockers.add((sl) -> sl.readLock());
+        readLockers.add((sl) -> readLockInterruptiblyUninterrupted(sl));
+        readLockers.add((sl) -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
+        readLockers.add((sl) -> tryReadLockUninterrupted(sl, 0, DAYS));
+
+        List<BiConsumer<StampedLock, Long>> readUnlockers = new ArrayList<>();
+        readUnlockers.add((sl, stamp) -> sl.unlockRead(stamp));
+        readUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockRead()));
+        readUnlockers.add((sl, stamp) -> sl.asReadLock().unlock());
+        readUnlockers.add((sl, stamp) -> sl.unlock(stamp));
+
+        List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
+        writeLockers.add((sl) -> sl.writeLock());
+        writeLockers.add((sl) -> writeLockInterruptiblyUninterrupted(sl));
+        writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
+        writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, 0, DAYS));
+
+        List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
+        writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
+        writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
+        writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
+        writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
+
+
+        for (Function<StampedLock, Long> readLocker : readLockers)
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers)
+        for (Function<StampedLock, Long> writeLocker : writeLockers)
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers) {
+            final StampedLock sl = new StampedLock();
+            final long stamp = readLocker.apply(sl);
+            assertTrue(stamp != 0L);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlockWrite(stamp));
+            readUnlocker.accept(sl, stamp);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlock(stamp),
+                         () -> sl.unlockRead(stamp),
+                         () -> sl.unlockWrite(stamp));
+            final long writeStamp = writeLocker.apply(sl);
+            assertTrue(writeStamp != 0L);
+            assertTrue(writeStamp != stamp);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlock(stamp),
+                         () -> sl.unlockRead(stamp),
+                         () -> sl.unlockWrite(stamp));
+            writeUnlocker.accept(sl, writeStamp);
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlock(stamp),
+                         () -> sl.unlockRead(stamp),
+                         () -> sl.unlockWrite(stamp));
+        }
+    }
+
 }
--- a/test/java/util/zip/TestExtraTime.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/zip/TestExtraTime.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641 8075526 8130914
+ * @bug 4759491 6303183 7012868 8015666 8023713 8068790 8076641 8075526 8130914 8161942
  * @summary Test ZOS and ZIS timestamp in extra field correctly
  */
 
@@ -32,6 +32,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileTime;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
@@ -40,37 +41,52 @@
 import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
+
+
 public class TestExtraTime {
 
     public static void main(String[] args) throws Throwable{
 
         File src = new File(System.getProperty("test.src", "."), "TestExtraTime.java");
-        if (src.exists()) {
+        if (!src.exists()) {
+            return;
+        }
+
+        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+
+        for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
+
+            // ms-dos 1980 epoch problem
+            test0(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
+            // negative epoch time
+            test0(FileTime.from(-100, TimeUnit.DAYS), null, null, null, extra);
+
             long time = src.lastModified();
-            FileTime mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
-            FileTime atime = FileTime.from(time + 300000, TimeUnit.MILLISECONDS);
-            FileTime ctime = FileTime.from(time - 300000, TimeUnit.MILLISECONDS);
-            TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
+            test(FileTime.from(time, TimeUnit.MILLISECONDS),
+                 FileTime.from(time + 300000, TimeUnit.MILLISECONDS),
+                 FileTime.from(time - 300000, TimeUnit.MILLISECONDS),
+                 tz, extra);
 
-            for (byte[] extra : new byte[][] { null, new byte[] {1, 2, 3}}) {
-                test(mtime, null, null, null, extra);
+            // now
+            time = Instant.now().toEpochMilli();
+            test(FileTime.from(time, TimeUnit.MILLISECONDS),
+                 FileTime.from(time + 300000, TimeUnit.MILLISECONDS),
+                 FileTime.from(time - 300000, TimeUnit.MILLISECONDS),
+                 tz, extra);
 
-                // ms-dos 1980 epoch problem
-                test(FileTime.from(10, TimeUnit.MILLISECONDS), null, null, null, extra);
-                // negative epoch time
-                test(FileTime.from(-100, TimeUnit.DAYS), null, null, null, extra);
+            // unix 2038
+            time = 0x80000000L;
+            test(FileTime.from(time, TimeUnit.SECONDS),
+                 FileTime.from(time, TimeUnit.SECONDS),
+                 FileTime.from(time, TimeUnit.SECONDS),
+                 tz, extra);
 
-                // non-default tz
-                test(mtime, null, null, tz, extra);
-
-                test(mtime, atime, null, null, extra);
-                test(mtime, null, ctime, null, extra);
-                test(mtime, atime, ctime, null, extra);
-
-                test(mtime, atime, null, tz, extra);
-                test(mtime, null, ctime, tz, extra);
-                test(mtime, atime, ctime, tz, extra);
-            }
+            // mtime < unix 2038
+            time = 0x7fffffffL;
+            test(FileTime.from(time, TimeUnit.SECONDS),
+                 FileTime.from(time + 30000, TimeUnit.SECONDS),
+                 FileTime.from(time + 30000, TimeUnit.SECONDS),
+                 tz, extra);
         }
 
         testNullHandling();
@@ -80,6 +96,18 @@
 
     static void test(FileTime mtime, FileTime atime, FileTime ctime,
                      TimeZone tz, byte[] extra) throws Throwable {
+        test0(mtime, null, null, null, extra);
+        test0(mtime, null, null, tz, extra);    // non-default tz
+        test0(mtime, atime, null, null, extra);
+        test0(mtime, null, ctime, null, extra);
+        test0(mtime, atime, ctime, null, extra);
+        test0(mtime, atime, null, tz, extra);
+        test0(mtime, null, ctime, tz, extra);
+        test0(mtime, atime, ctime, tz, extra);
+    }
+
+    static void test0(FileTime mtime, FileTime atime, FileTime ctime,
+                     TimeZone tz, byte[] extra) throws Throwable {
         System.out.printf("--------------------%nTesting: [%s]/[%s]/[%s]%n",
                           mtime, atime, ctime);
         TimeZone tz0 = TimeZone.getDefault();
@@ -120,13 +148,14 @@
         Path zpath = Paths.get(System.getProperty("test.dir", "."),
                                "TestExtraTime.zip");
         Files.copy(new ByteArrayInputStream(baos.toByteArray()), zpath);
-        ZipFile zf = new ZipFile(zpath.toFile());
-        ze = zf.getEntry("TestExtraTime.java");
-        // ZipFile read entry from cen, which does not have a/ctime,
-        // for now.
-        check(mtime, null, null, ze, extra);
-        zf.close();
-        Files.delete(zpath);
+        try (ZipFile zf = new ZipFile(zpath.toFile())) {
+            ze = zf.getEntry("TestExtraTime.java");
+            // ZipFile read entry from cen, which does not have a/ctime,
+            // for now.
+            check(mtime, null, null, ze, extra);
+        } finally {
+            Files.delete(zpath);
+        }
     }
 
     static void check(FileTime mtime, FileTime atime, FileTime ctime,
--- a/test/java/util/zip/TestLocalTime.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/java/util/zip/TestLocalTime.java	Wed Jul 27 13:33:55 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8075526 8135108 8155616
+ * @bug 8075526 8135108 8155616 8161942
  * @summary Test timestamp via ZipEntry.get/setTimeLocal()
  */
 
@@ -65,6 +65,9 @@
             test(LocalDateTime.of(1968, 04, 28, 2, 51, 25));
             test(LocalDateTime.of(1970, 04, 26, 2, 31, 52));
 
+            // for #8161942
+            test(LocalDateTime.of(2200, 04, 26, 2, 31, 52));  // unix 2038
+
         } finally {
             TimeZone.setDefault(tz0);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/net/ssl/templates/SSLSocketSample.java	Wed Jul 27 13:33:55 2016 +0000
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Please run in othervm mode.  SunJSSE does not support dynamic system
+// properties, no way to re-use system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8161106
+ * @summary Improve SSLSocket test template
+ * @run main/othervm SSLSocketSample
+ */
+
+import java.io.*;
+import javax.net.ssl.*;
+import java.net.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Template to help speed your client/server tests.
+ */
+public final class SSLSocketSample {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    private static final boolean separateServerThread = false;
+
+    /*
+     * Where do we find the keystores?
+     */
+    private static final String pathToStores = "../etc";
+    private static final String keyStoreFile = "keystore";
+    private static final String trustStoreFile = "truststore";
+    private static final String passwd = "passphrase";
+
+    /*
+     * Turn on SSL debugging?
+     */
+    private static final boolean debug = false;
+
+    /*
+     * Is the server ready to serve?
+     */
+    private static final CountDownLatch serverCondition = new CountDownLatch(1);
+
+    /*
+     * Is the client ready to handshake?
+     */
+    private static final CountDownLatch clientCondition = new CountDownLatch(1);
+
+    /*
+     * What's the server port?  Use any free port by default
+     */
+    private volatile int serverPort = 0;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     */
+    void doServerSide() throws Exception {
+        SSLServerSocket sslServerSocket;
+
+        // kick start the server side service
+        SSLServerSocketFactory sslssf =
+                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+        sslServerSocket =
+                (SSLServerSocket)sslssf.createServerSocket(serverPort);
+
+        serverPort = sslServerSocket.getLocalPort();
+
+        // Signal the client, the server is ready to accept connection.
+        serverCondition.countDown();
+
+
+        // Try to accept a connection in 30 seconds.
+        SSLSocket sslSocket;
+        try {
+            sslServerSocket.setSoTimeout(30000);
+            sslSocket = (SSLSocket)sslServerSocket.accept();
+        } catch (SocketTimeoutException ste) {
+            sslServerSocket.close();
+
+            // Ignore the test case if no connection within 30 seconds.
+            System.out.println(
+                "No incoming client connection in 30 seconds. " +
+                "Ignore in server side.");
+            return;
+        }
+
+        // handle the connection
+        try {
+            // Is it the expected client connection?
+            //
+            // Naughty test cases or third party routines may try to
+            // connection to this server port unintentionally.  In
+            // order to mitigate the impact of unexpected client
+            // connections and avoid intermittent failure, it should
+            // be checked that the accepted connection is really linked
+            // to the expected client.
+            boolean clientIsReady =
+                    clientCondition.await(30L, TimeUnit.SECONDS);
+
+            if (clientIsReady) {
+                // Run the application in server side.
+                runServerApplication(sslSocket);
+            } else {    // Otherwise, ignore
+                // We don't actually care about plain socket connections
+                // for TLS communication testing generally.  Just ignore
+                // the test if the accepted connection is not linked to
+                // the expected client or the client connection timeout
+                // in 30 seconds.
+                System.out.println(
+                        "The client is not the expected one or timeout. " +
+                        "Ignore in server side.");
+            }
+        } finally {
+            sslSocket.close();
+            sslServerSocket.close();
+        }
+    }
+
+    /*
+     * Define the server side application of the test for the specified socket.
+     */
+    void runServerApplication(SSLSocket socket) throws Exception {
+        // here comes the test logic
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
+
+        sslIS.read();
+        sslOS.write(85);
+        sslOS.flush();
+    }
+
+    /*
+     * Define the client side of the test.
+     */
+    void doClientSide() throws Exception {
+
+        // Wait for server to get started.
+        //
+        // The server side takes care of the issue if the server cannot
+        // get started in 90 seconds.  The client side would just ignore
+        // the test case if the serer is not ready.
+        boolean serverIsReady =
+                serverCondition.await(90L, TimeUnit.SECONDS);
+        if (!serverIsReady) {
+            System.out.println(
+                    "The server is not ready yet in 90 seconds. " +
+                    "Ignore in client side.");
+            return;
+        }
+
+        SSLSocketFactory sslsf =
+            (SSLSocketFactory)SSLSocketFactory.getDefault();
+        try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket()) {
+            try {
+                sslSocket.connect(
+                        new InetSocketAddress("localhost", serverPort), 15000);
+            } catch (IOException ioe) {
+                // The server side may be impacted by naughty test cases or
+                // third party routines, and cannot accept connections.
+                //
+                // Just ignore the test if the connection cannot be
+                // established.
+                System.out.println(
+                        "Cannot make a connection in 15 seconds. " +
+                        "Ignore in client side.");
+                return;
+            }
+
+            // OK, here the client and server get connected.
+
+            // Signal the server, the client is ready to communicate.
+            clientCondition.countDown();
+
+            // There is still a chance in theory that the server thread may
+            // wait client-ready timeout and then quit.  The chance should
+            // be really rare so we don't consider it until it becomes a
+            // real problem.
+
+            // Run the application in client side.
+            runClientApplication(sslSocket);
+        }
+    }
+
+    /*
+     * Define the server side application of the test for the specified socket.
+     */
+    void runClientApplication(SSLSocket socket) throws Exception {
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
+
+        sslOS.write(280);
+        sslOS.flush();
+        sslIS.read();
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    private volatile Exception serverException = null;
+    private volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        /*
+         * Start the tests.
+         */
+        new SSLSocketSample();
+    }
+
+    private Thread clientThread = null;
+    private Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    SSLSocketSample() throws Exception {
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.out.println("Server died: " + e);
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                System.out.println("Server failed: " + e);
+                serverException = e;
+            }
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.out.println("Client died: " + e);
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                System.out.println("Client failed: " + e);
+                clientException = e;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java	Wed Jul 27 13:33:55 2016 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package login;
+
+import java.security.Principal;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import com.sun.security.auth.UnixPrincipal;
+
+public class JaasClientWithDefaultHandler {
+
+    private static final String USER_NAME = "testUser";
+    private static final String LOGIN_CONTEXT = "ModularLoginConf";
+    private static final String CBH_PROP = "auth.login.defaultCallbackHandler";
+
+    public static void main(String[] args) {
+        try {
+            java.security.Security.setProperty(CBH_PROP, args[0]);
+            LoginContext lc = new LoginContext(LOGIN_CONTEXT);
+            lc.login();
+            checkPrincipal(lc, true);
+            lc.logout();
+            checkPrincipal(lc, false);
+        } catch (LoginException le) {
+            throw new RuntimeException(le);
+        }
+        System.out.println("Test passed.");
+
+    }
+
+    /*
+     * Verify principal for the test user.
+     */
+    private static void checkPrincipal(LoginContext loginContext,
+            boolean principalShouldExist) {
+        if (!principalShouldExist) {
+            if (loginContext.getSubject().getPrincipals().size() != 0) {
+                throw new RuntimeException("Test failed. Principal was not "
+                        + "cleared.");
+            }
+            return;
+        }
+        for (Principal p : loginContext.getSubject().getPrincipals()) {
+            if (p instanceof UnixPrincipal
+                    && USER_NAME.equals(p.getName())) {
+                //Proper principal was found, return.
+                return;
+            }
+        }
+        throw new RuntimeException("Test failed. UnixPrincipal "
+                + USER_NAME + " expected.");
+    }
+
+}
--- a/test/javax/security/auth/login/modules/JaasModularClientTest.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/javax/security/auth/login/modules/JaasModularClientTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -59,8 +59,7 @@
     private static final Path C_SRC = SRC.resolve("JaasClient.java");
     private static final String C_PKG = "client";
     private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
-    private static final String MC_DEPENDS_ON_AUTO_SERVICE_JAR_NAME = MODULAR
-            + C_PKG + AUTO + JAR_EXTN;
+    private static final String MCN_JAR_NAME = MODULAR + C_PKG + "N" + JAR_EXTN;
     private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
 
     private static final Path BUILD_DIR = Paths.get(".").resolve("build");
@@ -68,7 +67,7 @@
     private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
     private static final Path S_WITH_META_DESCR_BUILD_DIR = COMPILE_DIR.resolve(
             S_PKG + DESCRIPTOR);
-    private static final Path C_BUILD_DIR = COMPILE_DIR.resolve(C_PKG);
+    private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
     private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
     private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
 
@@ -83,8 +82,7 @@
     private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
     private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
     private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
-    private static final Path MC_DEPENDS_ON_AUTO_SERVICE_JAR = C_ARTIFACTS_DIR
-            .resolve(MC_DEPENDS_ON_AUTO_SERVICE_JAR_NAME);
+    private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
 
     private static final String MAIN = C_PKG + ".JaasClient";
     private static final String S_INTERFACE
@@ -99,10 +97,7 @@
 
     private static final boolean WITH_S_DESCR = true;
     private static final boolean WITHOUT_S_DESCR = false;
-    private static final String LOGIN_MODULE_NOT_FOUND_MSG
-            = "No LoginModule found";
     private static final String NO_FAILURE = null;
-    private static final Map<String, String> VM_ARGS = new LinkedHashMap<>();
 
     /**
      * Generates Test specific input parameters.
@@ -112,10 +107,10 @@
 
         List<List<Object>> params = new ArrayList<>();
         String[] args = new String[]{};
-        //PARAMETER ORDERS -
-        //client Module Type, Service Module Type,
-        //Service META Descriptor Required,
-        //Expected Failure message, mechanism used to find the provider
+        // PARAMETER ORDERS -
+        // Client Module Type, Service Module Type,
+        // If Service META descriptor Required,
+        // Expected Failure message, Client arguments
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
@@ -123,7 +118,7 @@
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
-                WITHOUT_S_DESCR, LOGIN_MODULE_NOT_FOUND_MSG, args));
+                WITHOUT_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
@@ -136,7 +131,7 @@
         params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
-                WITHOUT_S_DESCR, LOGIN_MODULE_NOT_FOUND_MSG, args));
+                WITHOUT_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
@@ -149,7 +144,7 @@
         params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
-                WITHOUT_S_DESCR, LOGIN_MODULE_NOT_FOUND_MSG, args));
+                WITHOUT_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
                 WITH_S_DESCR, NO_FAILURE, args));
         params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
@@ -166,29 +161,25 @@
 
         boolean done = true;
         try {
-            VM_ARGS.put("-Duser.language=", "en");
-            VM_ARGS.put("-Duser.region", "US");
-            VM_ARGS.put("-Djava.security.auth.login.config=", SRC.resolve(
-                    "jaas.conf").toFile().getCanonicalPath());
-
             done = CompilerUtils.compile(S_SRC, S_BUILD_DIR);
             done &= CompilerUtils.compile(S_SRC, S_WITH_META_DESCR_BUILD_DIR);
             done &= createMetaInfServiceDescriptor(S_META_DESCR_FPATH, S_IMPL);
-            //Generate regular/modular jars with(out) META-INF
-            //service descriptor
+            // Generate modular/regular jars with(out) META-INF
+            // service descriptor
             generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.EXPLICIT, MS_WITH_DESCR_JAR,
                     S_WITH_META_DESCR_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
             generateJar(true, MODULE_TYPE.UNNAMED, S_WITH_DESCRIPTOR_JAR,
                     S_WITH_META_DESCR_BUILD_DIR, false);
-            //Generate regular/modular(depends on explicit/auto service)
-            //jars for client
-            done &= CompilerUtils.compile(C_SRC, C_BUILD_DIR);
-            generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BUILD_DIR, true);
-            generateJar(false, MODULE_TYPE.EXPLICIT,
-                    MC_DEPENDS_ON_AUTO_SERVICE_JAR, C_BUILD_DIR, false);
-            generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BUILD_DIR, false);
+            // Compile client source codes.
+            done &= CompilerUtils.compile(C_SRC, C_BLD_DIR);
+            // Generate modular client jar with explicit dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
+            // Generate modular client jar without any dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
+            // Generate regular client jar
+            generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
             System.out.format("%nArtifacts generated successfully? %s", done);
             if (!done) {
                 throw new RuntimeException("Artifact generation failed");
@@ -226,9 +217,9 @@
 
         OutputAnalyzer output = null;
         try {
-            //For automated/explicit module type copy the corresponding
-            //jars to module base folder, which will be considered as
-            //module base path during execution.
+            // For automated/explicit module types, copy the corresponding
+            // jars to module base folder, which will be considered as
+            // module base path during execution.
             if (!(cModuleType == MODULE_TYPE.UNNAMED
                     && sModuletype == MODULE_TYPE.UNNAMED)) {
                 copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
@@ -237,20 +228,19 @@
 
             System.out.format("%nExecuting java client with required"
                     + " custom service in class/module path.");
-            String mName = getModuleName(cModuleType, cJarPath,
-                    C_PKG);
+            String mName = getModuleName(cModuleType, cJarPath, C_PKG);
             Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED
                     || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null;
             String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
                     sJarPath);
+            Map<String, String> vmArgs = getVMArgs(sModuletype,
+                    getModuleName(sModuletype, sJarPath, S_PKG));
             output = ProcessTools.executeTestJava(
-                    getJavaCommand(cmBasePath, cPath, mName, MAIN, VM_ARGS,
+                    getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
                             args)).outputTo(System.out).errorTo(System.out);
         } finally {
-            //clean module path so that the modulepath can hold only
-            //the required jars for next run.
+            // Clean module path to hold required jars for next run.
             cleanModuleBasePath(M_BASE_PATH);
-            System.out.println("--------------------------------------------");
         }
         return output;
     }
@@ -260,9 +250,9 @@
      * based on client/service module type.
      */
     @Override
-    public Path findJarPath(boolean service, MODULE_TYPE moduleType,
+    public Path findJarPath(boolean isService, MODULE_TYPE moduleType,
             boolean addMetaDesc, boolean dependsOnServiceModule) {
-        if (service) {
+        if (isService) {
             if (moduleType == MODULE_TYPE.EXPLICIT) {
                 if (addMetaDesc) {
                     return MS_WITH_DESCR_JAR;
@@ -277,11 +267,12 @@
                 }
             }
         } else {
+            // Choose corresponding client jar using dependent module
             if (moduleType == MODULE_TYPE.EXPLICIT) {
                 if (dependsOnServiceModule) {
                     return MC_JAR;
                 } else {
-                    return MC_DEPENDS_ON_AUTO_SERVICE_JAR;
+                    return MCN_JAR;
                 }
             } else {
                 return C_JAR;
@@ -289,4 +280,20 @@
         }
     }
 
+    /**
+     * VM argument required for the test.
+     */
+    private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
+            String addModName) throws IOException {
+        final Map<String, String> vmArgs = new LinkedHashMap<>();
+        vmArgs.put("-Duser.language=", "en");
+        vmArgs.put("-Duser.region=", "US");
+        vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve(
+                "jaas.conf").toFile().getCanonicalPath());
+        if (addModName != null && sModuletype == MODULE_TYPE.AUTO) {
+            vmArgs.put("-addmods ", addModName);
+        }
+        return vmArgs;
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java	Wed Jul 27 13:33:55 2016 +0000
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Arrays;
+import java.io.IOException;
+import java.lang.module.ModuleDescriptor;
+import java.util.ArrayList;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.OutputAnalyzer;
+import org.testng.annotations.BeforeTest;
+
+/**
+ * @test
+ * @bug 8151654
+ * @library /lib/testlibrary
+ * @library /java/security/modules
+ * @build CompilerUtils JarUtils
+ * @summary Test custom JAAS callback handler with all possible modular option.
+ * @run testng JaasModularDefaultHandlerTest
+ */
+public class JaasModularDefaultHandlerTest extends ModularTest {
+
+    private static final Path S_SRC = SRC.resolve("TestCallbackHandler.java");
+    private static final String MODULAR = "M";
+    private static final String S_PKG = "handler";
+    private static final String S_JAR_NAME = S_PKG + JAR_EXTN;
+    private static final String MS_JAR_NAME = MODULAR + S_PKG + JAR_EXTN;
+    private static final String HANDLER = S_PKG + ".TestCallbackHandler";
+
+    private static final Path C_SRC
+            = SRC.resolve("JaasClientWithDefaultHandler.java");
+    private static final Path CL_SRC = SRC.resolve("TestLoginModule.java");
+    private static final String C_PKG = "login";
+    private static final String C_JAR_NAME = C_PKG + JAR_EXTN;
+    private static final String MCN_JAR_NAME
+            = MODULAR + C_PKG + "NoMUse" + JAR_EXTN;
+    private static final String MC_JAR_NAME = MODULAR + C_PKG + JAR_EXTN;
+
+    private static final Path BUILD_DIR = Paths.get(".").resolve("build");
+    private static final Path COMPILE_DIR = BUILD_DIR.resolve("bin");
+    private static final Path S_BUILD_DIR = COMPILE_DIR.resolve(S_PKG);
+    private static final Path C_BLD_DIR = COMPILE_DIR.resolve(C_PKG);
+    private static final Path M_BASE_PATH = BUILD_DIR.resolve("mbase");
+    private static final Path ARTIFACTS_DIR = BUILD_DIR.resolve("artifacts");
+
+    private static final Path S_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(S_PKG);
+    private static final Path S_JAR = S_ARTIFACTS_DIR.resolve(S_JAR_NAME);
+    private static final Path MS_JAR = S_ARTIFACTS_DIR.resolve(MS_JAR_NAME);
+
+    private static final Path C_ARTIFACTS_DIR = ARTIFACTS_DIR.resolve(C_PKG);
+    private static final Path C_JAR = C_ARTIFACTS_DIR.resolve(C_JAR_NAME);
+    private static final Path MC_JAR = C_ARTIFACTS_DIR.resolve(MC_JAR_NAME);
+    private static final Path MCN_JAR = C_ARTIFACTS_DIR.resolve(MCN_JAR_NAME);
+
+    private static final String MAIN = C_PKG + ".JaasClientWithDefaultHandler";
+    private static final List<String> M_REQUIRED = Arrays.asList("java.base",
+            "jdk.security.auth");
+
+    private static final String CLASS_NOT_FOUND_MSG
+            = "java.lang.ClassNotFoundException: handler.TestCallbackHandler";
+    private static final String NO_FAILURE = null;
+
+    /**
+     * Generates Test specific input parameters.
+     */
+    @Override
+    public Object[][] getTestInput() {
+
+        List<List<Object>> params = new ArrayList<>();
+        String[] args = new String[]{HANDLER};
+        // PARAMETER ORDERS -
+        // Client Module Type, Service Module Type,
+        // Service META Descriptor Required,
+        // Expected Failure message, Client arguments
+        params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.EXPLICIT,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.AUTO,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.EXPLICIT, MODULE_TYPE.UNNAMED,
+                false, NO_FAILURE, args));
+
+        params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.EXPLICIT,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.AUTO,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.AUTO, MODULE_TYPE.UNNAMED,
+                false, NO_FAILURE, args));
+
+        params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.EXPLICIT,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.AUTO,
+                false, NO_FAILURE, args));
+        params.add(Arrays.asList(MODULE_TYPE.UNNAMED, MODULE_TYPE.UNNAMED,
+                false, NO_FAILURE, args));
+        return params.stream().map(p -> p.toArray()).toArray(Object[][]::new);
+    }
+
+    /**
+     * Pre-compile and generate the artifacts required to run this test before
+     * running each test cases.
+     */
+    @BeforeTest
+    public void buildArtifacts() {
+
+        boolean done = true;
+        try {
+            done = CompilerUtils.compile(S_SRC, S_BUILD_DIR);
+            // Generate modular/regular handler jars.
+            generateJar(true, MODULE_TYPE.EXPLICIT, MS_JAR, S_BUILD_DIR, false);
+            generateJar(true, MODULE_TYPE.UNNAMED, S_JAR, S_BUILD_DIR, false);
+            // Compile client source codes.
+            done &= CompilerUtils.compile(C_SRC, C_BLD_DIR);
+            done &= CompilerUtils.compile(CL_SRC, C_BLD_DIR);
+            // Generate modular client jar with explicit dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MC_JAR, C_BLD_DIR, true);
+            // Generate modular client jar without any dependency
+            generateJar(false, MODULE_TYPE.EXPLICIT, MCN_JAR, C_BLD_DIR, false);
+            // Generate regular client jar
+            generateJar(false, MODULE_TYPE.UNNAMED, C_JAR, C_BLD_DIR, false);
+            System.out.format("%nArtifacts generated successfully? %s", done);
+            if (!done) {
+                throw new RuntimeException("Artifact generation failed");
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Generate modular/regular jar based on module type for this test.
+     */
+    private void generateJar(boolean isService, MODULE_TYPE moduleType,
+            Path jar, Path compilePath, boolean depends) throws IOException {
+
+        ModuleDescriptor mDescriptor = null;
+        if (isService) {
+            mDescriptor = generateModuleDescriptor(isService, moduleType, S_PKG,
+                    S_PKG, null, null, null, M_REQUIRED, depends);
+        } else {
+            mDescriptor = generateModuleDescriptor(isService, moduleType, C_PKG,
+                    C_PKG, null, null, S_PKG, M_REQUIRED, depends);
+        }
+        generateJar(mDescriptor, jar, compilePath);
+    }
+
+    /**
+     * Holds Logic for the test client. This method will get called with each
+     * test parameter.
+     */
+    @Override
+    public OutputAnalyzer executeTestClient(MODULE_TYPE cModuleType,
+            Path cJarPath, MODULE_TYPE sModuletype, Path sJarPath,
+            String... args) throws Exception {
+
+        OutputAnalyzer output = null;
+        try {
+            // For automated/explicit module types, copy the corresponding
+            // jars to module base folder, which will be considered as
+            // module base path during execution.
+            if (!(cModuleType == MODULE_TYPE.UNNAMED
+                    && sModuletype == MODULE_TYPE.UNNAMED)) {
+                copyJarsToModuleBase(cModuleType, cJarPath, M_BASE_PATH);
+                copyJarsToModuleBase(sModuletype, sJarPath, M_BASE_PATH);
+            }
+
+            System.out.format("%nExecuting java client with required"
+                    + " custom service in class/module path.");
+            String mName = getModuleName(cModuleType, cJarPath, C_PKG);
+            Path cmBasePath = (cModuleType != MODULE_TYPE.UNNAMED
+                    || sModuletype != MODULE_TYPE.UNNAMED) ? M_BASE_PATH : null;
+            String cPath = buildClassPath(cModuleType, cJarPath, sModuletype,
+                    sJarPath);
+            Map<String, String> vmArgs = getVMArgs(sModuletype, cModuleType,
+                    getModuleName(sModuletype, sJarPath, S_PKG));
+            output = ProcessTools.executeTestJava(
+                    getJavaCommand(cmBasePath, cPath, mName, MAIN, vmArgs,
+                            args)).outputTo(System.out).errorTo(System.out);
+        } finally {
+            // Clean module path to hold required jars for next run.
+            cleanModuleBasePath(M_BASE_PATH);
+        }
+        return output;
+    }
+
+    /**
+     * Decide the pre-generated client/service jar path for each test case
+     * based on client/service module type.
+     */
+    @Override
+    public Path findJarPath(boolean depends, MODULE_TYPE moduleType,
+            boolean addMetaDesc, boolean dependsOnServiceModule) {
+        if (depends) {
+            if (moduleType == MODULE_TYPE.EXPLICIT) {
+                return MS_JAR;
+            } else {
+                return S_JAR;
+            }
+        } else {
+            // Choose corresponding client jar using dependent module
+            if (moduleType == MODULE_TYPE.EXPLICIT) {
+                if (dependsOnServiceModule) {
+                    return MC_JAR;
+                } else {
+                    return MCN_JAR;
+                }
+            } else {
+                return C_JAR;
+            }
+        }
+    }
+
+    /**
+     * VM argument required for the test.
+     */
+    private Map<String, String> getVMArgs(MODULE_TYPE sModuletype,
+            MODULE_TYPE cModuleType, String addModName) throws IOException {
+        final Map<String, String> vmArgs = new LinkedHashMap<>();
+        vmArgs.put("-Duser.language=", "en");
+        vmArgs.put("-Duser.region=", "US");
+        vmArgs.put("-Djava.security.auth.login.config=", SRC.resolve(
+                "jaas.conf").toFile().getCanonicalPath());
+        if (addModName != null
+                && !(cModuleType == MODULE_TYPE.EXPLICIT
+                && sModuletype == MODULE_TYPE.EXPLICIT)) {
+            vmArgs.put("-addmods ", addModName);
+        }
+        return vmArgs;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/security/auth/login/modules/TestCallbackHandler.java	Wed Jul 27 13:33:55 2016 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package handler;
+
+import java.io.IOException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class TestCallbackHandler implements CallbackHandler {
+
+    private static final String USER_NAME = "testUser";
+    private static final String PASSWORD = "testPassword";
+
+    @Override
+    public void handle(Callback[] callbacks) throws IOException,
+            UnsupportedCallbackException {
+        System.out.println("TestCallbackHandler will get resolved through"
+                + " auth.login.defaultCallbackHandler property.");
+        for (Callback callback : callbacks) {
+            if (callback instanceof NameCallback) {
+                ((NameCallback) callback).setName(USER_NAME);
+            } else if (callback instanceof PasswordCallback) {
+                ((PasswordCallback) callback).setPassword(
+                        PASSWORD.toCharArray());
+            } else {
+                throw new UnsupportedCallbackException(callback);
+            }
+        }
+    }
+
+}
--- a/test/lib/testlibrary/jdk/testlibrary/Platform.java	Wed Jul 27 08:33:15 2016 -0400
+++ b/test/lib/testlibrary/jdk/testlibrary/Platform.java	Wed Jul 27 13:33:55 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,10 +58,6 @@
         return vmName.endsWith(" Minimal VM");
     }
 
-    public static boolean isEmbedded() {
-        return vmName.contains("Embedded");
-    }
-
     public static boolean isTieredSupported() {
         return compiler.contains("Tiered Compilers");
     }