I'm getting an AccessControlException. What's wrong?
Even though I knew that J2EE itself includes a JMS provider, I was trying to
use JMQ's broker as the provider from a Bean. I had no problem doing JNDI
lookup of the TopicConnectionFactory that I deployed through "jmqobjmgr"
(into a local file). However, when I try to use it to create the connection,
I got java.security.AccessControlException. Based on the "Administration
Guide 2.0", I've done following setup but the failure stays. Your comment
and help will be highly appreciated. Thank!
1. jmqobjmgr add -tf -l "myTCF" -r
"java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory" -r
"java.naming.provider.url=file:///d:/tmp" -r
"java.naming.security.authentication=none"
2. Make sure there is a configured user "guest" (u=guest, p=guest,
g=anonymous)
3. Code:
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.fscontext.RefFSContextFa
ctory");
p.put(Context.PROVIDER_URL,"file:///d:/tmp");
p.put(Context.SECURITY_PRINCIPAL,"guest");
p.put(Context.SECURITY_CREDENTIALS,"guest");
Context ctx = new InitialContext(p);
TopicConnectionFactory TCF = (TopicConnectionFactory)
ctx.lookup("MyTCF");
System.out.println(TCF.toString());//Get it correctly here.
TopicConnection tc = TCF.createTopicConnection("guest", "guest");
// EXCEPTION HERE!!
I cut-and-paste the screen dump from J2EE as
follows. Note that my program starts at the stack frame
"JMSLayer.asyncSend".
The broker terminal only display one extra info:
[25/Apr/2001:16:33:05 PDT] [B1000]: Accepted connection from Connection
[Connect
ionID[d0249442:0:988241585215]]:tcp connection to
Socket[addr=localhost/127.0.0.
1,port=2207,localport=2196]. Connection count=1
Actually, I tried createConnection() first and since it didn't work I tried
to explicitly specify the default username/password myself. No difference in
terms of the failing result.
From the 1.3 javadocs (java.lang.RuntimePermission):
-
modifyThreadGroup:
modification of thread groups, e.g., via calls to ThreadGroup destroy,
getParent, resume, setDaemon, setMaxPriority, stop, and suspend methods
Also,
modifyThread:
Modification of threads, e.g., via calls to Thread stop, suspend, resume,
setPriority, and setName methods
-
Trouble is, even if you don't use ThreadGroups explicitly and simply use
new Thread();
I think ThreadGroups *are* modified - the new thread is added to
the running thread's ThreadGroup.
As you would expect, our JMS implementation does use threads.
I think you need to add:
permission java.lang.RuntimePermission "modifyThreadGroup";
permission java.lang.RuntimePermission "modifyThread";
to the policy file.
Let me know how if/when this gets resolved. We should definitely
add this type of info into a FAQ.
I've been trying to run a standalone app with a security manager
and security policy file.
You can basically do this via:
java
-D"java.security.manager"
-D"java.security.policy==file:/tmp/server.policy"
MyClassName
The -D"java.security.manager" line is to indicate to the VM that:
- yes, you want a security mgr to be used to enforce security
(not the default when an application is run via 'java ...')
- use the default built-in security mgr. If you want to use
a specific security mgr, like J2EE's, I assume you need to do:
java
-D"java.security.manager=com.sun.enterprise.J2EESecurityManager"
-D"java.security.policy==file:/tmp/server.policy"
MyClassName
with CLASSPATH set properly of course. I echoed the value of
the relevant CLASSPATH in the j2ee script and pasted it into
my test app's run script.
I did this because it's easier to test (at least for me) changes to a
policy file as compared to running the j2ee server. My initial run showed:
java.security.AccessControlException: access denied
(java.lang.RuntimePermission
modifyThreadGroup )
just like what you see. Upon adding the line
permission java.lang.RuntimePermission "modifyThreadGroup";
to the policy file, things work. I also added:
permission java.lang.RuntimePermission "modifyThread";
to be safe...