Eclipse plugin: attach a java process to a code launch - java

So I am doing an eclipse plugin for educational purposes.
My goal now is to have an additional java thread running , when the Run button is hit.
So, alongside with the normally launched programme , I want to have my own plugin code running (which I specified in the plugin).
I thought about trying to create a new java thread , running my code when I execute DebugUITools.launch(config, mode); .
But I am not sure how I would attach the thread to the launched process so that I could stop the thread too...
I also thought about creating java launch configuration for my plugin code, but it's probably impossible because as far as I can see, we need a Project for that.
So, are there any possibilities to programmatically attach new threads to a launched program? Or maybe create a second launch configuration out of plugin code, and launch it?
I hope I was able to explain my struggle to you.

Each Launch runs the code in a completely new JVM. You can't take a thread in the current JVM and move it to a different one.
A second launch configuration in your code would only end up launching yet another JVM which doesn't get you anywhere.
You would have the modify the existing launch configuration to add a jar containing your code and change the program entry point to point to your code so you can start your thread.

Related

Error: Undefined function or variable - java in MATLAB

I would like to run a simple media player made in Java from MATLAB, more precisely this one: https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/mediaplayerjava.htm
This code compiles without any problems and works, both when trying to run it in IntelliJ and when compiling with javac and running the .class file.
It compiles successfully under the same Java version as my MATLAB is using, so I am telling where the java-files are with javaaddpath(pwd). For some reason I get the error "Undefined function or variable 'MediaPlayer' while running the code provided in the link above, doing like this: test = MediaPlayer or test = MediaPlayer(); To be sure that everything is working I tried to compile and then run a simple java Hello World in MATLAB, which was working fine.
What could be the problem? If you have time, please help me out by compiling the code from the link above (2 files, press "Next Page for the second java file) and try to run it in MATLAB. I would be extremely thankful for any help!
Short answer:
The MediaPlayer is defined in package mediaplayer in your Java(FX) code:
package mediaplayer;
Therefore, the correct initialization would be:
test = mediaplayer.MediaPlayer();
Long answer:
From this point this question becomes really JavaFX specific and not about the trivial Matlab - Java interopability.
Problems:
JavaFX is bundled inside Java8 by default, and even Matlab R2016 is shipped with Java7, therefore the JavaFX package (javafx.*) will be not on the classpath of the JVM of Matlab, so you must ensure that JavaFX on the classpath of the JVM.
As soon as you manage to launch the Application (e.g. test = mediaplayer.MediaPlayer(); test.main({''});), it will block the Matlab thread. Even worse, when you close the window, the Application will still not exit and the Matlab thread remains blocked. This can be worked around by calling setImplicitExit(true) in the start method of the Application. This will force the Application to exit when all the Stages are closed, therefore the Matlab thread is not blocked anymore.
At this point the problem is that an Application cannot be started more than once. So if you have exited, you will be never able to start the same Application again.
What you can do to handle the last two points is to implement an "Application starter" in Java that runs on a separated thread and usable to execute JavaFX Applications.

Detect application mode (DEV, TEST, PROD) during build in Play Framework 2.x application

Good day all,
I'd like to be able to detect the mode that a Play application will use during build. Meaning I'd like to execute certain tasks within my Build.scala/build.sbt depending on whether the application is started in DEV or in PROD mode for instance.
The reason I need this is because we (the team) have implemented Grunt.js into the build process by adding it to the playRunHooks. Depending on whether the application is running in DEV mode or not we want to enable/disable some Grunt tasks.
I know I can check the application mode from within the actual application using Play.isDev and the like, is there a similar mechanism available for within the build files?
If not I would really only need to know the command that was issued by the developer (run, start, dist, stage etc.) but I can't seem to find a straight forward way of getting to know this either.
Can anyone point me in the right direction? Thank you in advance!
Any build tasks that are added to playRunHooks are only executed on "play run". If you do "play stage" or "play dist" those tasks are never executed.
The reason I need this is because we (the team) have implemented Grunt.js into the build process by adding it to the playRunHooks. Depending on whether the application is running in DEV mode or not we want to enable/disable some Grunt tasks.
Since you say build process and are looking to hook into the application when it's running in prod mode I think the place you're really looking to hook into is the dist command. In that case you'll want to create some tasks for your build file and get creative with .dependsOn to incorporate them.
SBT has a way of running external processes such that you could define a simple inputKey in your build.sbt file like so:
val doGulpRelease = inputKey[Unit]("Runs gulp --release")
doGulpRelease := {
val s = streams.value
s.log.info("Preparing to run my task")
"gulp --release" ! s.log
s.log.info("Done with my task")
}
Then, to hook into the dist process of play, you can set it to depend on a task created from the above:
dist in Universal <<= (dist in Universal).dependsOn(doGulpRelease.toTask(""))
This will cause your dist command to also run your custom build command, which in this case would do whatever the release task was defined to do.
In the same vein, if you need some build process to run for your tests, use test in Test and dependsOn to run whatever you need to. It seems to me you're asking an XY problem but if is the case that you're not and you really do need to run grunt subprocess's from within your running play app then you'll need to use the Global Object and hook into the onStart/onShutDown hooks and create some type of job runner for yourself. You could start here for some hints on running background tasks in play and besides that google is your friend.
Note: You may need to do some imports at the top of your build.sbt file to use the above code, and it will also depend on your sbt version, but with 0.13.5 I believe it is:
import sbt.complete._
import complete.DefaultParsers._
import com.typesafe.sbt.packager.Keys._

Java Distribution Code vs Development Code

I have an application developed in Java that's almost ready for distribution. However, I have a problem switching from my development env to publishing env, and back to development. For instance, in Eclipse, if I just want to do a test run via the run button, I have to change the code so my JMenuItems show up.
In my development environment I had the following that worked well:
JMenuItem[] appItems = new JMenuItem[2];
appItems[0] = new JMenu("New");
appItems[0].setIcon(new ImageIcon(../POS_System/images/new_icon_sm.png")));
But, as I near deployment, to get this to work in the deployable JAR, I need to alter the code:
JMenuItem[] appItems = new JMenuItem[2];
appItems[0] = new JMenu("New");
appItems[0].setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/new_icon_sm.png")));
This is order to reach into the JAR and get the appropriate image.
I have a lot of these JMenuItems. I'd really like to be able to test the app via the run button in Eclipse, as well as create a JAR without changing the code.
Is there a simple way to do this? I thought the getResource method would still allow me to use the JMenus, JMenuItems etc, but they aren't available when I run the program from Eclipse. It seems silly that I would have to keep switching back and forth.
I appreciate any help here.
If you do not want to move your images into the src/ folder as you have suggested, then in Eclipse, you should update your Eclipse configuration under the Project Prooperties -> Java Build Path and add an additional source folder, this one pointing to where you keep your images. I believe this will fix it.

Is there a way to delete meta-data on Eclipse run configurations?

I may have a corruption problem in Eclipse run configurations. This happened after I dragged (or copy-pasted, I don't remember) a Java class called MyClass from project1 to project2. Then I deleted project1. When I create a new run configuration the name given is MyClass (1). In other words, it thinks there is already a run configuration called MyClass, so the new one will have to have a number appended. (Edit: There is no existing MyClass run configuration so there is no apparent reason for the appended number. In fact, I deleted all of my run configurations.)
How can I easily clean up meta-data and be able to build again with minimal manual effort?
If there is a meta-data deletion recommendation that gets rid of more than just run configurations, that probably would still be a good solution, if it does not create a lot of manual work to get set up to work again.
Edit: The problem might be caused by the fact that there is a launch configuration named MyClass - project1 visible in the export dialogue. project1 no longer exists, but this remnant lives on, tying up the class name MyClass. I am not sure if there is a difference between a run configuration and a launch configuration.
AFAIK launch configurations are stored on:
${WORKSPACE}/.metadata/.plugins/org.eclipse.debug.core/.launches
Take a look to the existent configurations and remove those that are not interesting to you.
And restart Eclipse
Open Eclipse. Follow Run => Run Configurations. You will see options on the left hand side. Under the Java Applications option, you will see the list of runnable classes (the ones have a main method). These class nodes on that list are right clickable. By right clicking on your running configuration, you will see New, Duplicate and Delete options. You can delete your old running configuration via delete option. To create a new running configuration, right click on Java Applications option and click on New and then configure it.
You could try starting eclipse with the -clean command line option.
On windows the easiest way to do that is to copy your shortcut to eclipse and add the option to the arguments list, then start using the new shortcut.

Setting fork and spawn in a maven plugin

We're converting a buildfile from ant to a maven plugin. We're trying to start/stop a database (hsqldb) in a maven plugin.
We succeeded to start the database. But we think that the plugin stops the database when the plugin is executed. The database should keep on running after the execution, but it seems to stop right away.
Our guess is that we should use the 'fork' and 'spawn' attributes (they are also in our build.xml from ant), but we don't have an idea how to implement them in our java class from our DatabaseController (which extends from AbstractMojo).
Any ideas?
We're using hsqldb, thisis the code how we initialize it:
hsqlServer = new Server();
hsqlServer.setLogWriter(null);
hsqlServer.setSilent(true);
hsqlServer.setDatabaseName(0, "database");
hsqlServer.setDatabasePath(0, "file:data/database");
getLog().info("Starting server!");
hsqlServer.start();
When we run the plugin, the database starts, we even managed to create tables and write data to it. Then the plugin stops, and the server stops automatically with it.
If we run another plugin, one to stop the server, we always get a nullPointerException at this line:
hsqlServer.stop();
Kind regards,
Jeroen
One thing you can do is, looking at existing maven plugins that does the forking of new java processes. Maven-surefire-plugin for one, do something similar. Surefire has a configuration (which will be specified in the pom.xml) called forkMode, which controlls the forking.
You may have to go through the source (svn checkout the code) of the plugin to figure it out.
I'm not much familiar with surefire much. But as a start, you may read the following class (#fork( Object testSet, Properties...)!
./maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
Any code executed in maven is forked in another process. I worked with processes in some projects realm, it doesn't have a clear documentation about that.
You could call your code something like that:
Thread.currentThread().setDaemon(true);
hsqlServer = new Server();
hsqlServer.setLogWriter(null);
hsqlServer.setSilent(true);
hsqlServer.setDatabaseName(0, "database");
hsqlServer.setDatabasePath(0, "file:data/database");
getLog().info("Starting server!");
hsqlServer.start();
With an daemon thread, maven could thing witch your code is to be runned in background.
It´s supposition, but you could try it.

Categories