Developing software is a very tough business. But days like this make me believe that the world would be better off without software! For two days I have fought a very simple but elusive issue in Eclipse. Basically, when I installed Eclipse it wasn’t picking up any execution environments so no project would compile nor run. A screenshot of the empty Execution Environments screen is below.
Empty Execution Environment
I first thought this would be an easy problem to fix so I used the world brain. When that failed, I had to actually use my brain. It turns out, Eclipse gathers information about JREs available and stores that information in a configuration file (libraryInfos.xml in the .metadata/.plugins/org.eclipse.jdt.launching/ directory inside the newly created workspace). And I think this auto-generation is where the bug lies. Specifically, when Eclipse grabs the version information from a newly added JRE/JDK it can get corrupted. When it works correctly the Execution Environments screen looks like the following. FYI, in this case I used the Sun JDK 1.6 to run Eclipse.
Available Execution Environment
Here is a snippet of the libraryInfos.xml file when the bug is visible: <libraryInfo home="/opt/sun-jdk-1.6.0.07" version="CompilerOracle: exclude org/eclipse/core/internal/dtree/DataTreeNode.forwardDeltaWith 1.6.0_07">
and here is a similar snippet when the bug is not visible: <libraryInfo home="/opt/sun-jdk-1.6.0.07" version="1.6.0_07">
Notice that the version information is pretty funny looking?
And it looks like it is connected to the .hotspot_compiler file that I am using. The contents of it are: exclude org/eclipse/core/internal/dtree/DataTreeNode forwardDeltaWith
which causes the following to be printed on the command line when Eclipse starts: CompilerOracle: exclude org/eclipse/core/internal/dtree/DataTreeNode.forwardDeltaWith
So I assume this is a bug since it would be a crazy feature. My work-around is to move (or rename) the .hotspot_compiler file the first time I run the new Eclipse. I then add the Java JREs, close down Eclipse, move the .hotspot_compiler file back, and then restart Eclipse. Once the JREs are added the issue no longer persists (unless new JREs are added).
I recently read “Correctness by Construction: Better Can Also Be Cheaper” by Peter Amey and found it very interesting. As I worked in the SAnToS Lab for the last couple of years, I have become convinced that correctness by construction can certainly save time and money. So it is nice to see a well thought out and supported argument that this methodology is good.
The author’s stated goal is to “prevent errors ever making it to test.” Quite a worthy goal and something that would save time and money in development. And our lab shares this goal as we develop our products (I say product very loosely since our software is more like academic research prototypes).
One of the best parts of the paper is the reference to “Cost Effective Approaches to Satisfy Safety-Critical Regulatory Requirements” that details the improvements that Lockheed Martin saw using this type of approach. They got 4-fold productivity gains (over previous comparable programs), 10-fold quality improvements (over industry norms), and the cost was half (in comparison to non-safety critical code). This provides real numbers to debate the correctness by construction approach.
While I like the fact that there was data used in this paper, I have trouble with the 10-fold quality improvement claim since it compares it to industry norms. That isn’t exactly an apples-to-apples comparison so it isn’t overwhelming evidence. Good data, just not enough for me to claim it is conclusive.
I also wondered about another statement from the paper. In the paper the author says “…time is spent in the integration and validation phases … We are spending most of our time at the most expensive point in the life cycle.” I wonder if other methodologies might offer alternative ways to deal with this problem. I was thinking the (relatively new) agile methodologies might reduce the cost of integration and validation since they will be done more often and throughout the process.
In the paper the author says “Worse, it is the point at which any delay will inevitably affect the overall program schedule.” I don’t like how this is stated since I believe that any delay will affect overall program schedule, not just those delays that happen during the integration and validation phases. I think it is true that they become more costly. I further think that delays during these phases are harder on the project simply because there is less available slippage time towards the end of the project. So I agree with the authors point (delays during integration and validation are tough on projects), just not the way it is stated.
In the paper the author says “Purpose-designed languages with formally defined semantics are a fascinating research topic but are unlikely ever to achieve the kind of critical mass required to make them suitable for widespread industrial use.” I was stunned by this statement and the paragraph used to support it. Keep in mind that my research group is working in this area (creating tools to make it easier to develop using domain-specific languages). I have a hard time quantifying “widespread industrial use” since SPARK and Ada are probably far from that in my mind (I would say C, C++, and Java are the ones I would name off the top of my head as being in widespread industrial use). The author also goes on to say “It also has several major flaws: you can neither buy a compiler for it, nor a textbook, nor get training, nor hire staff! This is a fundamental drawback of the custom language approach.” I can understand that a closed language that only has closed tools has those major flaws. But an open language (published syntax and semantics) means that anyone can develop tools for it. And an open source tool chain means that everyone can use, share, and extend it. So a custom language is not exactly what the author should dislike. He should dislike proprietary languages whose syntax, semantics, and tools are hidden. And on the other hand, the author should like open languages that have open tools.
In the paper the author says “So our first opportunity to explore the behavior of the software in any rigorous fashion occurs very late in the development cycle with malign consequences.” Maybe I don’t quite understand what the author is getting at but there seem to be many ways to explore behavior of software well before object code. For example, using the original Cadena, a developer could specify the internal behavior of a component using a state-machine. The behavior of the system could then be analyzed to explore the software well-before object code is written. And I assume there are many other tools in this area where modeling is done and some form of analysis is performed on the model. I am not that familiar with Alloy and Alcoa but that seems to be its purpose.
Even more, a development team could use a test-driven approach to development which allows them to explore the behavior from day 1 in the development cycle. Or even using symbolic execution (e.g., Kiasan or JPF) so that the whole of the system doesn’t need to be available, just the portion under analysis.
What is a safety-critical system? They define it in the following way: “Such systems are characterized by the proportionally very high overall effort that goes into showing that the system is fit for service: the V&V effort.”
What is MC/DC? I obviously didn’t pay enough attention in my software engineering classes. But this page was able to educate me on what it is.
What is a purpose-designed language? I couldn’t find a definition for this but there were several references to it when I searched Google. My assumption is that this is the same thing as a domain-specific language.
What does “thin-slice” mean? I couldn’t find a good definition of this but found a reference in a book titled “Service- and Component-based Development: Using Select Perspective and UML” by Hedley, et. al.
What is the “Newspeak” language? This is a reference to the book “1984″ written by George Orwell. It also appears to be a reference to a language quoted in a book about Alan Turing. The author uses a reference to this as a justification that custom-languages are not a viable approach to the stated problem.
Overall, I really enjoyed the paper. It states real issues in developing safety-critical systems and offers a solution. I just wish the author would have made a more compelling argument – if I didn’t already believe it, I might not have agreed with the paper.
Last week I posted my first bug reports to Eclipse.org’s Bugzilla database. Tom Grosman (leader of the Hibachi project) suggested that I submit my patches as bug reports in their official bug database.
My second bug report (or enhancement) was about making parameters available as children of subprograms (procedures and functions). I mentioned this in a separate post earlier.
My third bug report (or enhancement) was about making an extension point available in Hibachi so others can create their own outline views. I mentioned this in a separate post earlier.
This is quite an achievement for me since I have never contributed to an open source project like this. I have reported bugs but never gone this far in diagnosing and fixing issues. And I hope these won’t be my last.
As I worked through my outline view extension of the Hibachi UI, I realized that it would be great to re-use the icons that are already available in the Hibachi UI and currently used in their outline view. It would be even better if the icons were accessible in a standard way (similar to the Eclipse Workbench UI, JDT UI, and Team UI conventions currently used).
The standard pattern that I have found is as follows:
Provide a Java interface that has String constants that map to each icon available. The name should be ISharedImages and the interface should declare 2 methods: 1) getImage(String) : Image and 2) getImageDescriptor(String) : ImageDescriptor.
Provide a static method (which is public) on the main plugin class that will get an instance of ISharedImages. It is typically named getSharedImages() : ISharedImages
Provide a class that implements ISharedImages. This class can be hidden from use by others in an internal package and not exported by the plugin.
The Hibachi UI isn’t currently implemented in this way but it is quite close. The Hibachi UI plugin does provide some String constants and a method in the main plugin class. The follow snippet gives an idea of what is currently implemented in the UIPlugin class.
public static final String ICON_PROCEDURE = “procedure.gif”;
public static final String ICON_FUNCTION = “function.gif”;
…
public static ImageDescriptor getImageDescriptorForIcon(String name) {…}
This allows the UIPlugin to cache ImageDescriptors but still forces the user to create and dispose of the Image (which is the important one to cache). So I took it upon myself to patch their UI plugin to provide this in the same way that other Eclipse plugins share their images (as described above). This will likely reduce the amount of memory because Images will be cached as well as ImageDescriptors. It will also make it easier for developers that extend Hibachi and make use of the icons because they will no longer have to create and destroy the Image.
My first task was to create the ISharedImages Java interface to hold all the constants that map to all of the images (icons) available in the Hibachi UI plugin. I chose to put that interface in the org.eclipse.hibachi.ui package so that it would be available to other plugins (that package is already set as “exported”). This also seems to be the standard location for the interface.
The second task was to create a class that implemented ISharedImages. I chose to create the class in the org.eclipse.hibachi.ui.internal package and name it SharedImages. This class implements the 2 required methods with some simple (straight-forward, pass-through) logic. In other words, it makes use of existing logic that was used to load and cache images but was not available outside the plugin (see the SWTResourceUtil and AdaPluginImages classes).
The third task was to create a method in the main plugin (UIPlugin) to get an instance of ISharedImages. This method uses the lazy initialization pattern (single instance that is a private field that is created the first time the method is called). This was easy to declare and simply creates an instance of SharedImages (which implements ISharedImages).
To make sure I did it correctly I wrote some code in our outline view plugin that grabs images. Testing that code brought a smile to my face since it worked the first time (which hardly ever happens for me).
At this point I have working code that matches the standard pattern but there is a lot of duplication of effort in the plugin. I would like to find a way to reduce that. For now, I will simply submit this patch and hope someone else can help make it better. Hopefully this patch is useful and will be merged into the mainline for the Hibachi project.
I am always annoyed when users contact me with questions that are answered in documentation that I have taken the time to write. I am always reminded of what Joel Spolsky says, “Users don’t read the manual.” It turns out, I am a user … and I didn’t read the manual. And I am feeling very dumb about it right about now. Let me explain why and go into a little more detail about the guts of the situation.
As I was working on the Hibachi codebase, I tried to generate a typed array from a Java collection. The Sun developers thought ahead and created a method that would help me to this, Collection.toArray(T[]). So I wrote the following code:
I then decided to test it (looking back, this is where it all started to fall apart – testing!). I got a NullPointerException but couldn’t figure out why. It turns out, the documentation for that method specifically mentions it. Unfortunately, I only got part way into the documentation before I gave up reading and assumed the best.
Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection.
So I thought that it would automatically allocate an array of the correct size. It turns out, the documentation explicitly says that if I do that I will get a NullPointerException:
Throws:
<a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/NullPointerException.html" title="class in java.lang">NullPointerException</a> – if the specified array is null.
So if I would have read the documentation fully, I would have seen that. So my fix was obvious, pass it an empty array instead:
This solved the NullPointerException and actually worked as advertised. I wish it worked in the original way but there is good reason that it can’t. The reason is caused by how the Java compiler works. Here is an example snippet of code:
import java.util.*;
public class Main {
public static void main(String[] args) {
Main[] mains = null;
List mainList = new ArrayList();
mains = mainList.toArray(mains);
}
}
When I compile it and look at the bytecodes I see:
public class Main extends java.lang.Object{
public Main();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object.”“:()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: new #2; //class java/util/ArrayList
5: dup
6: invokespecial #3; //Method java/util/ArrayList.”“:()V
9: astore_2
10: aload_2
11: aload_1
12: invokeinterface #4, 2; //InterfaceMethod java/util/List.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
17: checkcast #5; //class "[LMain;"
20: astore_1
21: return
}
As you can see, the typing information is completely gone for the parameter that is passed into toArray. But if you write the following code instead:
import java.util.*;
public class Main {
public static void main(String[] args) {
Main[] mains = new Main0;
List mainList = new ArrayList();
mains = mainList.toArray(mains);
}
}
you get the following bytecode which does include the typing information:
public class Main extends java.lang.Object{
public Main();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object.”“:()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: anewarray #2; //class Main
4: astore_1
5: new #3; //class java/util/ArrayList
8: dup
9: invokespecial #4; //Method java/util/ArrayList.”“:()V
12: astore_2
13: aload_2
14: aload_1
15: invokeinterface #5, 2; //InterfaceMethod java/util/List.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
20: checkcast #6; //class “[LMain;”
23: astore_1
24: return
}
So you can see that the only way that the method can work is if it is given a non-null object so that the compiler will include the typing information.
In summary, I am an idiot, the Java compiler is smart, and I wish it would protect me from myself sometimes.
With two minorchanges to the Hibachi codebase under my belt, I needed to start working on tasks that advance the goals of the SAnToS lab (my employer). The first task on that list is to extend the outline view so that we can display SPARK annotation information. The SPARK annotation information will eventually come from a custom parser being developed by Jon Hoag.
Here is a quick example of what SPARK annotations look like.
procedure Add(X : in Integer);
--# global in out Total;
--# post Total = Total~ + X;
The first line is the Ada declaration for a procedure named Add that takes 1 parameter (of type Integer with a mode of in and named X). The second line, which is an Ada comment and a SPARK annotation, states that a global variable named Total is changed in the body of the procedure. The third line provides a post-condition describing the value of Total after the procedure is executed. This information will eventually be shown in the outline view to make it easier for SPARK developers to navigate and understand the code.
This first task required a lot of investigation into the Hibachi codebase. I first had to understand the current extension points for the Hibachi UI plugin. I was hoping to find an extension point already created that would allow external outline views to be used. Finding that there wasn’t one, I had to devise a plan of attack. I would first create a list of possible solutions and then dig into each one until I had a favorite. I ended up with 3 possible solutions (2 of which were feasible).
The first option was to simply make changes to the current outline view to support the SPARK annotations and hope it would get merged into the mainline. This seemed like a bad idea for several reasons (our goals are not directly inline with the goals of the Hibachi project, SPARK annotations won’t always be available so the code would get messy, etc.). This option was abandoned very quickly.
The second option was to refactor the current Hibachi UI plugin to provide extension points for the content and label providers that are used in the outline view. I considered this but decided this might lead to a more fragile extension point so I opted to not pursue this option at this time. But there is no reason not to revisit this option in the future since it might make more sense in the long-run.
The third option was to refactor the current Hibachi UI plugin to provide an extension point that would allow others to provide their own outline views. This would require the Hibachi developers accept our changes into the mainline but would mean that we could keep our SPARK specific implementation out of their way (in other words, in our own plugin). This is the option that I pursued.
With that decision made, I started hacking away at the code trying to find the best way to design and implement the extension point. I tried to follow the example provided in the PrettyPrinter extension point but had to make some small changes. I chose to create a single extension point, refactor the existing outline view to use that new extension point, and then create a Manager pattern to keep track of the extensions and instantiate outline views. I also had to design a user interface that allowed the user to select the outline page implementation they wanted to use for each project (in the long-term this mechanism will likely change to allow a global setting of this).
The extension point that I created for the outline view is as simple as I could make it. It simply takes 3 values: 1) an ID, 2) a name, and 3) a class name (this follows the pattern used in the PrettyPrinter extension point). Below is an example of how to use it (taken from our SPARK plugin):
Note: Using the Eclipse Plugin/Manifest Editor makes declaring this extension much easier.
It should also be noted that the name provided will be used in the listing of outline pages available in the Property Page for the selection of Outline Page (as described below).
After my refactoring, I was able to test that the existing outline page still functions as expected. This wasn’t as easy as it sounds. It took me several days to get it right because of serious over-sight in how I implemented part of it – oops!
I then created the property page UI to allow the user to select their desired outline view. A screenshot of this is shown here.
Once that was all in place I created the start of our SPARK outline view. And with just a little elbow grease, I was able to get a very simple (no images) view done in a matter of hours. Most of that time was spent understanding the Ada model that Hibachi uses (which is very good based upon my limited experience with it).
The next step is to finish the basics for the SPARK outline view (handling all parts of the model, handling the navigation, and making it pretty with custom icons). This will likely take some real time to get right.
Anyway, here is the patch. I have spent some time testing but I am sure there are things that I missed. And their might be more refactoring necessary to bring it inline with Hibachi standards and style. I hope that the Hibachi developers will merge the patch, test it, and commit to using it in the mainline.
I have been working with Hibachi for a couple of weeks now and so far I am impressed with it. Well written code, especially for an open source project, and well documented (at least in comparison to what I have been reading for the last couple of years).
One issue that I came across while using it was that the outline view doesn’t show the parameters as sub-children in the tree. Let me see if I can convince you that making them sub-children isn’t just preference.
I assume the reason the Hibachi developers chose to do it this way is because it mirrors what the Eclipse JDT (Java Development Tools) does. Specifically, for each method in a class, there are no sub-trees. It simply lists the parameter types after the name. For example, given the following Java code:
public void myMethod(String s, Integer i) {
....
}
the outline view would look like the following screenshot:
So it seems reasonable that Hibachi (aka, ADT - Ada Development Tools) would do the same. But I think the Ada language is different enough from Java that it makes sense to re-evaluate this decision. I think that since Ada parameters have a mode (in, out, or in out) that it would be an improvement for users if each parameter were its own sub-tree node in the outline view. Then the icon used in the tree can denote the differences in mode.
So my suggestion is that we modify the model to return the parameters as children. With this change, the outline view shows each parameter as a sub-tree node. This makes it possible to change the LabelProvider (specifically the AdaOutlineLabelProvider) to add decorators for the mode.
Anyway, here is the patch that I created. I hope it is merged into the mainline.
The last couple of weeks have brought me back to coding – which is very exciting for me. My task is to extend the Hibachi project’s Ada development environment to work for SPARK and with our analysis tools.
My first order of business was to patch a bug that I came across. Very simple patch (just checking for nullness before making a call on that given object). I am hoping that the project developers will accept it into the mainline. I further hope that this will help the Hibachi developers trust me more so that I can eventually just submit fixes directly to the repository.
The stack trace I was getting (just the first couple of lines – light editing):
java.lang.NullPointerException
at ...hibachi.core.AdaProjectManager.getProjectData(AdaProjectManager.java:489)
at ...hibachi.core.AdaProjectManager.getProjectConfigurations(AdaProjectManager.java:1471)
Anyway, here is the diff. It can be applied using the built-in Eclipse patch mechanism on the org.eclipse.hibachi.core plugin/project.
As mentioned before, I have been re-tasked to work on a plugin for Eclipse that supports the development of SPARK. Therefore, I should probably learn something about the language.
I started off by trying to read through slides prepared by Dr. Hatcliff and Dr. Robby. The slides made sense but I wasn’t able to fully comprehend the language based solely on the slides.
I then found a simple Ada tutorial that walked me through the basics of Ada in a step-by-step manner. This allowed me to understand little bits of Ada through simple examples. And I was able to compile and run them to validate my understanding.
Coming back to the slides made a lot more sense. And re-reading the book chapters really made more sense. I think I am finally understanding Ada and SPARK. And I feel more confident that I can help development an IDE in Eclipse to support the development. Now I just need to understand the technologies provided by the Sireum project that I will have to interface with before starting the IDE implementation process.
“had only one tenth of the residual anomalies as comparable full Ada and only one hundredth of those found in parts of the system written in C.” from A Technical Overview of SPARK. I wonder how they define “residual anomalies” and how they measured them.
“SPARK does not have its own compiler suite. Rather, it leverages the use of existing Ada compilers.” from Barnes Chapter 1 — Introduction.
.ads files contain the specification (or declaration) of a package while .adb files contain the body (or implementation). From Barnes Chapter 2 — SPARK Language Principles.
“To make long numbers easier to read, underscores are permitted inside a numeric literal. For example, “1_000_000″ is legal.” from Section 3.3 – Numeric Literals of the Ada95 Lovelace Tutorial.
“Ada programs usually use a starting index of 1 if there’s no particularly natural starting point; this reduces the probability of so-called “one-off” errors (people normally count from one, not zero, and can sometimes get confused when starting from zero).” from Section 6.5 – Arrays of the Ada95 Lovelace Tutorial.