Java Static Analysis And Custom Bug Detectors
An anonymous reader writes "Java static analysis and custom bug detectors can be a very cost-effective way to improve software quality. By creating a detector for a known bug pattern, we can search for that bug pattern not only in the current code base for a specific project, but in any project, current or future. This article looks at how static analysis tools can change the way you manage software quality."
We develop Java-based vertical products and we have found PMD and JLINT when integrated with an appropriate development process, can be highly effective in preventing serious bugs. That said, both PMD and JLINT incorporates "religious" issues, and it is important to determine what the religious issues are and steer clear of them lest the good rules get lost among the non-essential (from project perspective) rules.
http://buddytrace.com/
As the lead guy on a "competing" static analysis framework - PMD - I can say that FindBugs is definitely a great piece of work. It catches all sorts of complicated problems with concurrency, does forwards/backwards data flow analysis, etc, etc. It's pretty sweet. Dr Pugh, who runs the project at the University of Maryland, did a JavaPosse interview that's some more good info on the project and where it's going.
Of course, if you really want to do source code analysis (vs bytecode analysis, which is what FindBugs does), then go for PMD, and [plug] get the book! [/plug]
The Army reading list
"By creating a detector for a known bug pattern, we can search for that bug pattern not only in the current code base for a specific project, but in any project, current or future."
Does it require a 1.21 gigawatt lightning bolt to power the future search feature?
The point is not to use another piece of software/language to solve bugs. In the industry, you're not always given the choice and, yet even worst, people who make decisive choices are not always knowledgeable to make proper decisions (hello, managers!). We get to deal with the choosen tools and that's it.
Your alternatives are probablement better in respect of quality due to their formalism but you'd have to convince your manager or boss to sign up with these solutions. Might be easier to stick with Java and use a Java bugs finder tools.
You should run whatever LINT-like tools you can find. Developers should agree as a group on what warnings are spurrious and what warnings are legitimate, and adjust any lint policy configurations to suit.
You can also find far more than simple bugs, but you can decide on best practices and consistency standards which should be adhered also. These can vary in importance, but it really helps for a clean and searchable codebase. For a trivial example, if coding in C, decide as a group whether to use *p = '\0' or *p = 0 when writing into a char string. For a more involved example, regularly scan the codebase for regular expressions like (>)\s*(8|16|24) to find possible Intel/PPC endian issues lurking where you don't expect it.
The adage goes, if you find you're doing something more than once, see if you can automate it, so you can pay more attention to the things which can't be automated. This goes for coding and debugging too.
[
You do realize that for the most part Java has static typing? (For example compare its types to those in Lisp, Lua, ect)
Philosophy.
Java is a strong typed language, which just mean that if you got a reference to a class A, then you know that the object is of the type A, or of a class that extend A. (And similary for the buildin types)
But that is far from enough to be bug free. Just a simple example (Yes, a bit silly, but it shows the problem)
public static int myFunction(int[] myArray,int index) {
return myArray[0]+myArray[index];
}
Now the question? Is this function buggy? I would say no, because it does exactly what the documentation say it does, and it does handle all cases where the function is called with correct input.
So if this function was part of a bigger program, would that program have a bug in calling this funciton. That is: Does there exists input, that will cause this function, to be called with a index=myArray.length.
And to answer that question automatic is someware between very very diffucult, and imposible. (But for most* programs answering that question is posibly)
*I will argue that for at least 99.999% of all correct programs that are written to solve a pratical problem, making a static analysis that prove they are correct are in fact posible.
Not having used any static analysis tools, but having worked on several java projects, I question how useful these tools are. In my experience, most bugs that could be detected by static analysis are usually caught relatively quickly anyway. The trickiest (and potentially most damaging) ones are usually non-general enough to slip past a general-purpose tool. Am I mistaken?
I made a mistake, I meant to say statically typed, that's why I was talking about casting. Casting allows dynamic typing and this is what I believe is one of the major contributors to the non-business bugs in code in case of Java.
You can't handle the truth.
...is Sun's Jackpot, headed up by Tom Ball. What's neat about Jackpot is that it does problem fixing, too, using a domain specific language. From the interview:
::
$object.show() => $object.setVisible(true)
$object instanceof java.awt.Component;
Feeding that DSL snippet to Jackpot will transform all Component.show() calls to Component.setVisible(true). Very, very cool stuff. Of course, you don't always want to make the transformation, but in the cases where you do, Jackpot looks like a great solution.
The Army reading list
OCaml and Haskell you say? Excellent. I was looking around for a magical silver bullet the other day, and these look like just the ticket!
there is no need to sign your posts. this isn't usenet. your username is right there above your post. stop it.
I think findbugs does this. I've started using it and it found lots of bugs in my code. As a result I have learned a few things about java, just by using it and fixing my bugs.
Only 'flamers' flame!
Does slashdot hate my posts?
Well, java only allow casts that can be legal, and it return null if the cast fails. So if you have public class A { }
public class B { }
public void f(B myB) { A myA=(B)myB; }
This will not compile at all, because there is no way to cast a B to an A.
If you have
public class Base { }
public class Derived extends Base { }
public void g(Base myBase) { Derived myDerived=(Derived)myBase; }
The function g is ok, and if myBase is infact an instance of Derived, then all is ok. If it is NOT an instance of Derived, then myDerived vil be null, and any code that use myDerived will cast null pointer exception. You can't cheat the java type system.
This is unlike c++, which will accept any cast you ask it to do.
... until Sun relases a new JRE and all your old aplications do not work at all anymore when users install the new JRE. Unmaintained applications die altogether or require constantly uninstalling and installing various JREs to run them as well as new ones. That's the biggest bug of all in Java and makes any bug tracking useless, and programming in Java pointless.
C/C++ applications tend to work for decades and can be written to be far more reliably cross-platform.
Odd. I have found exactly the opposite. Java is very well know for the excellence of its backward compatibility, and to say 'all your old applications don't work anymore' is just plain false. Java would not have had the huge success it has had if this were not the case, so your statement is plainly wrong.
On the other hand, C/C++ version bugs are well known and well documented - just think of the issues involved with gcc versions and linux kernel compilations. I have a very simple C++ app that compiled and ran fine on one version of gcc, but broke on another.
If you simply exchange C/C++ for Java, and vice versa, throughout your post, it then makes sense.
By a strange coincidence, that's also the only reason people make assertions like this.
there is no need to sign your posts. this isn't usenet. your username is right there above your post. stop it.
One Java desktop app which I use all the time is Azureus. You might argue that Azureus (a bittorrent client) isn't "serious," but it is pretty cool.
"Why would God give us a waist if we wasn't supposed to rest our pants on it?" - Rev. Roy McDaniels
Why not do a little research? Go to any of your favorite job sites e.g. Monster, Jobserve etc and search on some lannguage keywords, perhaps C C++ C# Java. You will usually find that there are more posts that include the word java than any other. Maybe someone somewhere is using it.
One would think that out of all people, IBM staff would be familiar with the ATM or the Halting Problem.
Just use a language that isn't Turing complete, and therefore can be guaranteed to terminate. http://www.e-pig.org/.
Why not fork?
Can't help myself to be obnoxious: although this is alleviated a bit with Java 1.5 (Java C# edition), Java has traditionally be statically typed when it isn't necessary (MyObject object = new MyObject(); int x = 4; .... Really, a proper compiler (like Ocaml's) can infer such types!) and runtime-typed when it would actually be useful (MyObject object = (MyObject) array.get(index); /* Sure hope that guy from the cubicle over there actually put a MyObject in there, let's check his code... */). That and no way for a proper library to use any form of overloading (the BigDecimal.add() fiasco), plus the tendency to write everything as a member where a function would actually do nicely (BigDecimal.add() again!) makes Java indeed a fairly loosely typed and inflexible tool. Ah well, also Cobol gave job security.
The type system of Haskell doesn't let you prove anything radically more interesting than that of Java or C++ to be honest. Also Haskell mixes up a bunch of other random ideas with that type system so you have to take the bad from the good - eg lazyness and the unusual syntax.
You can't cheat the java type system.
.NET had a triffle of potential (being a rewrite of Java), except that it's got Big [Corporate] Brother to keep it from reaching it's full potential.
You're kidding right.
Bar b = new Bar();
Foo f = (Foo)(Object)b;
Works just fine for me... Until you get the ClassCast Runtime Exception.
Now you might call this a contrived example.. Except that it's not.
How many thousands of function calls take Serializable or worse "Object" as a parameter? Virtually every IPC related activity does at some point. That includes all of j2ee, which are considered "enterprise" level coding frameworks.
Generics was a step in the right direction with compile-time enforcement of "many" of these opaque "Object" APIs.. But It definitely didn't penetrate some of the more important areas; just collections (which was at least the most [mis]used form of generalized types).
But Generics doesn't have any means of enforcement.
Collection myFoos = new ArrayList();
Collection myUnsafeFoos = myFoos;
Bar bar;
myUnsafeFoos.add(bar);
Foo foo = myFoos.iterate().next();
will throw a ClassCast Runtime Exception.
Now it's semi-trivial to write collections to enforce type-safety (just like synchornization).. But this is as effective as cooperative multi-tasking was in the 90's at reducing bugs.
Java has a lot of historical baggage that keeps it from being a refined and bug-resistant language.. And the proliferation of XML-configured reflective programming is really getting out of hand. That being said, I am not aware of any other development platform that is as versatile.
-Michael
until Sun relases a new JRE and all your old aplications do not work at all anymore when users install the new JRE.
That hasn't been a problem so far as even Java 1.1 applications will still work just fine today in Java 1.5.
That is because unlike other languages, Java has taken a lot of care to keep things working through revisions. Libraries going into disuse are deprecated, not removed - so you have a long time while a library or method call still exists before going away.
Even the design of Java's Generics system was made so that older code would be able to work in harmony with it.
When you're thinking of language revisions breaking code, you must thinking of C#... it's easy to get confused since it's a direct clone of Java.
C/C++ applications tend to work for decades and can be written to be far more reliably cross-platform.
They tend to work for decades because they are still running on the same 386 box they were originally installed on (a testament to Linux). Now if you are trying to move that complex C/C++ app to a more recent platform, like say Fedora 5 - all the sudden you glib isn't quite what the program was expecting.
C/C++ is great for cross platform compatibility along with performance, but you should not pretend that it doesn't take work to maintain and keep things in sync with librarires and system calls.
"There is more worth loving than we have strength to love." - Brian Jay Stanley
Sorry, HTML and less thans... :)
Collection<Foo> myFoos = new ArrayList<Foo>();
Collection myUnsafeFoos = myFoos;
Bar bar;
myUnsafeFoos.add(bar);
Foo foo = myFoos.iterate().next();
-Michael
In any case, C++ has all but abandoned the C-style form of casting, which forms the syntactical basis for Java's casting mechansims: currently C++ sports dynamic_cast (Java-style cast with dynamic type check, returns 0 if the cast fails), static_cast (does not do type checking, but still does a basic compile time check like java. It is present if there's no way that the cast can fail; at least if the programmer thinks that is the case), and reinterpret_cast (interprets bit_patterns as anything you want, the most liberal form of casting).
As usual in C++, you don't pay for what you don't use, if you don't need a runtime type-check, the language doesn't insist you should use one.
Well, java only allow casts that can be legal, and it return null if the cast fails.
Oh, really? After working with Java for the past 8 years, I sort of noticed that you can do this:
WhateverObject1 whateverObject1=new WhateverObject1();
WhateverObject2 whateverObject2=new WhateverObject2();
List list = new ArrayList();
list.add(whateverObject1);
list.add(whateverObject2);
SomeObject someObj = (SomeObject)list.get(0);
Now tell me again what will Java compiler do in this case if SomeObject is not the same as WhateverObject1?
You can't handle the truth.
Two points:
Technically, "intractable" doesn't mean "mathematically impossible," but "too big to manage," so the solution you propose would fall under the "intractable" category.
Also, while you're probably already aware of this, the standard limitations apply to your solution: no external input can be available, and no race conditions can exist in the program.
You want the truthiness? You can't handle the truthiness!
First, I don't see the relevance, so I suspect you don't understand the halting problem[*]. You've probably heard it phrased as in the Wikipedia article: "a general algorithm to solve the Halting problem for all possible program-input pairs cannot exist. We say that the halting problem is undecidable over Turing machines." You've probably heard arguments reducing other problems to the Halting problem and concluded that automated reasoning about programs is impossible.
By some word juggling and de Morgan's laws, Wikipedia's statement is equivalent to "there exist program-input pairs for which the halting problem cannot be solved with a general algorithm." I'd say those should be quite rare if you're doing "reasonable" things.
The common examples of undecidable programs involve "finding counterexamples to famous conjectures in number theory". I'm guessing your programs don't do that. There generally should be straightforward indicators of your programs' progress - input file pointers, size of internal data structures, iterators. If IBM Research put all their effort into the Halting problem and their program still couldn't tell if your program terminates, it might be because your program is screwed up. Thus, "our program can't tell if your program halts for all input" probably means "rethink your algorithm", just as "your program does not halt for input X" does. The same goes for other properties which can be reduced to the halting problem.
It'd still be a hard thing to do, though. I think most existing checker tools examine only a function at once, and I'm not aware of any attempts to do anything so sophisticated even at that level.
Simple but common, which make them great bugs for static analysis. But if you want fancier examples, look at these bugs the Stanford Checker (now Coverity) found in the Linux kernel.
Java is a strongly-typed language. If you cast something incorrectly, you get a ClassCastException. The runtime knows the type of every object. You may have meant "totally statically-typed language". In any case, the answer's still no - the System.gc() example that you found too simple is an obvious counterexample.
They're another way to find bugs, and the bugs they find are not a subset of those found by unit tests. There are a lot of classes of bugs that can't be found easily with unit tests (race conditions!). There are a lot of environments in which it is difficult to write unit tests (embedded code, kernel code, GUI code). And fundamentally unit tests require you to come up with the input that breaks it. If there's a case you never considered at all, they just won't have the same value as a second pair of eyes on your algorithm, which these static analysis tools effectively are.
Does this sort of reasoning sound familiar?
The halting problem is only intractible in the case of INFINITE memory. - factually wrong.
... ...
for(;;) {
if (something is true) {
break;
}
}
No infinite memory, just uncertain state of 'something'.
Also, Java being strongly typed means little in terms of bug preventions. - I actually meant strong AND static typing. Static typing would prevent most non-business bugs. It would prevent serialization, reflection, inheritance and collection element casting errors. That is a lot of types of errors.
You can't handle the truth.
First, I don't see the relevance, so I suspect you don't understand the halting problem[*]. - because YOU don't see the relevance doesn't mean I don't understand something.
Judging by that first statement uou missed most of my point. My point is that there is no real advantage building extra tools to search for simple errors, while still not being able to combat real problems, like infinite loops, incorrect conditions, class cast exception, null pointer exception. ATM has relevance to all of the above-mentioned bug types, so there.
You've probably heard it phrased as in the Wikipedia article: - way to infer. I have probably studied the ATM and Halting problem at Stephen Cook's class (you may want to look him up, he was my UofT prof.)
You've probably heard arguments reducing other problems to the Halting problem and concluded that automated reasoning about programs is impossible. - I already answered tha in the first paragraph in this comment.
Simple but common, which make them great bugs for static analysis. But if you want fancier examples, look at these bugs the Stanford Checker (now Coverity) found in the Linux kernel. - my argument is that these specific types of bugs are due to the language defficiencies. Were Java using strong static typing, these 'bug detectors' would have been included in the compiler.
Java is a strongly-typed language. If you cast something incorrectly, you get a ClassCastException. The runtime knows the type of every object. You may have meant "totally statically-typed language". In any case, the answer's still no - the System.gc() example that you found too simple is an obvious counterexample. - yes, cowboy, you are right. You might have read the rest of the thread to notice that I fixed my wording.
Race conditions can just as well detected with unit-tests. Sure, people don't always write unit tests and when they write them, they don't always write them well or complete them. But this problem has to do with the development practice and no bug detector will find all problems, most of the problems will still have to be debuged and once you debug them, you add another unit test or a suite of unit tests.
Hey, I didn't say these bug detector tools were completely useless, but I would rather see people write good unit tests and think through their code than rely on bug detectors.
After all, if detecting race conditions and deadlocks was a trivial matter, it would have been done in the compiler.
You can't handle the truth.
If this bug detection is as good as they say, it should be part of the compiler. If it is not good enough to be part of the compiler, I wouldn't bother with it.
You can't handle the truth.
It will give you a ClassCastException.
Now it depend on what the definition of cheating is. But going back to my original text which say
which just mean that if you got a reference to a class A, then you know that the object is of the type A, or of a class that extend A. (And similary for the buildin types)
So one could say, that you can try to cheat on the compiler, but It don't care becasue it knows the jvm will stop the actuelly type convension at runtime if it is wrong.
The compiler will give me a ClassCastException? :)))))))))) THE COMPILER? :))))))))))))))))))))
Ok, over and out.
You can't handle the truth.
GCC did not even come close to implementing the C++ standard until 3.2 - Your program was not C++, it was implemented in the C++-like dialect that earlier versions of g++ implemented.
This is often the case for pre-standard C++ programs.
(1) It was indeed C++.
(2) This has been an issue with C/C++ - compilers that are allowed to label themselves as C/C++ that aren't compatible. This is not the case with Java.
I've used lint4j, pmd, checstyle and indeed findbugs. These tools are very useful. The biggest problem is finding the time to fix the issues. It's tempting to skip the minor issues but then this is where you need to be strong.
I'd recommend that serious java developers integrate the above mentioned tools into their nightly builds and treat the identified issues as real bugs.
Jilles
Could you expand upon what you mean? I'm not sure I understand you. What is ATM? I haven't heard of it before. - Accelerating (universal) Turing Machine, ATM is a class of TM that is capable of solving complex problems, more precisely ATM = {| M is a TM and M accepts w} This means that this machine will test input w on ALL possible Turing Machine configurations M with the assumption of finding a Halt (accept/reject state.) ATM is undecidable and I am not going into Oracle TM, which could supposedely decide ATM. ATM cannot decide HALT, that's the main point.
proving termination of reasonably coded functions is quite practical for everyday programs you write - agreed, that is what complexity and descrete math is all about. But automatic induction will take the same amount of time to run as the actual code that is being tested, which means that for all inputs, there is no polynomial solution. Besides, real-life code may depend on states of other external components, such as user input/databases/network input/interrupts etc., which just multiply the number of total possible inputs.
If it's hard to prove (or impossible) to prove that a function terminates, how can you yourself as a programmer be sure it terminates (you must have some idea why it does if you wrote it)? For this reason, it really isn't that important that the halting problem is undecidable. - I, as a programmer have an understanding of the base case and of the induction, but in reality there can always be an input to the function that will go out of the boundaries of the function. You believe that such input is possible to find with an automated induction machine, I know it is possible to find, but I know that there is no feasible solution for all inputs. Basically your inference engine will have to use heuristics to rule out less likely input subtrees, but this means that there is no guarantee that the engine has covered every single possibility.
I understand that we can write code to detect some deadlocks and some infinite loops in compile-time. I also understand that the code that detects dead-locks and infinite loops in runtime always works better, because it can catch conditions, for which the input could not be tested by a compiler.
--
Again practically speaking I would rather see people write good unit-tests, and this will catch much more problems than these bug-detectors.
If these bug-detectors actually become good enough to be incorporated into compilers, then go nuts, use the compiler directive to try and find these bugs. But again, on my projects I wouldn't recommend going with bug-detectors over unit-tests and given the simple fact that projects have limited resources (limited time, money and people) there is always a compromise that needs to be made.
You can't handle the truth.
Sorry it should have been
{ <M,w> | M is a Turing Machine and M accepts w }
the angle brackets are a bitch to type in HTML.
You can't handle the truth.
Not really true. C++ suppports three types of casts and one obsolete form that combines those three in some form I never can remember:
The () is really poor syntax and the usage is discouraged. (and shame on Java for adopting that syntax).
Of these, Java support dynamic_cast, expanded a bit to support primitive types. (which should never have been added, imho.)
Yes, C++ will accept nearly any cast, provided you ask it to :) So you can get unchecked casts (static_cast) platform_dependent casts (reinterpret_casts) and the Java style cast that fail graciously. The idiom is even somewhat nicer in C++.
Religion is regarded by the common people as true, by the wise as false, and by rulers as useful.
QAC++ made by Programming Research Its by far the best static analysis tool out there. They also make QAC which again i find to be the best startic analysis for C. Very useful when coding for embedded systems i believe they also make QAJ, but i dont think its as good as their main two tools
I wouldn't trust it. The people who write bad code will write bad debug detection code... especially if they are coders who have been outsourced and do not care if it works or not.
The code in javac is more than three times the size of my HelloWorld program, so I'm not sure it's compiling it correctly. Especially if Sun farmed out javac to some outfit in Bangalore. They won't care if it works. I'm scared to run my program now. What if it doesn't say "Hello World"? It might say "Goodbye world" and then delete my hard drive since the javac guys just don't care.
I'm just going to have to hand-assemble the bytecodes myself. I don't trust anybody!
For example:This gives:With static typing, that's in C++ for example when you don't use virtual, you don't get B::f() when the last myA.f() is called. That's because Java resolves the type of myA dynamically, and not statically.
C++ static example:Now, this gives:The second A::f() means that the type of myA is resolved statically.
If you make f() virtual, it is resolved dynamically, as in Java for the caller object (not for the parameters).
This will give you a B::f() on the last line, try it.
Please explain what you meant or stop posting BS when I'm just out of a course entitled "Comparing C++ and Java object models".
IntelliJ Idea (http://www.jetbrains.com/), a java IDE, has had "custom bug detectors" in it for a while. And you can add your own, via the plugin api, and you can select which ones you want on/off, and its part of the tool, like it should be. You get a GUI for fixing it, that matches compiler based syntax errors, etc. Makes me wonder if IntelliJ features came first, or this open-source project did. Anyone know?
Clearly you are a youngin that has been indoctrinated by educators because it seems that java is all they will teach nowadays. I fail to understand why. I assume its laziness, lack of funding and loss of touch with the real world.
.... maybe the anonymous Trolls need to come out of thier holes and visit the real world now and then.
I find it amusing that all of the people posting about their positive experiences with Java have user id's less than 50000, meaning they have been around here quite a while.
The trolls are all anonymously sprouting FUD
You've clearly never ever developed anything in Java before. Perhaps you've heard the saying "Do not hold strong opinions about things you do not understand"... I've been developing a fairly large Java application for over 5 years, and the old beta versions that were written for Java 1.3 work unmodified on the Java 1.6 beta.
Your statement is 100% false, face it.
The fact that Java allows this behaviourto go unnoticed during compilation is the reason for most non-business problems found in applications.
You can't handle the truth.
I am writing this from my car, and I am in a hurry, so I won't reply to everything right now, maybe later, but this one:
Why would you not want a program to catch bugs for you? The only reason you write unit tests is because the language and tools you're using are not powerfully enough to detect these problems statically. I take an exception with this one.
Unit tests are not only about correctness of the language constructs, unit tests complement documentation, they are business constructs and no detector can do this for anyone ever because all business problems are different.
Of-course unit tests assert specific output on specific input but the the reason behind the output given this input has to do with the problem at hand, not with the language constructs or with your ability as a programmer to find concurrency bugs in applications.
Ok, later.
You can't handle the truth.
Java frameworks will make this an awfully expensive pursuit.
Anyone can write pretty code to hibernate and make huge mistakes.
Same with pretty much every other framework.
In the given example...wouldnt the test have failed?
All hammers are not equal true. But you have to be able to carry
your toolbelt to work and at work without breaking your back
and your shops.
Thats not cheating the Java type system.
... that is cheating the type system, because the type system thinks: oki, b is of type A.
Cheating is:
class A {}
class B {}
A a = new A();
B b = (B)a;
Without any exception!
In C++ you would need to add a "*" to the declarations and you could write it like above and it would WORK!!!!
In Java the assignment causes a ClassCastException in C++ the assignment works (Depending on C++ language standard). In C++ ypu get likely a crash as soon as you use a method on the object b
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
"if you fully understand exactly what your application is doing at every point, and do not rely on someone else's code (read libraries or classes)..."
you'll drop dead before you ever finish writing it.
I wish I were as sure of anything as some people are of everything
I got that. My point was that you don't need to determine if an arbitrary program is error-free in all of those categories to have a useful tool. If static checkers can point out a bunch of errors in a huge program and a bunch of places they're suspicious of, then they are useful. And they can. Did you follow that Stanford Checker link? It detected all of the classes of errors you mentioned. Sure, it missed many more errors of those classes, and actual humans had to give it some project-specific knowledge for that to happen, but it seems like a good investment - it saves more time than it takes.
I'd rather see them put the time into whatever tool seems to be helping them most at the moment. And then when it reduces their debugging time, they can use the surplus to try other things. You seem to be making a lot of assumptions - that doing something perfectly is useful but doing it well is not, that the time available for program verification is constant, etc.
As an example of turning bug instances into bug patterns, I always read through the list of bugs fixed in each version of the jdk1.6.0 builds. In build 89, a bug was fixed in the serialization of ArrayBlockingQueue.
I wrote a FindBugs bug detector to look for similar cases: a class with transient fields, but no readObject or readResolve method to restore the field. I had to tune the detector a bit (for example, raise the priority if it is set to a non-default value in the constructor). I'm still doing some tuning, but at the moment the new detector reports warnings in 47 jdk 1.6 b89 classes, 18 of which are confirmed to be bugs. This took me a total of 5 hours of work.
Bugs listed below (these have been reported to Sun); this detector isn't in the current 1.0 release of FindBugs, but is available is the latest CVS snapshot, and will be in the next release.
Bill Pugh
-----
java.security.Timestamp and java.security.CodeSigner:
they have a transient myhash field used to cache the hashCode that is
initialized to -1. If you serialize/deserialize one of these
and invoke hashCode on the result, you'll get an incorrect hashCode of 0.
javax.management.AttributeList
has a transient boolean field tainted. If you add something other than an Attribute
to an AttributeList, serialize/deserialize it, and then invoke asList(), you get back
a List that contains something that isn't an Attribute. If you call asList() on
the original AttributeList, you get an exception.
javax.management.relation.RoleList
javax.management.relation.RoleUnresolvedList
problems isomorphic to the above problem
sun.util.BuddhistCalendar
has a transient field yearOffset that is initialized in the constructor. If you
serialize/deserialize a BuddhistCalendar, you get back a broken BuddhistCalendar
that computes dates incorrectly (off by 543 years)
javax.swing.DefaultDesktopManager
has a transient field floatingItems that is initialized to an empty array of Rectangles, and
it sure looks like the code is assuming that floatingItems is assumed to be nonnull, so
if you serialize/deserialize it, it will be broken (of course, I can never be sure if
anybody seriously intends for awt/swing objects to be serialized.
com.sun.rowset.CachedRowSetImpl
com.sun.rowset.FilteredRowSetImpl
com.sun.rowset.JdbcRowSetImpl
com.sun.rowset.JoinRowSetImpl
com.sun.rowset.WebRowSetImpl
com.sun.rowset.internal.CachedRowSetReader
com.sun.rowset.internal.CachedRowSetWriter
com.sun.rowset.internal.InsertRow
com.sun.rowset.internal.SyncResolverImpl
com.sun.rowset.internal.WebRowSetXmlReader
com.sun.rowset.internal.WebRowSetXmlWriter
com.sun.rowset.providers.RIOptimisticProvider
all initialize in their constructors transient fields pointing to resource bundles
for providing localized error messages, and the resource bundle will be null if the
an object is deserialized and serialized.
javax.smartcardio.CommandAPDU
has 3 transient fields (nc, ne and dataOffset) that are computed by the call to parse in the constructor
from the apdu array. However, if the object is serialized/deserialized, the fields will have their
default values.
Well you've obviously never written anything in a complex Java environment. I've seen apps I've worked on break in 1.5 where they worked fine in 1.4.2_08. This caused our team huge headaches because it was an applet problem that had already been installed on a lot of client machines, some external to the organisation I worked for.
I don't know the GP from a bar of soap, but if you're going to call someone a liar how about you check your facts first.
These posts express my own personal views, not those of my employer
Could you give an example of what you mean here (e.g. a description of a simple function and why you would always be required to write unit tests)? - do you work? Seriously? Here is an example: A service code at Bell Canada is a two character description of a program or a service or a piece of rental equipment. The current big project at Bell is called All In One (AIO) (all different order capture systems are being put into one large system.) There is a function, that makes a decision whether a newly activated receiver is within AIO or it is a Genesis receiver (legacy service.) This function has to retrieve model and package information for a receiver, retrieve and cache a list of AIO packages and decide whether the the currently activated receiver is AIO or not. The function retrieves data with a data controller (this is a Weblogic Integrator project, so it follows BEA WLI architecture practices,) it then caches the data if it is not cached yet and then it compares the data from the current receiver to the cached data and makes a decision on whether this receiver is AIO.
The unit test sets up the necessary data and the database tables, sets up receiver information and runs the function and makes assertions at the end. This unit test is a part of a unit test suite that tests various business functions for the project. The unit test asserts that the function correctly implements the current requirements. The unit test is tied to a specific requirement. If the requirement changes, the unit test will change first to accomodate the new requirement and then the function will be modified.
The database drives the functionality of what is AIO and what is not, by changing the database, the output of the program is modified for different receivers.
1. It is impossible to know what the exact data will be.
2. It is guaranteed that the data will be modified once in a while (first time it will be preset on the 14th of July.)
3. It is necessary to have the unit test check the boundary conditions, and so there is more than one unit test (actually it is the same unit test ran with different data sets on all known boundaries and some cases between the boundaries. The boundaries include empty set, one element in the set per model, an arbitrary number of elements in the set per model, where there is either none, one or an arbitrary number of models.)
4. There is no way to tell what the models will be, what the packages will be, so there is no way to test for ALL inputs. No amount of time given to an inference engine can ever finish testing a function for an unlimited input size.
Good night.
You can't handle the truth.
...and actual humans had to give it some project-specific knowledge for that to happen, but it seems like a good investment - it saves more time than it takes. - that remains to be seing, I am not easily convinced of that, maybe I am jaded but I have seen to many instances, where maintenance and usage of a tool is more of a hindrance than help for a project.
You can't handle the truth.
Because it's a ridiculous challenge, perhaps, and ignores a whole range of things that are actually more important? I've seen plenty of Java applications that do something useful in a mission critical environment, and there are no C/C++ applications for the same task because the Java one works just fine. You've also completely ignored the question of ease of development and maintainability, which is worth far more than raw performance in a real-world environment where throwing an extra CPU at the job is cheaper than hiring another developer to bug-fix.
++ Say to Elrond "Hello.".
Elrond says "No.". Elrond gives you some lunch.
OK, slashdot user id's are a measure of programming knowledge?
No but AC posting is often the measure of a clueless troll, not always but in your case it seems to fit well.
Show me a java application that actually does something useful in a mission critical environment that performs better than a C/C++ application for the same task and is truly platform independent.
If you look you will find there are plenty of java applications that do what they need to do, are as fast as any C/C++ application , are robust, easy to maintain and are cross platform. In fact Java applications are most likely doing a whole bunch better these days compared to C/C++ applications in the business arena.
Your attitude is very 90's, Java has come a long way since then. I suggest you grow up and have another look at whats out there.
If memory is finite and the program is non-interactive, the stop problem is decidable. All you have to do is simulate the program with a fixed input and create a copy of *all* the memory (assuming that the input and the program counter are in that memory) at each step. If a certain memory snapshot repeats itself, the program will never stop. This, of course, means that the program cannot be interactive, because the input must be fixed and of fixed size before you begin the simulation.
There is a whole theory in mathematical logic dealing with the stop problem on interactive programs working with finite memory. Look up 'automata over infinite objects'.
Well you've obviously never written anything in a complex Java environment. I've seen apps I've worked on break in 1.5 where they worked fine in 1.4.2_08. This caused our team huge headaches because it was an applet problem that had already been installed on a lot of client machines, some external to the organisation I worked for.
It is great the way that posters assume things! I work on substantial Java applications daily - apps with hundreds of thousands of lines of code.
There are very complex Java applications that run unchanged on different versions of Java - JBoss, NetBeans for example. These are app servers and IDEs - it is hard to think of apps that are more complex. I have never seen a single app break between Java 1.4 and 1.5.
It is great the way that posters assume things! I work on substantial Java applications daily - apps with hundreds of thousands of lines of code.
/. stupidity never ceases to amaze me.
Talk about the pot calling the kettle black. You called the GP a liar because his experience didn't match yours. How dare you then come back and point the finger at someone making assumptions you hypocrite!
There are very complex Java applications that run unchanged on different versions of Java - JBoss, NetBeans for example. These are app servers and IDEs - it is hard to think of apps that are more complex
I have never seen a single app break between Java 1.4 and 1.5.
Well I have. "It works for me on my machine so stuff you" is nonesense that no professional should be uttering, let alone calling a perfect stranger a liar because they've seen something you haven't.
Explain my experience then. I'm either lying (and I happen to know for a fact that I'm not, and would gladly prove it if it didn't require breaking my contract and if I thought it would sway you one bit).
JBoss and Netbeans are just two technologies. Most of my experience happens to be with Eclipse though I have used Netbeans, and Weblogic though I've also used Tomcat and JBoss. So what. There are more technologies out there that neither of us have used than you could shake a stick at and to make the assumption that no applications have broken just because you haven't seen it is both arrogant and ignorant.
What do you do when your users complain there's a bug you can't reproduce? Shut your eyes, put your hands over your ears and shout "la la la la la" at the top of your voice?
These posts express my own personal views, not those of my employer
Talk about the pot calling the kettle black. You called the GP a liar because his experience didn't match yours. How dare you then come back and point the finger at someone making assumptions you hypocrite!
/. stupidity never ceases to amaze me.
No, I did not call the GP a liar. I am careful with wording.
Well I have. "It works for me on my machine so stuff you" is nonesense that no professional should be uttering, let alone calling a perfect stranger a liar because they've seen something you haven't.
Again, I did not call him a liar.
Explain my experience then. I'm either lying (and I happen to know for a fact that I'm not, and would gladly prove it if it didn't require breaking my contract and if I thought it would sway you one bit).
Then why are you bothering posting if you can't prove it? I am not saying you are lying. It is certainly possible to write apps that break from one JRE to another, but it is also pretty simple to ensure they don't - the release period between JREs are long, and the guidelines are clear. But if you can't provide actual evidence, what is the point?
JBoss and Netbeans are just two technologies. Most of my experience happens to be with Eclipse though I have used Netbeans, and Weblogic though I've also used Tomcat and JBoss. So what. There are more technologies out there that neither of us have used than you could shake a stick at and to make the assumption that no applications have broken just because you haven't seen it is both arrogant and ignorant.
They aren't just two technologies - they are illustrations of a wide range of aspects of the JRE - GUI, multithreading, file handling, networking, concurrency. If anything should break between releases, these should.
I did, of course, not say that no applications have broken. I said I have not seen any that have broken, and this includes very complex apps.
What do you do when your users complain there's a bug you can't reproduce? Shut your eyes, put your hands over your ears and shout "la la la la la" at the top of your voice?
I fix the bugs. I deal with them. I write my apps and test them on different JREs. To write an app so tied in to one JRE that it breaks on a new one is, these days, inexcusable and a sign of bad development practice. If Tomcat and NetBeans can manage for this not to happen, so can everyone else. There has rarely been a technology that is so backwards compatible as Java.
Well, see the example I gave is not exotic, it is very indicative of a real world problem and it is just one function out of hundreds in on component of a large project. Really, most problems in large real-life projects are not normal algorythms for sort/search/combinatorics, most unit tests are used to test business functions such as SQL statements and business algorythms that are basically pieces of business requirements. Certainly if all that we were writing was just simple sorts/searches/data structures/quickest paths/graph traversals, basically all the stuff from Knuth :) or just the theory that you get to learn at the university, then the automated tools would have covered everything nicely. But unit tests test pieces of business logic, like what I have to do at Bell, or what I had to do at Hydro One or ADP, or IFDS, or Avema, or Symcor, or Christie Digital or the banks or insurance companies (I am a contractor.) And it is all domain specific. So I regard unit tests very highly due to the fact that they are descriptions of business problems, not computer science algorythms. Normally on contracts I lead teams, create designs and develop software and set the minimum standards for the project, and these standards include common frameworks for unit testing. So I always insist on common approach to unit testing, and actually we have to often use unit testing frameworks to do some integration testing where possible. I may take a look at these bug detectors and see what it takes to set up and configure the tests. If these tests are not intrusive and the developers themselves do not have to do anything additional in the code to accomodate the tests I may in some projects add these detectors to the build procedure. But it is all case by case scenario and it will depend on many things like the deadlines, resources, complexity of the project, number of people on the project on whether the project a new one or is it an addition/modification of an existing one and whether there are actually bugs that are being discovered that are similar to the bugs that this tool can detect. So it will take sometime to build enough knowledge about what this detectors can do and whether they can help in specific situations before I will let my teams use them.
:) have a good one.
Well, back to work
You can't handle the truth.
That's not the correct way to be doing things, anyway. Try this instead
You missed the part where I compared it to cooperative multi-tasking.. You are wrapping the collection at constructor time, BUT half (and I do mean half) of the time you don't have control over the constructor to an object.. Especially if you are writing middle-ware code, which is most of what Java does - at least good application designs write most of their code in the form of middle-ware.
Take Sort for example... It can't depend on the fact that even though it asks for a generified collection that there is any sort of type-safety involved.. The only thing it can do is pre-validate the data-type of the existing items in the collection that is passed to it. But that's a performance hit, and the ONLY thing that this will do is produce a more meaningful runtime exception.. i.e. instead of an exception in the comparator you get one in the sorter with an explicit "element in collection of type X was really Y" RuntimeException.
Caches, Marshellers / Serializers, IPC services, persistence sercies, etc. They all are middleware applications which throw really really confusing errors sometimes because they aren't passed the expected classes. And when I say confusing, I mean they don't often throw class-cast exceptions, but instead meta-data mismatch exceptions.. But that leads you to believe that you've missed an attribute in the XML configuration instead of the fact that you've adding an object of the wrong type to the middle-layer.
Ideally, generics would be fully enforced by the VM. What we currently have (even with the spettering of Collections.unmodifiable,synchronized,checked etc are weak-enforcement which at best provides spot cleanness of code.. But any static anylizer tool could have detected innappropriate local bugs.. The more critical bugs are inter-moule bugs. And APIs of that sort tend to be littered with innappropriate parameter-checking. If you don't think this is a problem, then what is the number 1 security loop-hole in most older C libraries? gets(). This function (for performance purposes) didn't verify the size of the string so it allowed the over-flowing of the buffer and overwriting of user-space memory. Most other languages handle strings in a less performant, but more robust manner, so this type of bug has mostly dissapeared.
In java, with the advent of dynamic proxies and aspect-oriented-programming, the situation is even worse, because inter-module libraries can proxy objects which don't even match the appropriate prototype/interface. So you actually wouldn't get a class-cast-exception, but instead an arbitrary exception (most likely an NPE) inside the InvocationHandler.
This is mostly a rant, but it's based on my growing frustration with the lack of type-safety in java frameworks... Yes, you're certainly free to not use those frameworks.. But with the increasing movement into container-managed services (tomcat, jboss, or even spring/pico-container), this type-looseness is becoming a growing problem.
-Michael
The GP complained that he'd seen Java apps break. You said you hadn't and that you couldn't imagine more complex apps. You were definitely implying he was a liar. This isn't a court of law so burdens of proof don't apply here. To me your intent was very clear.
5 31
In your latest post again you insist that because you haven't in your very limited experience seen Java apps break, that it's rare. It's not.
Google for the following phrase:
java 1.5 breaks application
You get such links as:
http://developer.apple.com/qa/qa2006/qa1474.html
http://forums.macosxhints.com/showthread.php?t=47
That's just the tip of the iceberg and I'm not going to do any more work proving that things have broken because with your attitude I don't see you admitting to a mistake.
Guess what happens if you use any 3rd party product that is in any way incompatible. You need to get another version of that product.
Now you're obviously not interested in reality. In your mind because you haven't had the displeasure of working on something that's been badly broken by a JRE release all is good. Enjoy living your fantasy but don't force it down other people's throats or belittle them when they point out that they've seen it happen.
These posts express my own personal views, not those of my employer
The GP complained that he'd seen Java apps break. You said you hadn't and that you couldn't imagine more complex apps. You were definitely implying he was a liar. This isn't a court of law so burdens of proof don't apply here. To me your intent was very clear.
5 31
No, I was clearly saying that complex apps obviously don't break with version changes.
In your latest post again you insist that because you haven't in your very limited experience seen Java apps break, that it's rare. It's not.
Yes, a very limited experience based on being a developer for 30 years and using Java since it came out.
You get such links as:
http://developer.apple.com/qa/qa2006/qa1474.html
http://forums.macosxhints.com/showthread.php?t=47
That's just the tip of the iceberg and I'm not going to do any more work proving that things have broken because with your attitude I don't see you admitting to a mistake.
Oh for goodness sake! This suggests that you really don't understand the issue! Those links you showed aren't the 'tip of the iceberg' - they are most of it. Of course things wont work if you compile specifically for a later version of the JRE and then expect it to run on them. That is a crazy as expecting an app compiled for MacOS/X to run on Mac OS 7!
This is not an issue of JRE upgrates breaking existing apps - it is an issue of using a JDK upgrade and not taking into account the fact that the compiler produces code for the equivalent JRE. There is nothing wrong with than, and a simple switch can change this.
Guess what happens if you use any 3rd party product that is in any way incompatible. You need to get another version of that product.
Only if that 3rd party product relies on a later JRE or JDK, in which case it is entirely reasonable.
Now you're obviously not interested in reality. In your mind because you haven't had the displeasure of working on something that's been badly broken by a JRE release all is good. Enjoy living your fantasy but don't force it down other people's throats or belittle them when they point out that they've seen it happen.
I haven't worked on something that has been badly broken by a JRE release, because few people have. You haven't shown any such thing. All you have shown what happens if someone compiles for a later JRE and tries to run it on an earlier one. Do you seriously expect all your clients to automatically upgrade to JRE 1.5? Of course not. It is your responsibility as a developer to take into account the versions of runtimes your clients use. If you update your compiler (javac), it is your fault if things break.
You get such links as:
http://developer.apple.com/qa/qa2006/qa1474.html
http://forums.macosxhints.com/showthread.php?t=47
That's just the tip of the iceberg and I'm not going to do any more work proving that things have broken because with your attitude I don't see you admitting to a mistake.
This is quite laughable. Both of these links have nothing to do with the fantasy that you are trying to propogate.
Your credibility = 0
Nice one! I'll be adding it to IntelliJ IDEA on the train to work this morning.
This is quite laughable. Both of these links have nothing to do with the fantasy that you are trying to propogate.
Your credibility = 0
I second the zero. Cough up some code, troll, or admit that you're a 15 year old who recently wrote a CS101 fibonacchi generator in C++ and thus you hate java because all cool c++ gurus on teh intarwebz do.
Since your comment was neither modded up -- which it deserved -- nor replied to -- which is equally as disappointing -- I wanted to let you know that I, for one, have read it several times. It was insightful, and I have nothing to add other than "well said."
This is quite laughable. Both of these links have nothing to do with the fantasy that you are trying to propogate.
The "fantasy" I'm trying to propogate? You're truely dillusional and brainwashed if you believe that upgrading or changing your JRE can't break your apps. Have fun living in your fantasy. A credibility raiting from a fool is of no interest or consequence to me.
These posts express my own personal views, not those of my employer
Look I've seen code break. You haven't. I don't care if you get a team of 30 coders with a combined experience of 900 years to tell me their apps haven't broken. I've seen apps break, and not only when the code's compiled for a later JRE. We've had to develop specific workarounds and re-release stuff due to this. I can't show you because I'm bound by an employment contract and I'm not about to embarass my employer even if I wasn't. That you don't believe me doesn't make an inkling of difference to my life. Enjoy your fantasy.
...complete with a whole section on runtime issues
1 921&messageID=42128216 00.html2 494&messageID=2042086d =4783788d =6204839
If you are going to reply at all the first thing I challenge you to do is explain this migration guide by Sun for Java 1.3 to 5.0:
http://java.sun.com/j2se/JM_White_Paper_R6A.pdf
More references. Again not the best. Wish I could show you my good example but see above.
http://forum.java.sun.com/thread.jspa?threadID=73
http://www.codecomments.com/archive251-2005-5-498
http://forum.java.sun.com/thread.jspa?threadID=43
http://bugs.sun.com/bugdatabase/view_bug.do?bug_i
http://helpdesk.wisc.edu/page.php?id=2891
http://www.javalobby.org/java/forums/t18329.html
http://bugs.sun.com/bugdatabase/view_bug.do?bug_i
The above links very clearly show installing the latest JRE is not sufficient to run all your old code. With many Java applications, you can't just remove all older versions of a JRE and upgrade to the latest.
I also recall that if your code is applet based, the tags used to invoke the JRE changed after Microsoft dumped their custom JVM due to the legal action between Sun and MS.
The bottom line is that you're calling anyone who has seen anything break due to a newer JRE a fool and a liar based on your "30 years of experience". I know for a fact that this is false. Your arrogance is astounding and your insistance on this makes me wonder what you've been doing for 30 years since I know of no complex environment where the runtime backward compatibility is so fantastic that you don't need to test a new version to be sure it works for your application.
These posts express my own personal views, not those of my employer
Here you go. Get your info straight from Sun. See the section on runtime errors.
http://java.sun.com/j2se/JM_White_Paper_R6A.pdf [sun.com]
Getting your adolescent friends to second your opinion or creating a second account to bolster yourself is completely juvenile.
For your info I'm over 30, have a bachelor and masters, and have been doing this for some years...all of which has no bearing on the truth of what I've said of course.
These posts express my own personal views, not those of my employer
First, let me say that you seem to have a tendency to respond to what you think I wrote, not what I actually did.
I have never said that no apps ever break with JRE upgrades, or that you never need to test things with different JREs
What I have actually said is that issues with JRE updates are rare. Java is one of the most backward-compatible systems ever produced. Nothing you have said and no links you have provided have demonstrated otherwise. You seem to be considering matters of how to access JREs or how to package applets as if they were somehow related to the Java language and compatibility. They aren't. You have provided a very minor list of issues that may occur when people upgrade from Java 1.3 (released 6 years ago!) with Java 1.5. That minor list simply emphasises how few programs are going to break, and the minor matters involved.
I realise you are not in a position to give a personal example, but that does not help the debate. Until you can give some specific reason, I can't see any point in continuing.
If anything, this conversation has helped prove my point - that the suggestion made by a poster a while back that 'all your old aplications do not work at all anymore when users install the new JRE' is utter nonsense. (note the use of the word 'all' - not 'some', or 'a very few', but 'all'!).
It it is so obviously nonsense that I can't see why anyone is bothering to argue against it.
First, let me say that you seem to have a tendency to respond to what you think I wrote, not what I actually did.
.com bust and try and run that without any kind of change. If it's complex I'd give you even odds it breaks.
...and yet you do continue.
Let me say you have a tendancy to word things so as to imply other things, then back down when confronted with facts.
What I have actually said is that issues with JRE updates are rare.
I say bollox to that.
Java is one of the most backward-compatible systems ever produced.
It's one of the most widely used systems that has been designed with backward compatibility in mind, I grant you that.
Nothing you have said and no links you have provided have demonstrated otherwise.
Yes typically if someone wants to be stubborn nothing convinces them to change their opinion.
You seem to be considering matters of how to access JREs or how to package applets as if they were somehow related to the Java language and compatibility. They aren't.
Wait a second there and get your straw man out of my face. You are claiming that Java (I presume that includes the runtime) is "one of the most backward compatible systems ever produces" then you takl about Java the language separately as if that's all you were ever speaking off. The grand parent didn't go into language syntax, he said JREs broke. Make up your mind what you're arguing and stop trying to employ such obvious sophistry.
You have provided a very minor list of issues that may occur when people upgrade from Java 1.3 (released 6 years ago!) with Java 1.5.
Shall I go and chase down every change between minor versions that caused something to break? I've demonstrated my point which is that it's not all that rare. If Sun thought it was important enough to produce a document, and most sane developers feel the need to retest with new JREs I'd say compatibility is an issue.
Go find some 1.0.2 code from the
That minor list simply emphasises how few programs are going to break, and the minor matters involved.
I think if I went and pulled down 1000 examples you'd claim they're only minor. The word fanboy comes to mind.
realise you are not in a position to give a personal example, but that does not help the debate. Until you can give some specific reason, I can't see any point in continuing.
If anything, this conversation has helped prove my point
Only if you're in the habit of ignoring problems and hoping they'll go away.
that the suggestion made by a poster a while back that 'all your old aplications do not work at all anymore when users install the new JRE' is utter nonsense. (note the use of the word 'all' - not 'some', or 'a very few', but 'all'!)
I think you know perfectly well that all was an exaggeration. Java is designed with the intent of backward compatibility. However many many apps do break. You just dismiss it as so rare no one should bother worrying about it.
Summary of this debate. You spot a post where someone points out Java isn't always compatible between releases and that this can cause a headache. You say I've rarely seen things break. I say I have seen things break quite a bit and provide what examples I'm free to. You insist these are minor and choose to ignore them.
Good luck. I live in the real world. If I depend on something, I expect some breakage between versions and test and fix accordingly. I think that's a much better solution than yours which is to tell people its rare. Not just for Java. For any software btw not just Java: Every version of Windows breaks some apps. I'm not saying don't use any piece of software but I am saying don't pretend change doesn't break things no matter how well done.
These posts express my own personal views, not those of my employer
This is a program that will never have the same memory pattern, and (given infinite memory) will never terminate.
The stop problem is undecidable in general; in very special cases you will get a 'yes' or a 'no', but never in general.
Yes, I said, in a computing device with *fixed* memory.