8151654: Additional modular test for "auth.login.defaultCallbackHandler"
authorssahoo
Tue, 26 Jul 2016 09:53:35 +0800
changeset 39774 25d5618feb3c
parent 39773 0392b8791906
child 39775 37b3d7bf72ee
8151654: Additional modular test for "auth.login.defaultCallbackHandler" Reviewed-by: mchung, weijun
jdk/test/java/security/Provider/SecurityProviderModularTest.java
jdk/test/java/security/modules/ModularTest.java
jdk/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java
jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java
jdk/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java
jdk/test/javax/security/auth/login/modules/TestCallbackHandler.java
--- a/jdk/test/java/security/Provider/SecurityProviderModularTest.java	Mon Jul 25 05:39:05 2016 +0000
+++ b/jdk/test/java/security/Provider/SecurityProviderModularTest.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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/jdk/test/java/security/modules/ModularTest.java	Mon Jul 25 05:39:05 2016 +0000
+++ b/jdk/test/java/security/modules/ModularTest.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/login/modules/JaasClientWithDefaultHandler.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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/jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java	Mon Jul 25 05:39:05 2016 +0000
+++ b/jdk/test/javax/security/auth/login/modules/JaasModularClientTest.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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/jdk/test/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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/jdk/test/javax/security/auth/login/modules/TestCallbackHandler.java	Tue Jul 26 09:53:35 2016 +0800
@@ -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);
+            }
+        }
+    }
+
+}