Closing browser opened using java.awt.Desktop - java

I wrote a simple Java program to open a specific webpage when the program is run. I need to close it again after a given amount of time. Here is the function I wrote and am using to open the page:
public static void openWebpage(String uri) throws Exception {
java.awt.Desktop.getDesktop().browse(new java.net.URI(uri));
}
Is there a way to close that webpage programatically? I already have another thread acting as a timer, so I simply need to close the webpage once the timer runs out.

Related

Call to Reader.Capture() in DigitalPersona U.are.U SDK does not return

I am developing an application for a DigitalPersona U.are.U 4500 fingerprint reader and using the U.are.U 2.2.3 SDK Java API.
The sample Java application that ships with the SDK works flawlessly.
However, when I try to do the same thing in my own sample application, the call to the Reader.Capture() method never returns, even though I can see the reader flashing when recording my fingerprint.
Below is a variation on the sample code I have tried with.
Other things I have tried:
Running the capture code in an instance of the class (i.e. not in a static context)
Running the capture operation in its own thread as well, but the results are the same.
Using the CaptureThread class from the demo application
The only difference I can see between my sample and the SDK sample app is that the latter is a graphical application. But why would that make a difference?
Unplugging the device causes the call to fail with an exception. That is about the only way I can get it to return.
import com.digitalpersona.uareu.*;
public class Main{
static Reader r;
public static void main(String[] args) {
try {
// Pick first available reader
ReaderCollection rc = UareUGlobal.GetReaderCollection();
rc.GetReaders();
r = rc.get(0);
if (r==null)
return;
// Open Reader
r.Open(Reader.Priority.COOPERATIVE);
System.out.println(r.GetStatus().status); // Outputs READY
// The following call just hangs and never returns...
Reader.CaptureResult
cr = r.Capture(Fid.Format.ISO_19794_4_2005, Reader.ImageProcessing.IMG_PROC_DEFAULT, 500, -1);
System.out.println(cr.quality.name()); // Just to test
} catch (UareUException e) {
e.printStackTrace();
}
}
}
The last two parameters, the two ints, passed to the Capture method are the resolution and the timeout respectively; passing -1 for the timeout blocks indefinitely. This is taken from the sample application as well.
I finally managed to get an example working.
Strange as it may seem, it only works in the context of a Java GUI application.
So, simply extending a JFrame and starting the reader capture on a separate thread seems to be sufficient.
This requirement is not specified anywhere in the SDK documentation that I can see.
UPDATE
It seems the problem is worse than I initially thought. Not only must the API be called in the context of a Java GUI application, but the GUI must also be in focus, otherwise the capture call simply does not return.
I have verified this with the example SDK applications. The Capture() method does not return if the apps are not in focus. This also applies to the C# examples, where the windows must be in focus, which suggests that this is built into the DLLs that ship with the solution.
This is terrible for our scenario, where we want to develop a local service that a browser can communicate with because, while the browser is in focus, obviously the Java application is not.
I faced the similar issue and it can be fixed by opening a reader in exclusive mode as below,
m_reader.Open(Reader.Priority.EXCLUSIVE);
Refer to below lines from documents,
public static final Reader.Priority COOPERATIVE
Client uses this priority to open reader in cooperative mode. Multiple clients with this priority are allowed. Client receives captured images if it has window with focus.
public static final Reader.Priority EXCLUSIVE
Client uses this priority to open reader exclusively. Only one client with this priority is allowed.

How to kill the browser instance (chrome) that was opened by web driver previously

I want to kill the browser instance (chrome) that was opened by web driver previously. How would I do that? In my code below, I intentionally didn't want to include quit() or close() as I want to leave the browser open. So every time I execute or run this program, I want to kill/close the previously opened browser and then start a new instance and leave it on. As a result, only one instance of browser should be open at a time. I am using Mac.
public static void main(String[] args){
String website = "http://www.google.com";
System.setProperty(".....");
WebDriver driver = new ChromeDriver();
driver.get(website);
}
The behaviour atm is that everytime I execute this, chrome instance will just pile up. What is the best way to avoid this? I am not doing this for testing purpose. I'm doing this because I want to automate a task. Thanks.
You can try out this code :
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\Automation\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com/");
try{
Runtime.getRuntime().exec("TASKKILL /F /IM chrome.exe");
}
catch(IOException io){
System.out.println(io.getMessage());
}
}
Note : It will kill all instances of chrome that was previously opened along with the newly opened instance.
If I understand correctly, you are trying to automate a part of the flow, then let the automation program exit leaving the browser open for completing rest of the steps manually. In this case, the best way to ensure only one such window is open would be to keep the automation script idling until you are done with with manual task. Something like this at end of your main function:
try {
while(true) {
Thread.sleep(1000);
driver.getCurrentUrl();
}
} catch(Exception e) {}
Would ensure that the program remains alive as long as the browser window is open. You can continue manual process in the browser. Once you are done, you can close the browser, which would automatically end this process. Or before starting the new task, you kill the old one with ^c, which in turn closes the browser.
The second option without keeping the automation script idling, would be to find the process id of newly created browser instance. You can save the process id in some file in temporary folder. Every time your script starts, it'd check the the file, read pid from it, and if the process id exists, try to kill it before spawning a new browser window.

Launch Opera and Wait Until it is Closed [duplicate]

Question
I want to start the Firefox web browser as process to visit a specific website, then wait until it is closed.
A special situation is that the browser may already be open and running, as the user may have visited some website already.
In that case, the browser would probably open a new tab in an existing window and the newly launched process will be terminated immediately. This should not confuse my waiting process: Either, I want a new browser window (if that can somehow be enforced, maybe via command line arguments) and wait until that is closed, or keep the existing browser window and wait until all the tabs resulting from my process are closed.
Environment
I think it doesn't matter, but my programming environment is Java and you can assume that I know the path of the browser.
Example
The only browser for which I can obtain the expected behavior is Internet Explorer (sigh.). Here, I need to basically create a new batch script in a temp folder with something like
start /WAIT "" "C:\Program Files\Internet Explorer\iexplore.exe" -noframemerging http://www.test.com/
I then run the batch script instead of directly the browser and delete it once I am finished with waiting.
Intended Process
To make the intended process clearer:
My program starts.
My program launches the Firefox browser as separate process and provides an URL to visit as argument to that process.
The Firefox browser runs asynchronously, as a new process, and visits the provided URL. So far, this is easy.
After launching the new process (the Firefox browser), my own program should wait for the said process to terminate. This is the hard part, as
Many modern browsers start multiple processes. I would need to wait for all of them.
Many modern browsers may somehow "detach" themselves from the process that I launched. Sorry, I don't know a better word, what I mean is: I start a process which then starts another process and terminates immediately while the other process keeps running. If I wait for the browser process originally started by my program, the waiting will be finished while the browser is still open.
A special case of the above is tabbed browsing as realized in many browsers: If the browser is already open (in a separate process started by the user) when I launch it, my newly started browser process may simple communicate the URL to visit to the existing process and terminate. The user is still on my provided URL while my program thinks she has closed the browser. This issue can maybe be forbidden by specifying a special command line argument, like noframemerging for the IE.
Once the browser has terminated or all tabs related to the URL I provide have been closed, my program will cease to wait and instead continue doing its business.
The use case is that I have a web application which can either run locally or on a server. If it is run locally, it launches a web server, then opens the browser to visit the entry page. Once the browser is closed, that web application should shut down as well. This works reliable for Internet Explorer, for all other cases, the user has to close the browser and then, explicitly, the web application. Thus, if I could wait reliably for Firefox to finish, this would make the user experience much better.
Solution Preferences:
Solutions are prefered in the following order
Anything which ships with the pure Java JRE. This includes special command line arguments to the browser.
Things that require me to, e.g., create a batch script (such as in the IE case.)
Anything that requires 3rd party open source libraries.
Anything that requires 3rth party closed source libraries.
Any platform independent answer (working both Windows and Linux) is prefered over platform-dependent ones.
Reason: In the ideal case, I would like to know what exactly is done and include it into my own code. As I want to support different browsers (see "PS" below), I would like to avoid having to include one library per browser. Finally, I cannot use commercial or closed source libraries, but if no better answer turns up, of course, I will honor any working solution with an accept. I will accept the first (reasonably nice) working answer of type "1". If answers of lower preference turn up, I will wait a few days before accepting the best one among them.
PS
I will launch a couple of similar questions for other browsers. Since I believe that browsers are quite different in the command line arguments they digest, the way the launch threads and sub-processes, I think this makes sense.
Similar question regarding Chrome: Launch Chrome and Wait Until it is Closed
Similar question regarding Opera: Launch Opera and Wait Until it is Closed
Similar question regarding Chromium: Launch Chromium and Wait Until it is Closed
Similar question regarding Edge: Launch Edge Browser and Wait Until it is Closed
Similar question regarding Safari: Launch Safari and Wait Until it is Closed
Here is a sample program that may somehow manages to demonstrate the capability of a selenium library to fulfill what you want. You need to download the selenium library and set it to your IDE first before you can run this program.
The program allows you to click a button. Then the firefox browser automatically opens and launch a website in a few seconds. Please wait while the website is loading. After that you may close the Firefox browser. The program shall also automatically close after 2 seconds.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.net.ConnectException;
import javax.swing.*;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class AnotherTest extends JFrame {
WebDriver driver;
JLabel label;
public AnotherTest() {
super("Test");
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width - 400) / 2, (screenSize.height - 100) / 2, 400, 100);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
quitApplication();
}
});
JButton jButton1 = new javax.swing.JButton();
label = new JLabel("");
JPanel panel = new JPanel(new FlowLayout());
panel.add(jButton1);
add(panel, BorderLayout.CENTER);
add(label, BorderLayout.SOUTH);
jButton1.setText("Open Microsoft");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
label.setText("Loading browser. Please wait..");
java.util.Timer t = new java.util.Timer();
t.schedule(new java.util.TimerTask() {
#Override
public void run() {
openBrowserAndWait();
}
}, 10);
}
});
}
private void openBrowserAndWait() {
driver = new FirefoxDriver();
String baseUrl = "https://www.microsoft.com";
driver.get(baseUrl);
java.util.Timer monitorTimer = new java.util.Timer();
monitorTimer.schedule(new java.util.TimerTask() {
#Override
public void run() {
while (true) {
checkDriver();
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
}
}
}
}, 10);
}
private void checkDriver() {
if (driver == null) {
return;
}
boolean shouldExit = false;
try {
label.setText(driver.getTitle());
} catch (NoSuchWindowException e) {
System.out.println("Browser has been closed. Exiting Program");
shouldExit = true;
} catch (Exception e) {
System.out.println("Browser has been closed. Exiting Program");
shouldExit = true;
}
if (shouldExit) {
this.quitApplication();
}
}
private void quitApplication() {
// attempt to close gracefully
if (driver != null) {
try {
driver.quit();
} catch (Exception e) {
}
}
System.exit(0);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AnotherTest().setVisible(true);
}
});
}
}
Selenium is primarily used for testing automation of web applications. It can directly open browsers and read the html contents in it. See http://www.seleniumhq.org/ for additional information.

Bring a running application to front when other instance is opened

I have made my java application as Single instance application. I have implemented File Lock system for the same.
If the application is already running, I want to show the running application to front. How do I achieve that? How can I acess the running process of that application and show it?
What you are asking for is OS dependent but you can always have your own implementation to do this. You application can listen on a certain port for a bring-to-front command that you can send from the second instance of your application.
void main(String[] args){
if(applicationAlreadyRunning){
// Send bring-to-front message to running instance on a known port
// and exit.
}
}
When a bring-to-front message is received you can do:
public void BringToFrontCommandReceived(){
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myMainFrame.toFront();
myMainFrame.repaint();
}
});
}
JWS not only provides an x-plat SingleInstanceService, but it also (from memory) pops the application toFront() on newActivation(String[]). Of course if it is not automatic, you can call it explicitly.
Here is a demo. of the SIS.

Java JButton and swing problem

I am doing a networking project. I compiled a code under Java Project console app and it works. But when I create a GUI and assign the code to run when a button is pressed, it hangs on clicking the button.
This is the source code:
#Action
public void EstablishConnection() {
serverAddress = jTextFieldServerAddress.getText();
serverPort = Integer.parseInt(jTextFieldPort.getText());
serverUName = jTextFieldUName.getText();
serverUPwd = jTextFieldUPwd.getText();
try {
client = new FTPClient();
client.connect(serverAddress, serverPort);
boolean login = client.login(serverUName, serverUPwd);
if(login) {
System.out.println("Successfully logged in\n");
}
else {
System.out.println("Unable to login\n");
}
}
catch(Exception ex) {
System.out.println("Exception Raised: " + ex);
}
}
The action is called when a button is pressed in the swing app. It is not working for me. But it is working very fast for a console app.
Anytime I see the word "hang" I assume you need to be using a separate Thread to execute the hanging code. See Concurrency in Swing for the solution.
I would suggest that you should run code that depends on external factors, like accessing a remote server etc., that could delay the response, in a thread of it's own.
Display a MessageDialog with an indeterminate progress bar:
connProgressBar.setIndeterminate(true);
You neither know whether your connection will terminate, nor if it will, so add a button that allows the user to kill the connection thread, whenever she feels like it.
Since you are probably connecting to an ftp server in order to upload and download files, after the connection has been established, use a determinate progressbar that shows the download percentage of the file or files progress, that runs in a new thread.

Categories

Resources