JDK-8198352 : java.util.MissingResourceException: sun.security.util.AuthResources when trying to use com.sun.security.auth.module.UnixLoginModule
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 9,10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2018-02-14
  • Updated: 2018-11-30
  • Resolved: 2018-07-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12
11 b22Fixed 12Fixed
Description
FULL PRODUCT VERSION :
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux tichy 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux


EXTRA RELEVANT SYSTEM CONFIGURATION :
Start Application with:
-Djava.security.auth.login.config=jaas_unix_bug.config
-Djava.security.manager
-Djava.security.policy=jaas_unix_bug.policy


Content of jaas_unix_bug.config (see attached source)

Java9JAASUnixBug {
    com.sun.security.auth.module.UnixLoginModule required debug=true;
};

Content of jaas_unix_bug.policy (see attached source)

grant {
   permission javax.security.auth.AuthPermission "modifyPrincipals";
   permission javax.security.auth.AuthPermission "createLoginContext";
   permission javax.security.auth.AuthPermission "doAsPrivileged";

};

grant Principal com.sun.security.auth.UnixPrincipal "<enter your accounts user name here>" {
   permission java.util.PropertyPermission "os.name", "read";
   permission java.util.PropertyPermission "java.version", "read";
};

A DESCRIPTION OF THE PROBLEM :
When starting the attached application, the expected behaviour is to output the values of the two system properties named in the policy file (when your user account is granted permission to read them in the policy file). This happens when using Java 8.

With Java 9 however, an exception is thrown like this:

java.util.MissingResourceException: Can't find bundle for base name sun.security.util.AuthResources, locale en_US
	at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1679)
        at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1572)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1546)
	at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:838)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
	at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
	at java.base/sun.security.util.ResourcesMgr.getAuthResourceString(ResourcesMgr.java:44)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.toString(UnixNumericGroupPrincipal.java:149)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.hashCode(UnixNumericGroupPrincipal.java:198)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.put(HashMap.java:612)
	at java.base/java.util.HashSet.add(HashSet.java:220)
	at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)
	at java.base/java.util.HashSet.<init>(HashSet.java:120)
	at java.base/javax.security.auth.SubjectDomainCombiner.combine(SubjectDomainCombiner.java:221)
	at java.base/java.security.AccessControlContext.optimize(AccessControlContext.java:608)
	at java.base/java.security.AccessController.checkPermission(AccessController.java:894)
	at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:558)
	at java.base/java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
	at java.base/java.lang.System.getProperty(System.java:774)
	at de.elbosso.scratch.misc.Java9JAASUnixBug$1.run(Java9JAASUnixBug.java:29)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:484)
	at de.elbosso.scratch.misc.Java9JAASUnixBug.main(Java9JAASUnixBug.java:39)
Caused by: java.lang.IllegalStateException: Recursive update
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1774)
	at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
	at java.base/sun.security.util.ResourcesMgr.getAuthResourceString(ResourcesMgr.java:44)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.toString(UnixNumericGroupPrincipal.java:149)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.hashCode(UnixNumericGroupPrincipal.java:198)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.put(HashMap.java:612)
	at java.base/java.util.HashSet.add(HashSet.java:220)
	at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)
	at java.base/java.util.HashSet.<init>(HashSet.java:120)
	at java.base/javax.security.auth.SubjectDomainCombiner.combine(SubjectDomainCombiner.java:221)
	at java.base/java.security.AccessControlContext.optimize(AccessControlContext.java:608)
	at java.base/java.security.AccessController.getContext(AccessController.java:837)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:424)
	at java.base/java.util.ResourceBundle$ResourceBundleProviderHelper.loadResourceBundle(ResourceBundle.java:3585)
	at java.base/java.util.ResourceBundle.loadBundle(ResourceBundle.java:1834)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1764)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1718)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1718)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1652)
	... 23 more

REGRESSION.  Last worked in version 8u151

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile the attached source 
edit jaas_unix_bug.policy and enter the actual username 
execute the application as follows:
java Java9JAASUnixBug -Djava.security.auth.login.config=jaas_unix_bug.config -Djava.security.manager -Djava.security.policy=jaas_unix_bug.policy

If the application is run under Java 8 it works, under Java 9 it does so only if you give an additional command line parameter  -  this activates the workaround 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the expected behaviour is to output the values of the two system properties named in the policy file
ACTUAL -
java.util.MissingResourceException: Can't find bundle for base name sun.security.util.AuthResources, locale en_US
	at java.base/java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:2045)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1679)
        at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1572)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1546)
	at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:838)
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1719)
	at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
	at java.base/sun.security.util.ResourcesMgr.getAuthResourceString(ResourcesMgr.java:44)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.toString(UnixNumericGroupPrincipal.java:149)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.hashCode(UnixNumericGroupPrincipal.java:198)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.put(HashMap.java:612)
	at java.base/java.util.HashSet.add(HashSet.java:220)
	at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)
	at java.base/java.util.HashSet.<init>(HashSet.java:120)
	at java.base/javax.security.auth.SubjectDomainCombiner.combine(SubjectDomainCombiner.java:221)
	at java.base/java.security.AccessControlContext.optimize(AccessControlContext.java:608)
	at java.base/java.security.AccessController.checkPermission(AccessController.java:894)
	at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:558)
	at java.base/java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
	at java.base/java.lang.System.getProperty(System.java:774)
	at de.elbosso.scratch.misc.Java9JAASUnixBug$1.run(Java9JAASUnixBug.java:29)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/javax.security.auth.Subject.doAsPrivileged(Subject.java:484)
	at de.elbosso.scratch.misc.Java9JAASUnixBug.main(Java9JAASUnixBug.java:39)
Caused by: java.lang.IllegalStateException: Recursive update
	at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1774)
	at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
	at java.base/sun.security.util.ResourcesMgr.getAuthResourceString(ResourcesMgr.java:44)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.toString(UnixNumericGroupPrincipal.java:149)
	at jdk.security.auth/com.sun.security.auth.UnixNumericGroupPrincipal.hashCode(UnixNumericGroupPrincipal.java:198)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.put(HashMap.java:612)
	at java.base/java.util.HashSet.add(HashSet.java:220)
	at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352)
	at java.base/java.util.HashSet.<init>(HashSet.java:120)
	at java.base/javax.security.auth.SubjectDomainCombiner.combine(SubjectDomainCombiner.java:221)
	at java.base/java.security.AccessControlContext.optimize(AccessControlContext.java:608)
	at java.base/java.security.AccessController.getContext(AccessController.java:837)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:424)
	at java.base/java.util.ResourceBundle$ResourceBundleProviderHelper.loadResourceBundle(ResourceBundle.java:3585)
	at java.base/java.util.ResourceBundle.loadBundle(ResourceBundle.java:1834)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1764)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1718)
	at java.base/java.util.ResourceBundle.findBundle(ResourceBundle.java:1718)
	at java.base/java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1652)
	... 23 more

ERROR MESSAGES/STACK TRACES THAT OCCUR :
see above

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Set;

public class Java9JAASUnixBug
{
	public static void main(java.lang.String[] args) throws LoginException
	{
		javax.security.auth.login.LoginContext lc = new javax.security.auth.login.LoginContext("Java9JAASUnixBug");
		lc.login();
		javax.security.auth.Subject subject = lc.getSubject();
		Set<Principal> principals=subject.getPrincipals();
//Workaround start
		for(Principal principal:principals)
		{
			if(args.length>0)
				principal.toString();
		}
//Workaround end
		PrivilegedAction action = new java.security.PrivilegedAction()
		{
			@Override
			public Object run()
			{
				try
				{
					System.out.println(System.getProperty("java.version"));
					System.out.println(System.getProperty("os.name"));
				}
				catch(java.lang.Throwable t)
				{
					t.printStackTrace();
				}
				return null;
			}
		};
		Subject.doAsPrivileged(subject, action, null);
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
see attached source code between workaround start and workaround end (just start the example giving one or more command line parameters to activate the workaround)


Comments
To reproduce the issue, execute the attached test case with the security options stated in bug report. JDK 8u162- Pass JDK 9.0.4 + 11 - Fail JDK 10-ea+43 - Fail
19-02-2018