I've found a very strange behavior while debugging an Android application at the following code:
private String process(byte[] item) {
if(item == null) {
item = new byte[0];
}
//byte val = item[0];
//String str = "Val = " + Integer.toString(val);
//Log.e(TAG, str);
[...]
return rez;
}
Sometimes, while debugging, the execution steps inside the 'IF' block when 'ITEM' is a non-null variable. What's worse is that Eclipse's Expressions view actually lists 'ITEM' as non-null, allocated variable, and 'item == null' as false. This seems to happen as long as the commented lines stay commented, and it happens both on the sim and the device.
Any ideas what is going on ?
I am using Eclipse 3.7.1, latest Android SDK, and various 1.6+ sims and 2.1+ devices.
try
if(item==null)
(without the spaces).
It worked for me.
edit the error has come back after another change in the lay-out of the program (i.e. by removing a comment)
Related
I have only ever seen something like this once before when I accidentally tried to debug in release mode, but that isn't the case here. To my question. I have this block of code in an android app:
if (leftRight[0] != null && leftRight[1] != null) {
Log.d("", "test");
return leftRight;
} else {
Log.e("", "test134");
return null;
}
When debugging, the if statement is true and it executes the first Log.d(). However, when stepping to the next line it jumps straight to the return null which I don't understand how that is possible since it is in the else rather than the if. The second Log.d() is skipped over also.
Hopefully I am just missing some small thing, but I am completely baffled as to what is going on. Anything to point me in the right direction is appreciated.
EDIT
If it matters, leftRight is a Point[] containing two Points.
Basically, you are right, it should not happen. However, consider this code:
Log.d("", "test");
if (leftRight[0] != null && leftRight[1] != null) {
return leftRight;
} else {
return null;
}
It has the same effect. Maybe your compiler restructures the code in this way and the debugger is just reflecting this as best as he can ...
EDIT: you can find out whether this is the case using "javap"
EDIT2: you may also try out whether the behavior changes if you change the log messages to do something different ...
If your function returns correct value, there is big chance there are some issues with debugger. Mismatch between lines might happened in example when your code was modified after you build it. I suggest you to clean your workspace, rebuild it and try again.
Whenever I start my app I have the following code:
C.userPreferences = getSharedPreferences("default",0);
C.userPreferencesEditor = C.userPreferences.edit();
C.something = C.userPreferences.getStringSet(C.SOMETHING, null);
C.something = C.something == null ? new HashSet<String>() : C.something;
for(String str : C.something){
Log.d("debugging C.something",str);
}
And this correctly logs "one","two" from the string set.
Afterwards I have the following function:
C.something.add("name");
C.userPreferencesEditor.putStringSet(C.SOMETHING, C.something);
C.userPreferencesEditor.apply(); //or with .commit();
And debugging shows "one","two" and "name".
When I restart the app and debug for the first time I only obtain "one" and "two".
Any idea on why this happens? tyvm
This says
Objects that are returned from the various get methods must be treated as immutable by the application.
More specifically:
Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.
Can you try copying the HashSet you retrieved, adding a new entry to the copy, and saving it in preferences?
BTW - I'd be really curious to know why this is the way it is - not very intuitive...
Whenever I try to close a file in drjava after making some edits and not saving, the program, as expected, gives the dialog box:
"[Filename] has been modified. Would you like to save it?"
In many cases, I'll decide at this point to cancel the closing and make some more edits, then save the file manually.
Unfortunately, hitting "Cancel" has the same effect as hitting "No": the window closes without saving, and I lose my work.
Is this the intended behavior of drjava? Or is there some option to select / some code I can use to fix the problem? Although as long as I remember the behavior it's manageable, it's still pretty inconvenient.
It's open source, so we can take a look at the implementation. Here's the code that opens the dialog (some code omitted) from the newest branch:
private boolean _fileSaveHelper(OpenDefinitionsDocument doc, int paneOption) {
...
int rc = JOptionPane.showConfirmDialog(MainFrame.this, text, "Save " + fname + "?", paneOption);
switch (rc) {
case JOptionPane.YES_OPTION:
boolean saved = false;
if (notFound) saved = _saveAs();
else saved = _save();
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return saved;
case JOptionPane.NO_OPTION:
if (doc != lastActive) {
_model.setActiveDocument(lastActive); // breaks when "if" clause omitted
}
return true;
case JOptionPane.CLOSED_OPTION:
case JOptionPane.CANCEL_OPTION:
return false;
default: // never executed
throw new RuntimeException("Invalid option: " + rc);
}
}
There are separate cases for "no" and "cancel", so it looks like they do try to handle it properly. Thus it's probably a bug. The method is referenced by this method
public boolean quitFile(OpenDefinitionsDocument doc) {
return _fileSaveHelper(doc, JOptionPane.YES_NO_CANCEL_OPTION);
}
which is referenced somewhere outside MainFrame.java. I am not inclined to look into it as I don't even have a Java IDE installed. If you wish, you can fork the project and use an IDE like Eclipse to quickly find the references to the method. Speaking of which, I'd suggest just using Eclipse as I remember Dr. Java offering little in the way of basic features such as code completion and formatting.
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!!!");
}
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" !