How to detect that code is running inside eclipse IDE - java

How to detect that code is running inside eclipse IDE

I am not aware of a generic way to get this kind of information.
One suggestion:
When you start a Java program (or a web server) inside Tomcat, simply add an argument that will indicate that this program is launched by Eclipse.
You can do that by opening the "Open Run Dialog" ("Run" menu), then select your type of application and add in the "Arguments" tab a -DrunInEclipse=true.
In your Java code, you can check the value of the property:
String inEclipseStr = System.getProperty("runInEclipse");
boolean inEclipse = "true".equalsIgnoreCase(inEclipseStr);
This way, if the program is not running inside Eclipse (or unfortunately if you forgot to set the property) the property will be null and then the boolean inEclipse will be equal to false.

Although I agree that having the code detecting a single IDE as the dev env is not an optimal solution, the following code works.
Like others proposed, using a flag at runtime is better.
public static boolean isEclipse() {
boolean isEclipse = System.getProperty("java.class.path").toLowerCase().contains("eclipse");
return isEclipse;
}

1) Create a helper method like:
public boolean isDevelopmentEnvironment() {
boolean isEclipse = true;
if (System.getenv("eclipse42") == null) {
isEclipse = false;
}
return isEclipse;
}
2) Add an environment variable to your launch configuration:
3) Usage example:
if (isDevelopmentEnvironment()) {
// Do bla_yada_bla because the IDE launched this app
}

Actually the code is not being run inside Eclipse, but in a separate Java process started by Eclipse, and there is per default nothing being done by Eclipse to make it any different than any other invocation of your program.
Is the thing you want to know, if your program is being run under a debugger? If so, you cannot say for certain. You CAN, however, inspect the arguments used to invoke your program and see if there is anything in there you do not like.

If your workspace matches some pattern like "/home/user/workspace/Project" you can use the code below:
Boolean desenv = null;
boolean isDevelopment() {
if (desenv != null) return desenv;
try {
desenv = new File(".").getCanonicalPath().contains("workspace");
}
catch (IOException e) {
e.printStackTrace();
}
return desenv;
}

A more generic and precise way, that can be used on any IDE would be loop at:
ManagementFactory.getRuntimeMXBean().getInputArguments()
looking for "-Xdebug" || (starting with) "-agentlib:jdwp=".
I came with this from #saugata comment here.
This is excellent if you want to throw a conditional exception preventing the application from simply exiting. Use a boolean like "ideWait" and add it to Eclipse watch expressions as ideWait=false, so whenever you stop at that throw, and "drop to frame" you can continue debugging happily (I mean it!)

I don't think there is any way to do this. But what I would suggest is just a command line argument such as 'debug'. Then in your main method just do
if (args.length > 0 && args[0].equalsIgnoreCase("debug")) {
// do whatever extra work you require here or set a flag for the rest of the code
}
This way you can also get your extra code to run whenever you want just by specifiying the debug parameter but under normal conditions it will never execute.

This might work if your alternative execution work flow provides a different set of dependencies:
boolean isRunningInEclipe = false;
try {
Workbench.getInstance();
isRunningInEclipe = true;
} catch (NoClassDefFoundError error) {
//not running in Eclipse that would provide the Workbench class
}

You could detect if you're inside a JAR or not, as per Can you tell on runtime if you're running java from within a jar?
Eclipse will run your app from the classes/ dir, whereas most of your end users will be running the app from a JAR.

System.out.println("Is my parent eclipse[.exe]? " +
ProcessHandle.current()
.parent()
.flatMap(parent -> parent.info().command())
.orElse("")
.matches("^.*eclipse(\\.exe)?$"));

You may try something like this:
if (ClassLoader.getSystemResource("org/eclipse/jdt/core/BindingKey.class")!=null){
System.out.println("Running within Eclipse!!!");
} else {
System.out.println("Running outside Eclipse!!!");
}

Related

Java Jinput: rescan / reload controllers

I am using java jinput library to read data from joypad, and I have trouble reloading Controllers, I use this to load them:
public Controller[] findStickControllers() {
ControllerEnvironment ce =
ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
System.out.println(cs.length); //test
ArrayList<Controller> sel = new ArrayList<>();
for (Controller c: cs) {
if(c.getType() == Type.STICK) {
sel.add(c);
}
}
return sel.toArray(new Controller[]{});
}
This works fine, but if I disconnect my controller, calling this will find it again, and vice versa (connecting it after the first check will not find it at all).
I have tried to put sleep before the fist lookup, with these results:
Controllers are acctually scanned when this method is called first time (not at start of the program)
When called again, this always returns same controllers as it returned for the first time.
First call will also write warning bellow
Even when controller is connected (and works), then disconnected (it will still find it though) and reconnected, it will not work
Warning from point 3: (didn't format well in the list)
WARNING: Found unknown Windows version: Windows 8
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
I am using Win 8, and had same problem on Win 7. I had also tried this with mouse, same results.
How can I acctually reload controllers for the 2nd, 3rd, and so on time?
I encountered the same problem. The reason is that the actual hardware scan happens only once for each DefaultControllerEnvironment object. Since the only accessible instantiation is a singleton, it never does another scan.
A simple way to force a hardware scan is to create a new object, but neither the class nor the constructor are public. You can however work around this limitation by calling the constructor via reflection.
Rescan
private static ControllerEnvironment createDefaultEnvironment() throws ReflectiveOperationException {
// Find constructor (class is package private, so we can't access it directly)
Constructor<ControllerEnvironment> constructor = (Constructor<ControllerEnvironment>)
Class.forName("net.java.games.input.DefaultControllerEnvironment").getDeclaredConstructors()[0];
// Constructor is package private, so we have to deactivate access control checks
constructor.setAccessible(true);
// Create object with default constructor
return constructor.newInstance();
}
Usage
// Be aware that creating a new environment is fairly expensive
Controller[] controllers = createDefaultEnvironment().getControllers();
Remove Windows 8 Warnings
/**
* Fix windows 8 warnings by defining a working plugin
*/
static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
String os = System.getProperty("os.name", "").trim();
if (os.startsWith("Windows 8")) { // 8, 8.1 etc.
// disable default plugin lookup
System.setProperty("jinput.useDefaultPlugin", "false");
// set to same as windows 7 (tested for windows 8 and 8.1)
System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin");
}
return null;
}
});
}
If you use the accepted answer, you might want to consider killing the thread that was spawned by the previous environment before setting a new one because it won't be cleaned up otherwise. You can do so by calling something like:
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (final Thread thread : threadSet) {
final String name = thread.getClass().getName();
if (name.equals("net.java.games.input.RawInputEventQueue$QueueThread")) {
thread.interrupt();
try {
thread.join();
} catch (final InterruptedException e) {
thread.interrupt();
}
}
}
The warning is because the last time I updated that code windows 7 wasn't even out IIRC, I'll update it.
The controller reload is a feature that has been requested a number of times, but no-one deems it important enough to spend any time implementing it. If you submit a patch I'll take a look and see about committing it. Until someone finds it important enough to spend the time to write it, it's just a missing feature.
I had the same problem before.
I add the rescanning feature (for Windows back-end only) and post the patch on Java gaming forum but no ones seem interested in to integrate it.
So if you need it, apply my patch from here: http://www.java-gaming.org/topics/rescan-controllers/24782/msg/224604/view.html#msg224604

Program works in Eclipse debugger but not anywhere else...?

The following code segment:
private class ConnectionControl implements Runnable
{
public void run()
{
while( true )
{
if( !cnnct.isInMsgEmpty() )
System.out.println( "Incoming message: " + cnnct.getInMsg().getPayloadString() ) ;
}
}
}
Works when I run it in eclipse debugger and place a breakpoint at the System.out line. However, if I run it normally I don't get the "Incoming message..." output.
Any thoughts on why this would be or how even to debug it???
Ahh figured it out... had a deadlock situation going on where two threads were using the same resource. Thanks for your help guys!
Cheers!
There are multiple ways to invoke Java code, depending on where you need it.
What you have shown is not enough to be self-standing, and should cause an error if you try to invoke it as an applet or a java application (java .... ConnectionControl). It may be that Eclipse can invoke a Runnable - I have not seen it though.
Try
making the class public
add a static main method making it a Java application
put a message in the start of the main method so you can see it is invoked
You're already using System.out.println for your program output. Add some sysouts that output where you are in the code and the status of various variables.
I don't know how this is being called but from the code I see your if condition is always evaluating false.

How do I setup Eclipse to stop on the line an exception occurred?

How can I setup Eclipse to stop at the point an exception occurred.
I have an Eclipse breakpoint setup to break on an exception. In the code example below, the problem I'm having is Eclipse tries to open the Integer source code. Is there any way to just have debugger break at the point shown in my code example? If I move down the stack trace, I will get to this line, it'd be nice if there's a way to do this without the "Source not found" window coming up.
This can be done in Visual Studio, so it's driving me crazy not being able to find a way to do this in Eclipse.
package com.test;
public class QuickTest
{
public static void main(String[] args)
{
try
{
test();
}
catch(NumberFormatException e)
{
System.out.println(e.getMessage());
}
}
private static void test()
{
String str = "notAnumber";
Integer.parseInt(str);//<----I want debugger to stop here
}
}
I'm not sure how else to get there, but I just do:
Window -> Show View -> Breakpoints
And in that tab there is a "J!" that lets you set breakpoints on exceptions.
Preferences -> Java -> Debug -> Step Filtering
Choose packages you want to filter out when debugging (java.*, sun.*, etc)
On debug make sure the little step filtering arrow is selected.
This should do the trick.
Can't you just set a breakpoint on the Integer.parseInt(str) line?
If you point your Eclipse project at using a JDK instead of a JRE it should pick up the source code for all of the platform classes (Integer etc).
The Debug view will show the entire stack of the current execution. You need to select the line you want to see. It will be same as you had a breakpoint there, you can see all the variables etc.

Testing if Quicktime and Java are installed?

In Javascript how can I test if the user has the quicktime plugin and java plugins installed?
For Java, you can use navigator.javaEnabled(). Or you can look here: http://www.pinlady.net/PluginDetect/JavaDetect.htm
For QuickTime, you can do:
var QtPlugin = navigator.plugins["Quicktime"];
if (QtPlugin) {//QuickTime is installed}
See here: http://javascript.internet.com/miscellaneous/check-plugins.html
This of course does not work in IE. The only way to check plugins in IE is using VB script, and it is very strange and messy. You can only test for specific plugin versions, for example, "quicktime" won't cut it. You have to specify the version, which is not published for versions older than 5, and I can't find a reference for version 7
The above examples haven't got the answer to the QuickTime part of your question, so here's what I'm writing right now even though the question has been closed and is a little old.
var p = navigator.plugins;
var qtcheck = 0;
for (i=0;i<p.length;i++) {
if (p[i].name.match(/QuickTime/) != null) {
qtcheck++
}
}
if (qtcheck > 0) { // do nothing, QuickTime is intalled }
else {
videos = document.querySelectorAll('object[type="video/quicktime"]')
// use .getElementById instead if there are multiple videos
// replace them with document.createElement('img')
For a more comprehensive and foolproof method i.e. without worry of a plug-in being renamed for whatever reason, you can check within the array of MimeTypes for type="video/quicktime" which is the ultimate answer of whether the object will be supported (or if you're not using the QT video, whatever else you're using it for instead).
This means creating a loop inside the loop through the plugins instead, but is a more firm verification than just a string match:
function checkQT() {
var p = navigator.plugins;
var QT = false; // assume you don't have it
for (i=0;i<p.length;i++) {
for (j=0;j<p[i].length;j++) {
if (p[i][j].type == "video/quicktime") {
QT = true;
return true;
}
else continue;
return false;
}
}
}
I searched around online and found a bunch of great IE fallback scripts here (not sure if this paste service code is going to persist so I gisted it for posterity), from which I took the QuickTime one:
function IEhasQT() {
if (!window.ActiveXObject) return false;
try { if(new ActiveXObject("QuickTime.QuickTime")) return true; }
catch (e) {}
try { if (new ActiveXObject('QuickTimeCheckObject.QuickTimeCheck')) return true; }
catch (e) {}
return false;
}
I tested some others and they just didn't work - catching the exceptions is important.
If you're doing what I'm doing (QuickTime fallback to a gif animation) you might want to take the attributes of the video to provide to the image (or whatever else you're using). The downside to this is that you have to couple it to an onscroll as well as onload (or use Jquery) as the browser is liable to try and find the element before the DOM has loaded no matter how you try and avoid it.
If anyone else reading this is looking for a similar answer, the code to do so is
function noQTfallback() {
var vid1 = document.getElementById("<insert your object id>");
var vid1gif = document.createElement('img');
vid1gif.setAttribute("src","<insert your URL source>");
vid1gif.setAttribute("style",vid1.getAttribute("style"));
document.getElementById("<...>").replaceChild(vid1gif, vid1);
}
function IEhasQT() {
// as above
}
function checkQT() {
// as above
}
function QTbackup(){
if (!checkQT() && !IEhasQT()) {
noQTfallback();
}
}
window.document.body.onload = QTbackup;
window.onscroll = QTbackup;
Oddly, you can have multiple versions of QuickTime installed, my Chrome browser on Windows has 7 copies... Luckily I have a Chromebook which doesn't have QT plug-in either installed or available, so I'm checking and seeing what works to distinguish it, this is the best I've come up with.
I never understood why testing was so important until looking at everyone's awful code on this online, incredible. I know no one cares about IE but basic things like || instead of && are just bad to leave lying around for other developers to reuse.
I've checked this on Windows, Linux and Android (IE and Chrome). The onscroll gives a bit of a jump but without Jquery or some other framework it's unavoidable I guess (and beats "plug-in not supported" !

What is the best way to detect whether an application is launched by Webstart

As it was made clear in my recent question, Swing applications need to explicitly call System.exit() when they are ran using the Sun Webstart launcher (at least as of Java SE 6).
I want to restrict this hack as much as possible and I am looking for a reliable way to detect whether the application is running under Webstart. Right now I am checking that the value of the system property "webstart.version" is not null, but I couldn't find any guarantees in the documentation that this property should be set by future versions/alternative implementations.
Are there any better ways (preferably ones that do not ceate a dependency on the the webstart API?)
When your code is launched via javaws, javaws.jar is loaded and the JNLP API classes that you don't want to depend on are available. Instead of testing for a system property that is not guaranteed to exist, you could instead see if a JNLP API class exists:
private boolean isRunningJavaWebStart() {
boolean hasJNLP = false;
try {
Class.forName("javax.jnlp.ServiceManager");
hasJNLP = true;
} catch (ClassNotFoundException ex) {
hasJNLP = false;
}
return hasJNLP;
}
This also avoids needing to include javaws.jar on your class path when compiling.
Alternatively you could switch to compiling with javaws.jar and catching NoClassDefFoundError instead:
private boolean isRunningJavaWebStart() {
try {
ServiceManager.getServiceNames();
return ds != null;
} catch (NoClassDefFoundError e) {
return false;
}
}
Using ServiceManager.lookup(String) and UnavailableServiceException is trouble because both are part of the JNLP API. The ServiceManager.getServiceNames() is not documented to throw. We are specifically calling this code to check for a NoClassDefFoundError.
Use the javax.jnlp.ServiceManager to retrieve a webstart service.
If it is availabe, you are running under Webstart.
See http://download.java.net/jdk7/docs/jre/api/javaws/jnlp/index.html
As you mentioned, checking the System property as follows is probably the cleanest way:
private boolean isRunningJavaWebStart() {
return System.getProperty("javawebstart.version", null) != null;
}
In a production system I have used the above technique for years.
You can also try to check to see if there are any properties that start with "jnlpx." but none of those are really "guaranteed" to be there either as far as I know.
An alternative could be to attempt to instantiate the DownloadService us suggested by Tom:
private boolean isRunningJavaWebStart() {
try {
DownloadService ds = (DownloadService) ServiceManager.lookup("javax.jnlp.DownloadService");
return ds != null;
} catch (UnavailableServiceException e) {
return false;
}
}
Of course that does have the downside of coupling your code to that API.
I have no real experience with Java web start other than looking at it a few years back.
How about start your application with a parameter that you define than you set when the app is started via Java web start.
If you want to pass in arguments to your app, you have to add them to the start-up file (aka JNLP descriptor) using or elements.
Then check to see if these properties are set.
Again this is a suggestion I have not coded for JWS and it may not be this easy.
You can check whether the current classloader is an instance of com.sun.jnlp.JNLPClassLoader (Java plugin 1) or sun.plugin2.applet.JNLP2ClassLoader (Java plugin 2). Despite the "applet" package, an applet using JNLP with the Java plugin 2 uses another classloader, sun.plugin2.applet.Applet2ClassLoader. It works with OpenJDK too.

Categories