JavaExe and Java application as windows system service interactive to desktop - java

Request:
This is a very common problem faced by Java devs in my locale. I am really stuck for many days on this. Searched and tried a lot, read the docs. read ALL the stackoverflow questions related to JavaExe. Please only reply if you have done similar thing before and have a comprehensive answer. I would be really grateful to the community!
Senario:
I am using JavaExe to run an application as system service in desktop interactive capability.
To be exact I have an application that captures screenshots of desktops. I want it to run (as admin) on any user login so no one can stop it.
I have a myapp.jar, settings.txt and a lib dir.
I have searched alot and found JavaExe works (by watching its examples)
If anyone has a better way. Please state so.
Problem:
According to my research,
you must create a .properties file that has named like the .exe, and write "RunType = 1" in this file.
you define a static method in your main class : serviceInit()
Do I need to place any class or reference/import? How?
Edit:
My code below works as stand alone .jar and in javaExe.exe too.
It now does makes a system service and runs by as SYSTEM user. but It is NOT interactive to desktop. i.e its not showing any GUI.
package temp;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
public class Temp {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
serviceInit();
}
public static boolean serviceInit(){
new Thread(){
public void run(){
Integer i = 0;
while(i < 999999999){
JOptionPane.showMessageDialog(null,i);
i++;
}
}
}.start();
return true;
}
}
And I dont think that bundling the .jar, lib directory and settings.txt into one .exe is possible?

you should have in your case :
public class MyApp_ServiceManagement
{
static boolean isMsgToDisplay = false;
/////////////////////////////
public static boolean serviceInit()
{
(new Thread()
{
public void run()
{
for(int i=0;i < 6;i++)
{
try { sleep(5*1000); }
catch(Exception ex) {}
isMsgToDisplay = true;
}
}
}).start();
return true;
}
/// is Data ready to be send to the UI ?
public static boolean serviceIsDataForUI()
{
return isMsgToDisplay;
}
/// Data to be send to the UI
public static Serializable serviceDataForUI()
{
isMsgToDisplay = false;
return "hello, I am an interactive Service";
}
}
and for the UI part :
public class MyApp_TaskbarManagement
{
/// To show (or not) the icon in tray
public static boolean taskIsShow()
{
return false;
}
/// Receive the message from Service
public static void taskDataFromService(Serializable data)
{
JOptionPane.showMessageDialog(null, data);
}
/// descr of UI
public static String[] taskGetInfo()
{
return new String[]
{
"UI part of Service"
};
}
}

the main() method is never called in service mode (except one particular case), but if you want keep your main() method you must put a call to main() in serviceInit().
Put serviceInit() in your main class or in another class named XXX_ServiceManagement where XXX is the name of your main class.
Then, serviceInit() must return before a 30 seconds delay.
Don't put a infinite loop, ... in it.
Put your code in a thread, and start it from serviceInit() (or main)
That answer to your problem?

Related

Why is my Java static block is not executing? (Extremely simple example. Other answers don't seem to apply.)

I've included my code below. Following some other examples, I even tried to dynamically load the class in order to force it to run the static block, but that doesn't solve my problem. The class is loaded and class.getName() is printed successfully, but still, when it gets to the last line in the main method it throws an error saying the array is null.
All the other answers address things which don't seem to apply here, like how using the "final" keyword can allow the compiler to skip static blocks. Any help is appreciated!
package helper;
public class StaticTest {
public static boolean [] ALL_TRUE;
private static void setArray(){
ALL_TRUE = new boolean[8];
for(int i=0;i<ALL_TRUE.length;i++){
ALL_TRUE[i] = true;
}
}
static {
setArray();
}
public static void main(String [] args){
ClassLoader cLoader = StaticTest.class.getClassLoader();
try{
Class aClass = cLoader.loadClass("helper.StaticTest");
System.out.println("aClass.getName() = " + aClass.getName());
} catch(ClassNotFoundException e){
e.printStackTrace(System.out);
}
System.out.println(StaticTest.ALL_TRUE[0]);
}
}
In case anyone else lands here, the problem was that I had checked the Netbeans option "Compile on Save" (under Build->Compiling). Somehow, compiling files immediately upon saving was preventing the static block from being run.
Again, thanks to everyone who chimed in to verify that the code itself worked as expected.

jnotify - anything else to use instead of Thread.Sleep when file is detected

I am really needing some help on this.
I have adopted the JNOTIFY approach to detecting any new files in a directory. When the file arrives the Listener informs that a new file is in the location.
#BeforeTest(alwaysRun=true)
public void Polling() throws Exception {
ListenToNotifications.checkFolderPickup();
}
I have attempted this where I addded a call to my Setup function in order to call my setup function after the file is detected.
//snippet from Listener Class from checkFolderPickup();
public void fileCreated(int wd, String rootPath, String name) {
print("New File just created " + rootPath + " : " + name);
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
try {
BaseTest.setup();
} catch (Exception e) {
e.printStackTrace();
}
}
My question is //Thread.sleep(1000000) i feel this is not a safe approach and I wanted to know if there is any other approach that I could possibly use instead of a Thread.Sleep, because this function will have to be executed once each time a new file is available and the old file will be deleted eventually and so on, I cannot make the Sleep to short , it will just ignore and continue with Base.Setup()
public static void checkFolderPickup() throws Exception {
...removed other code
boolean watchSubtree = true;
int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());
//Thread.sleep(1000000);
Thread.sleep(20000);
boolean res = JNotify.removeWatch(watchID);
if (!res) {
// invalid watch ID specified.
}
}
I basically need my framework to keep polling that directory and each time it will execute the base setup process and follow a workflow, delete the file then poll again and so on.
Can anyone please advise?
You don't need any other modules , you can use custom expected condition:##
using:
import java.io.File;
define the method inside any pageobject class:
private ExpectedCondition<Boolean> newfilepresent() {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
File f = new File("D:\\workplace");
return f.listFiles().length>1;
}
#Override
public String toString() {
return String.format("wait for new file to be present within the time specified");
}
};
}
we created a custom expected condition method now use it as:
and in code wait like:
wait.until(pageobject.filepresent());
Output:
Failed:
Passed
Once you register a watch on a directory with JNotify, it will continue to deliver events for files in that directory. You should not remove the watch if you wish to continue to receive events for that directory.

Concept to create thread wide/class wide object

I'm searching for a concept to forward an object to subobjects.
Example:
I would like to create log files for several main Objects, that include sub objects (imagine a REST server that would log every single connection by ID).
Creating one big log file is simple ( redirect System.out.println, I already encapsulated that)
Example code:
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Application.java
package com.dev4ag;
class Application{
private ElementA elA;
private String prefix;
public Application(String name){
this.elA = new ElementA();
this.prefix = name;
}
public void countUp(){
Debugger.debug(this.prefix+": I will now count up");
this.elA.doSomeStuff();
}
}
ElementA.java
package com.dev4ag;
class ElementA{
private int counter;
private SubElementA subElementA;
public void doSomeStuff(){
counter++;
Debugger.debug("Counter is: "+counter);
}
//Constructor
public ElementA(){
subElementA = new SubElementA();
this.counter = 0;
};
}
SubElementA.java
package com.dev4ag;
class SubElementA{
public SubElementA(){
Debugger.debug("I am called, too");
}
}
Debugger.java
package com.dev4ag;
public class Debugger {
public static void debug(String output){
//Just imagine we would write to a file here ;)
System.out.println(output);
}
}
(it was more easy to write system.out.println than to create a file, just imagine, Debugger.debug would write to a file).
Now I am thinking about a solution to create one Debug output target for each App. I could definitely change debug to not being static and create a debug object within Application.
But is there any way to use this object in the sub classes without forwarding the debug object either through Constructor or setter function, which would mean to have to add an object for the debugger to each class?
What would be the most beautiful solution for that?
Note that this solution might decrease performance a lot and it is pretty dirty way, but some loggers include such data.
But you can use Thread.currentThread().getStackTrace() to get stacktrace like in error and get class and method from where your method was called.
If you are using java9+ then you should probably use StackWalker API instead, especially that it have nice filters and other useful features.
So then you could guess app by class/method names on the stack.

How to use methods from two classes in eachother in Java?

I've been looking around and I only found one answer which wasn't clear enough, to me at least.
I am building a very basic chat application with a GUI and I have separated the GUI from the connection stuff. Now I need to call one method from GUI in server class and vice versa. But I don't quite understand how to do it (even with "this"). Here's what a part of code looks like (this is a class named server_frame):
textField.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
srv.sendData(arg0.getActionCommand());
} catch (Exception e) {
e.printStackTrace();
}
textField.setText("");
}
}
);
This is a code from server_frame, srv is an object from the other class (server) which contains sendData method, and I probably didn't define it correctly so hopefully someone could make a definition of it.
On the other side class server from which object srv was made contains method using JTextArea displayArea from server_frame in this code:
private void displayMessage(final String message){
sf = new server_frame();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
sf.displayArea.append(message);
}
}
);
}
Yet again sf is an object made of server_frame and yet again probably missdefined :)
Hopefully that was clear enough, sadly I tried the searching but it just didn't give me the results I was looking for, if you need any more info I will gladly add it!
Thanks for reading,
Mr.P.
P.S. Please don't mind if I made terminology mishaps, I am still quite new to java and open to any corrections!
Some class must be building both of these objects--the GUI and the server--and it should make each aware of the other. For example, say the main class is ServerApplication. I'll use standard Java convention of starting class names with an uppercase letter for clarity.
class ServerApplication {
Server server;
ServerFrame gui;
public static void main(String []) {
server = new Server(...);
gui = new ServerFrame(server);
server.setGui(gui);
}
}
Each class should store the reference to the other as well.
class Server {
ServerFrame gui;
public void setGui(ServerFrame gui) {
this.gui = gui;
}
...
}
class ServerFrame extends JFrame {
Server server;
public ServerFrame(Server server) {
this.server = server;
}
...
}
I think you may be looking for the ClassName.this.methodName syntax. this in those actionlisteners refer to the anonymous class you created. If you used the above syntax you would be referencing the class that contains the anonymous class.
Or if you are looking for a private field in the class, you would do ClassName.this.privateField

Java Swing - How to double click a project file on Mac to open my application and load the file?

I have created a Mac Java Swing application, and i have set a file extension(*.pkkt) for it in the "Info.plist" file, so when double clicking that file it opens my application.
When i do that the program runs fine. Now i need to load the (*.pkkt) project in the program, but the file path is not passed as an argument to the main(...) method in Mac as happens in Windows Operating System.
After some search i found an Apple handling jar "MRJToolkitStubs" that has the MRJOpenDocumentHandler interface to handle such clicked files. I have tried using it to load that file by implementing that Interface in the main program class, but it is not working. The implemented method is never called at the program start-up.
How does this Interface run ?
------------------------------------------------- Edit: Add a Code Sample
Here is the code i am using :
public static void main( final String[] args ) {
.
.
.
MacOpenHandler macOpenHandler = new MacOpenHandler();
String projectFilePath = macOpenHandler.getProjectFilePath(); // Always Empty !!
}
class MacOpenHandler implements MRJOpenDocumentHandler {
private String projectFilePath = "";
public MacOpenHandler () {
com.apple.mrj.MRJApplicationUtils.registerOpenDocumentHandler(this) ;
}
#Override
public void handleOpenFile( File projectFile ) {
try {
if( projectFile != null ) {
projectFilePath = projectFile.getCanonicalPath();
System.out.println( projectFilePath ); // Prints the path fine.
}
} catch (IOException e) {}
}
public String getProjectFilePath() {
return projectFilePath;
}
}
As mentioned in the comment above "getProjectFilePath()" is always Empty !
On Java 9, use Desktop.setOpenFileHandler()
The proprietary com.apple.eawt packages have been removed from recent versions of Java and has been incorporated into various methods in the Desktop class. For your specific example:
import java.awt.desktop.OpenFilesHandler;
import java.awt.desktop.OpenFilesEvent;
import java.io.File;
import java.util.List;
public class MyOpenFileHandler implements OpenFilesHandler {
#Override
public void openFiles​(OpenFilesEvent e) {
for (File file: e.getFiles​()) {
// Do whatever
}
}
}
Then elsewhere, add this:
Desktop.getDesktop().setOpenFileHandler(new MyOpenFileHandler());
The OpenFilesEvent class also has a getSearchTerm() method. Say that a person used Spotlight on macOS to search for the word "StackOverflow", then decided to open up a document. With this method, can you determine that "StackOverflow" was the word they searched for, and choose to do something with that (perhaps highlight the first occurrence of the word).
You're going to want to use the Apple Java Extensions.
They should be included in any JDK that runs on Mac OS X, but the documentation is kind of hard to get. See this answer for more details.
Specifically, you'll want to make an OpenFilesHandeler.
This code snippet should work:
import com.apple.eawt.event.OpenFilesHandeler;
import com.apple.eawt.event.AppEvent;
import java.io.File;
import java.util.List;
class MacOpenHandler implements OpenFilesHandeler {
#Override
public void openFiles(AppEvent.OpenFilesEvent e) {
List<File> files = e.getFiles();
// do something
}
}
And somewhere:
import com.apple.eawt.Application;
...
MacOpenHandeler myOpenHandeler = new MacOpenHandeler();
Application.getApplication().setOpenFileHandler(myOpenHandeler);

Categories