Reputation: 32113
I have a button in my program that, when pressed, is supposed to take you to my wiki page about the program. I used the following line to do so:
java.awt.Desktop.getDesktop().browse(new java.net.URI("http://supuh.wikia.com/wiki/BHT"));
The problem is that, no matter what environment in which the program is run, I always get the following error:
java.security.AccessControlException: access denied (java.awt.AWTPermission showWindowWithoutWarningBanner)
does anyone know how I can fix this? Note that this only works in the one program. Any other program I make can use the same method with no problem.
At the start of my program, this hook is added. The program runs fine without it...
System.setSecurityManager(new SecurityManager()
{
@Override
public void checkExit(int status)
{
closeFile(status);
}
});
this hook is needed, but the browse(URI uri)
method in question won't work with it. Solutions?
Upvotes: 4
Views: 3161
Reputation: 328624
Instead of using your own SecurityManager
, install a shutdown hook instead:
Runnable runnable = new Runnable() {
closeFile(status);
}
Runtime.getRuntime().addShutdownHook(new Thread (runnable, "Close file"));
Upvotes: 0
Reputation: 597124
This means you are running with a security manager:
SecurityException
- if a security manager exists and it denies the AWTPermission("showWindowWithoutWarningBanner") permission, or the calling thread is not allowed to create a subprocess; and not invoked from within an applet or Java Web Started application
If this is an applet, or a Java Web Start app - sign your jar.
Update Adding a security manager to detect program exit is wrong. There are multiple ways to do this properly. In your case I guess this would be most appropriate:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
closeFile();
}
));
Swing-specific solutions are:
if you don't have to perform extra actions, use frame.setDefaultCloseAction(Frame.EXIT_ON_CLOSE)
use addWindowStateListener
and check for WindowEvent.WINDOW_CLOSED
That said, two notes:
you must not hold files open for a long time. Use try/catch/finally
to open and close them whenever they are needed.
if you really need a security manager at some point, make sure you override the appropriate method of the SecurityManager
that checks whether you can open the link. (won't tell you which one, so that you are not tempted to jump onto this solution, which is wrong)
To summarize, I'd go for setDefaultActionOnClose
, and close each file right after I finish reading/writing it.
Update 2: After you linked to your original question describing what exactly are you trying to achieve, things change a bit. You are trying to prevent exit, so you do need a SecurityManager
. This makes it so that you should override the checkPermission
method and do nothing there (i.e. don't throw exceptions), at least when these permissions are checked (they are checked when browse is called):
new AWTPermission("showWindowWithoutWarningBanner")
new FilePermission("<<ALL FILES>>", SecurityConstants.FILE_EXECUTE_ACTION)
Update 3 Here's how exactly to override the method:
@Override
public void checkPermission(Permission permission) {
if (permission instanceof AWTPermission) {
if (permission.getName().equals("showWindowWithoutWarningBanner")) {
return;
}
}
if (permission instanceof FilePermission) {
if (permission.getActions().equalsIgnoreCase("execute")) {
return;
}
}
java.security.AccessController.checkPermission(permission);
}
(you can go without the outer if-s)
Update 4 The above method will work only if you have given permissions to your program. Otherwise it is a not-well documented behaviour of the JVM that overriding security managers are not allowed to be unprivileged. Take a look at this report - the comments say how to work it around.
To make your life simpler, you can simply @Override public void checkPermission(..)
with an empty method body.
Upvotes: 7