Problem with java.awt.Desktop - java

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.
Exit hook
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?

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.

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"));

Related

JavaFX 8 initialize method

So I am trying to do a chat type program using JavaFX for the GUI. I have it so a class that acts as a server will loop and keep adding client connections to it.
public void serverconnection()
{
// portnumber was saved from constructor
try (ServerSocket socket = new ServerSocket(this.portnumber))
{
// loop is a bool set to true
while (loop)
{
// this class extends Thread and has its own overwritten start method
new myclass(socket.accept()).start();
}
}
catch (IOException e)
{
System.exit(404);
}
}
so the problem is (I am assuming) was, this loop keeps looping until the program closes. but since I was calling this within the JavaFX's initialize method
public void initialize(URL url, ResourceBundle rb)
{
// constructor, nothing here is needed for this post
myclass z = new myclass(45234);
// problem here, since this has a loop, but
z.serverconnection();
// gui wont load till after this is done
// but serverconnection is only done after program ends
}
the problem with this is, apparently, the GUI will not load until AFTER initialize has finished, but it will not finish until program closes. After google searching, I could not find any fix for this. I need a way to call a method that will do all this, AFTER initialize method has finished. My client side class is similar to this, but the methods to connect on that are activated on events when clicking a login button. For this serverside one, I am trying to start without any interaction with the user. so is there a way to call a method or make this work AFTER initialize method has ran?
You might want to run this loop in a thread, so do something like
Thread t = new Thread(z::serverconnection)
t.start()
If you do this at the end of your initialization() method, it will run exactly then.
This will start a thread which runs forever; you might want to add a feature for interrupting the thread when the program is supposed to be terminated.
Remember that for changing anything in the GUI you need to sumbit a task via Platform.runLater(). This is because the GUI may only be modified from within that one thread. So in order to modify anything, you have to wrap that in a Runnable and submit it for execution.
You can do that in this way:
Platform.runLater(new Runnable() {
#Override
public void run() {
doWhateverNeedsToBeDone();
}
});
In Java 8, you can do anything of the following, depending on the extent of the work to be done:
Platform.runLater(() -> {
doWhateverNeedsToBeDone();
});
Platform.runLater(() -> doWhateverNeedsToBeDone());
Platform.runLater(this::doWhateverNeedsToBeDone);
The latter only works if doWhateverNeedsToBeDone() is a method of this.

UISpec4J and external application

I am trying to launch an external application for testing using UISpec4J.
Here are the questions and their answers I referred so far:
How to automate a swing java web start application which runs clicking a link into a web application, which is automated with Selenium WebDriver?
Getting all windows using UISpec4J
UISpec4J Capturing modal dialog, before the trigger finish
my.exe referred below is a Java application wrapped in exe using some tool. Internally it uses the jars and is Java GUI application.
This executable launches a splash screen first, then a dialog to choose where you want to connect to and after that main window is shown. Unless I can automate where I can connect to I won't get main window.
Based on these questions I have come up with following code fragments:
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
return WindowInterceptor.run(new Trigger() {
#Override
public void run() throws Exception {
// running jnlp by netx launcher
Runtime.getRuntime().exec("C:\\my.exe");
Thread.sleep(10000);
}
});
}
});
In the approach above I simple get "No window was shown" error.
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
final Window[] result = new Window[1];
WindowInterceptor
.init(new Trigger() {
#Override
public void run() throws Exception {
Runtime.getRuntime().exec("C:\\my.exe");
//Thread.sleep(10000);
}
})
//.processTransientWindow()
.process(new WindowHandler() {
public Trigger process(Window window) throws Exception {
result[0] = window;
return Trigger.DO_NOTHING;
}
})
.run();
return result[0];
}
});
In the second approach above, I still get "No window shown" error AND control never reaches to overriden "process" method.
I referred to http://www.uispec4j.org/reports/apidocs/org/uispec4j/interception/WindowInterceptor.html and recommended approach is to use init to capture modal dialog is init\process sequence.
To capture non-modal it is recommended that we should use following:
Window window = WindowInterceptor.run(panel.getButton("open").triggerClick());
But I have NO idea where and how I am supposed to call it..
From the first question I referred, mentioned above, we should be able to do that because the answer to it mentions launching jnlp application which is external application.
I tried with jre 6 update 0 and I can at least run test. In java update 37, from the third question I referred above, I get abstract method not implemented error.
What am I doing wrong? Any idea?
I am using latest UISpec4J package - version 2.4.
Thanks in advance,
-Neel.
I'm very new to UISpec4J but I'm guessing it needs to run in the same JVM in order to intercept and interact with the GUI components. When you start the exe file with exec, it will create a new process and a new, separate JVM. That'll not work, if I understand UISpec4J correctly.
Regarding the non-modal example, the documentation says "You would retrieve the window from within the test...", so in a setup method or in a test should work.

How to terminate a scheduled thread when JavaFX Runtime exits?

I'm looking over similar examples to this problem. We have a JavaFX app which runs some GUI updates via thread running from: ScheduledExecutorService::scheduleAtFixedRate.
This is similar to a couple of other questions. The two I recognised as most like my situation are these:
JavaFX Task threads not terminating
how to stop "JavaFX Application Thread"
The question I need to resolve, however, is about the next step. My target is for an embedded application and there's no opportunity to manually kill the JVM-task, or the other easy answers, etc. I'm afraid a reboot is reserved for something critically-serious.
We need to ensure that all threads are closed off in an orderly way. What I'm looking for is some kind of call back or event that lets me register a clean-up routine to close-down my stuff?
I was thinking that there ought to be 'something' in the base class, JavaFX javafx.application.Application to do the deed.
http://docs.oracle.com/javafx/2/api/javafx/application/Application.html
Is the Stop method something I might use or can I register to be called when there is a stop from my FXMLController?
At present when I run my JavaFX app from Netbeans, the JVM process persists. This stops any further build scripts and locks the JAR file. Netbeans gives you an option to kill the task. The true solution means that the application/JVM closes-down orderly and neatly.
(update) ... I looked into the javafx.Application class that you use to launch the JavaFX app. I implemented a Stop() method. Here I make sure that I've called Platform.exit() ...
/////
// #see
// -- http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#stop%28%29
//
public void stop()
{
Platform.exit();
}
This doesn't cure the problem when running from NetBeans. Sometimes you need to click the stop [X] button two times, but the process does stop when you use the kill button. If you are interested in progress this is reported as bug: [Bug 245284], there's a small clock example to demonstrate the problem. When you close the window, the NetBeans process running panel is still 'running'. You can't build because the JAR file is locked. At least we know to manually kill the development program.
Suggestions welcome . . .
I have a partial solution to cover fellow developers who get caught in this situation. Declare a stop() method in in your JavaFX app (called "MainApp" by the Netbeans Maven JavaFX template). There are questions of course, but first the method.
See: JavaFX Application
Stop is called at the end of your program. I had the call to call Platform.exit() to close-down JavaFX runtime. I've added a call to shutdown other active Executor threads, which I kept in an list for now, to test the solution.
public class MainApp extends Application
{
#Override
public void start(Stage stage) throws Exception
{
.....
}
/**
* Close down the application
* #see
* -- http://docs.oracle.com/javafx/2/api/javafx/application/Application.html#stop%28%29
**/
#Override
public void stop()
{
Platform.exit();
for( ScheduledExecutorService sched : activeExecutorServices )
{
sched.shutdown();
}
}
}//MainAppl class
So by commenting-out the call to shutdown and running my JavaFX program, the application finishes but won't exit, and Netbeans show a running task. You need to manually click on the kill-button in Netbeans.
Uncomment the shutdown() call. When the JavaFX application exits, it also dissappears from the Netbeans running jobs. That appears to be a resolotion.
The remaining questions:
What is the correct order between Platform.exit() and shutdown()?
With more than one ScheduledExecutorService does it matter which order is used to shut them-off? LIFO or FIFO?
Is there a better way?
Ought Netbeans be able to detect the 'process overrun' and report this as a problem. That at least leave you and I with the option to ignore it or fix the program.
Hopefyully that will assist the next someone who faces a similar problem :-)
you can use setOnCloseRequest
#Override
public void start(Stage primaryStage) {
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
ThreadPool.shutdown();
}
});
initGui(primaryStage);
initData();
}

Custom message when closing a part in Eclipse RCP 4

we have the following problem:
In our Eclipse RCP 4 application there are multiple parts and the parts are closable. When the user is closing a part there should be a custom pop-up (depending on some internal part state) which is asking the user if he really wants to close the part or not.
It seems to be not that easy to implement in Eclipse RCP 4 or we have just totally overseen something.
I'll just give you a short brieifing about the things we tried:
Use dirtable with a #persist method in the part. Though the problem is, we don't want this standard eclipse save dialog. So is there a way to override this?
public int promptToSaveOnClose(): This seemed to be promising but not for Eclipse 4 or is there a way to integrate it that way? Compare: http://e-rcp.blogspot.de/2007/09/prevent-that-rcp-editor-is-closed.html
Our last try was to integrate a custom part listener, simple example shown in the following:
partService.addPartListener(new IPartListener() {
public void partVisible(MPart part) {
}
public void partHidden(MPart part) {
partService.showPart(part, PartState.ACTIVATE);
}
public void partDeactivated(MPart part) {
}
public void partBroughtToTop(MPart part) {
}
public void partActivated(MPart part) {
}
});
The problem with this was we are running into a continuous loop. Something similar is posted over here in the last comment: Detect tab close in Eclipse editor
So I could write some more about this problem, but I think that's enough for the moment. If you need some more input just give me a hint.
Thanks for helping.
The save prompt is generated by the ISaveHandler registered in the context of the MWindow containing the MPart. You can write your own ISaveHandler and set it in the window context to replace the default.
You might also want to look at the IWindowCloseHandler also in the window context.
Thanks greg, this has helped and I was able to achieve changing the pop-up when the user closes a part. Here's a short description of what I've done:
Use the MDirtyable for marking the part as dirty whenever it's needed.
Create a custom save handler which implements ISaveHandler (when a part got closed the save method is called). Add the additional logic to this handler (e.g. a custom message dialog)
Register this handler at application start-up (I just chose a method which is called at the start-up):
#Inject
private MWindow window;
...
ISaveHandler saveHandler = new CustomSaveHandler(shell);
window.getContext().set(ISaveHandler.class, saveHandler);
Note that the registration via a model processor was sadly not that easy because the model processor is called too early. (Take a look at: http://www.eclipse.org/forums/index.php/t/369989/)
The IWindowCloseHandler is just needed when the complete window is closed, though this was not an requirement for us :).

keyReleases are simulating keyPresses in Linux (java Swing GUI)

I have a kiosk GUI application I'm working on and it requires me to block users from being able to Alt-Tab out of the fullscreen window. I posted a question about this a while back and a member helped me with some code, which worked perfectly under a Windows environment.
Here it is:
public class TabStopper implements Runnable {
private boolean isWorking = false;
private MenuFrame parent;
public TabStopper(MenuFrame parent) {
this.parent = parent;
new Thread(this, "TabStopper").start();
}
public void run() {
this.isWorking = true;
Robot robot;
try {
robot = new Robot();
while (isWorking) {
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_TAB);
parent.requestFocus();
Thread.sleep(10);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop() {
this.isWorking = false;
}
public boolean isWorking() {
return this.isWorking;
}
}
However, I need this to be able to work in Linux as well. I made an executable jar from the source and brought it into Linux. Everything worked except the Alt and Tab keys were being constantly pressed. The buttons on my GUI were constantly being cycled and I was able to open a terminal (I set a backdoor in the application during testing in case something like this happens) which wouldn't let me type anything because Tab lists all the files in the current directory.
Could anyone tell me if there would be a fix that would work in both Linux and Windows environments. However, if I had to choose, I would go for Linux.
EDIT: I can also confirm that the Alt key is being "pressed". What's with this weird behaviour?
Forget grabbing Alt+Tab with hacks like this. It is a bad hack and it is error-prone. There are also so many other hotkey combinations.
For linux you have two options:
Use a minimal window manager or no window manager at all. For example, with fluxbox you can remove all key bindings alltogether and you can also make your application maximise by default, etc. You can empty the desktop menus such that the user gains no control even when your application crashes. This is a clean solution that really solves your problem instead of some parts of it. There are many ways to fiddle with the system other than Alt+Tab.
Grab input controls completely. This is what games do. For example libSDL does it for you and there are java wrappers for the functionality as well. This should also work as expected, except you use a window manager that does not allow input control grabbing per default (I don't know of any).

Categories