As an ArgoUML contributor I'm going to blog my activities here, so that they may draw interest by other developers or help other developers when doing tasks similar to what I've done. AND(!) the grand vision that makes an Argonaut what he is, TO THRIVE IN THE BIG DANGEROUS WORLD, TAKING THE Argo TO A GOOD SHORE ;-))

Saturday, June 28, 2008

ArgoUML 0.26 enters alpha

Recently ArgoUML 0.26.alpha1 was released. This is another step forward to a much anticipated ArgoUML 0.26. It contains some new things and one of these is the profile subsystem, to which I made a modest contribution.

I'm now working in priority 2 issues of the profile subsystem, which block the stable release. I'm also working in documenting this subsystem, first in the cookbook and then I'll do updates to the user manual. I hope I can still give a bit of of attention to the C++ module...

So, here is a list of things I would like to try to fix before 0.26:

  1. issue #4994: Editing loaded profile should be prevented

    ExplorerPopup.isRelatedToProfiles(Project, Object) is used to detect if a element is related to the profiles configured in the current project. In the same package is the support for drag-n-drop, class DnDExplorerTree, which method isValidDrag(TreePath destinationPath, Transferable tf) contains the validation of valid and invalid drags. We may make impossible for profile model elements to be dragged by checking if the Transferable contents contain profile model elements. On the other hand, this would make it impossible to add a profile contained model element to a diagram and this would limit the usefulness of the profiles. FigNodeModelElement is the base class of many of the model element figures in the diagrams. Here the are two things needed: disable the menus that can modify the model element and disable the editability of the model element in-place. Such as the editing of names.

  2. issue #5017: profile model elements are absent from diagrams on reload
  3. issue #4991: Profiles subsystem missing in the cookbook
  4. issue #4992 – this is the one related to the update of the user manual for inclusion of the profile related functionality
  5. issue #3771: Add tag definitions for tags used by the cpp generator – for this it is only needed to update the user manual to reflect the usage of the UML profile for C++ instead of the previous way of copying into the model the model elements of the included profile.
  6. issue #27 of argouml-cpp: anarres-cpp: dependencies caused ArgoUML loading failure – I thought I had fixed this, but, in 0.26.alpha1 there is still the following warning:
     2008-06-27 19:17:48,526 ERROR: Unable to find required class while
          loading org.anarres.cpp.Main$Option - may indicate an obsolete
          extension module or an unresolved dependency (ModuleLoader2.java:719) 
    java.lang.NoClassDefFoundError: gnu/getopt/LongOpt at 
    java.lang.ClassLoader.defineClass1(Native Method) at 
    java.lang.ClassLoader.defineClass(Unknown Source) at 
    java.security.SecureClassLoader.defineClass(Unknown Source) at 
    java.net.URLClassLoader.defineClass(Unknown Source) at 
    java.net.URLClassLoader.access$000(Unknown Source) at 
    java.net.URLClassLoader$1.run(Unknown Source) at 
    java.security.AccessController.doPrivileged(Native Method) at 
    java.net.URLClassLoader.findClass(Unknown Source) at 
    java.lang.ClassLoader.loadClass(Unknown Source) at 
    sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at 
    java.lang.ClassLoader.loadClass(Unknown Source) at 
    java.lang.ClassLoader.loadClass(Unknown Source) at 
    org.argouml.moduleloader.ModuleLoader2.addClass(ModuleLoader2.java:714) at 
    org.argouml.moduleloader.ModuleLoader2.processEntry(ModuleLoader2.java:680) at 
    org.argouml.moduleloader.ModuleLoader2.processJarFile(ModuleLoader2.java:614) at 
    org.argouml.moduleloader.ModuleLoader2.huntModulesFromNamedDirectory(ModuleLoader2.java:554) at 
    org.argouml.moduleloader.ModuleLoader2.huntForModulesFromExtensionDir(ModuleLoader2.java:512) at 
    org.argouml.moduleloader.ModuleLoader2.huntForModules(ModuleLoader2.java:435) at 
    org.argouml.moduleloader.ModuleLoader2.doInternal(ModuleLoader2.java:311) at 
    org.argouml.moduleloader.ModuleLoader2.doLoad(ModuleLoader2.java:164) at 
    org.argouml.moduleloader.InitModuleLoader.init(InitModuleLoader.java:55) at 
    org.argouml.application.SubsystemUtility.initSubsystem(SubsystemUtility.java:49) at
    org.argouml.application.Main.initializeSubsystems(Main.java:430) at 
    org.argouml.application.Main.main(Main.java:169) Caused by: 
    java.lang.ClassNotFoundException: gnu.getopt.LongOpt at 
    java.net.URLClassLoader$1.run(Unknown Source) at 
    java.security.AccessController.doPrivileged(Native Method) at 
    java.net.URLClassLoader.findClass(Unknown Source) at 
    java.lang.ClassLoader.loadClass(Unknown Source) at 
    sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at 
    java.lang.ClassLoader.loadClass(Unknown Source) at 
    java.lang.ClassLoader.loadClassInternal(Unknown Source) ... 24 more 2008-06-27 
    19:17:48,546 ERROR: Failed to find any loadable ArgoUML modules in      jar 
    X:\ArgoUML\0.26.ALPHA_1\ext\anarres-cpp-no-dependencies-1.2.3.jar     (ModuleLoader2.java:627)
  7. There is a problem in JCPP from anarres that it doesn't close the files when the contained CppReader is told to close itself. This is causing 5 tests in argouml-cpp to fail with an error, when the tearDown() is trying to delete the files.
  8. There are some more argouml-cpp issues I would like to solve, but, this is a fair cry...

Google Summer of Code 2008

I'm a Google Summer of Code 2008 mentor for ArgoUML. It is fun and, as stated over and over, one learns a lot by teaching and in my case mentoring.

The student I'm mentoring is Bogdan Szanto and he is working in fixing diagram usability issues. This includes fixing some existing problems and adding new features, that hopefully will make ArgoUML users happier.

Bogdan already helped fix some problems found in the new sequence diagrams implementation – argouml-core-diagrams-sequence2. I was a bit late in this game, because he started working in this during the community bonding period and we both wanted him to “bond” with other developers than me. But, now it is long finished and I started supporting his work directly by reviewing patches and testing code and learning about the specifics of the implementation. So, while I was debugging I found the following issues that must go into the DB:

  • Summary: Broom causes ClassCastException when used in a seq2 diagram that contains a Note “connected” to a ClassifierRole

    ModeBroomMessages thinks that all edges in the diagram are messages, but, there can be connections between Notes and ClassifierRoles. The following exception happens when the Broom is used in a seq2 diagram that contains a Note “connected” to a classifier role:

     java.lang.ClassCastException: org.argouml.uml.diagram.static_structure.ui.FigEdgeNote
     at org.argouml.uml.diagram.sequence2.ui.ModeBroomMessages.getAllFigMessages(ModeBroomMessages.java:198)
     at org.argouml.uml.diagram.sequence2.ui.ModeBroomMessages.getAllFigMessagesDownward(ModeBroomMessages.java:177)
  • Summary: destroy action cleans the lifeline of the caller

    When a destroy action is created between two classifier roles, the lifeline of the caller becomes fully dashed. I think that the opposite shouldn't also occur, but, that the lifeline of the callee either should become dashed from the point where the message arrives onward or that it should finish there (preferable).

    See the attached figure “destroy-action-clears-lifeline-of-caller.png”.

  • Summary: selected create Action + “Alt” key cause repositioning of created CR

    When you draw a create Action between two classifier roles, leaving it selected, and, afterwards press the “Alt” key, the created CR is repositioned in the top position. If the create Action isn't selected this problem doesn't occur.

Saturday, April 05, 2008

Resolving and persisting profile references

In the context of issue 4946 (Loading project which references non-default profile doesn't work) I needed to make some design changes to the profile sub-system and to the MDR implementation of the model sub-system of ArgoUML. At first I used what I now see as a brute force approach, banging the existing code to try to make the problem go away. I'm glad it didn't worked and I started thinking and designing my way out of this priority 1 bug.

Basically the problem aroused when we tried to finish the profile sub-system to have a developer release of ArgoUML, the release 0.25.5. Originally the UML profile for C++ was contained in the ArgoUML core. There were two types of profiles:

  • ArgoUML core profiles – these are XMI files contained in ArgoUML, being physically part of the argouml.jar.
  • User defined profiles – these are XMI files saved by the user, which he intends to use as his own profiles, normally for reusing in several models.

It was agreed that part of the work would be to enable the language modules to contain the corresponding profiles, and as such I tried to put the C++ profile in the ArgoUML C++ module. So, ArgoUML would now have three types of profiles:

  • code profiles;
  • module profiles;
  • user defined profiles.

Now I need to explain the idea of resolving references when loading XMI files...

A XMI file is a XML file. Being so, it is possible to make a reference from one XMI file to another and this is how in the future ArgoUML you can have a model and several profiles referenced from this model. But, the references take the form of URL#ID, being the URL the reference to a different XMI file where there must exist a definition of a model element with the identifier ID.

To enable offline work in the case of core and module profiles and flexible user defined profile directories locations in the case of user defined profiles, you need to add a midle man resolving these beautiful URLs to system paths - enter the XmiReferenceResolverImpl.

The XmiReferenceResolverImpl was based on the AndroMDA code that did the same thing. It has some complex code that is able to resolve a reference from the net, local disk or even in the classpath. But, the resolving of a reference to a profile was hard coded, being the base URL and the base system path constants of XmiReferenceResolverImpl.

So, when the C++ profile was moved, the reference resolving didn't worked any longer for it since its system reference was now different. It broke the initial solution of having the reference resolving somehow hard coded in the MDR model implementation.

I tried very much to make it work again, doing some more hard coding in the profile loading side and in the MDR implementation side:

  1. [2008-01-28 to 2008-02-05] Hack, hack, debug, debug, and I made the C++ profile module work :-)
  2. [2008-02-26 to 2008-03-04] Hack, hack, debug, debug, hack, hack and the user profiles work too :-))
  3. [2008-03-??] But wait, my automated test for the C++ profile persistency is now failing :-(
  4. [2008-03-?? to 2008-03-23] Debug, debuug, hack, haaack...
  5. [2008-03-24] Stop! Think a bit, and think a bit more and... This design for resolving references is broken.

So, I went back to the drawing board and started thinking a bit on what is required to enable the reference resolving that we needed. There were some lessons learned:

  1. the XmiReferenceResolverImpl must not have hard coded base URLs and base system paths to resolve the profiles references;
  2. when the XMI for a profile is read, the XmiReferenceResolverImpl must replace the given system reference with a public reference which is handed to it;
  3. the best place to know about what are the system and public references for a given XMI is the place where the call to load the XMI is done.

Enter the ProfileReference, although, as Marcos Aurélio commented, it would better to be called ModelReference.

ProfileReference class diagram.

Picture 7ProfileReference class diagram.

As seen, to enable DRY, I added the CoreProfileReference and the UserProfileReference, but, the language modules will in principle use directly the ProfileReference, or define their own XxxProfileReference. The ProfileModelLoader.loadModel(String path) method is deprecated and the ProfileModelLoader.loadModel(ProfileReference reference) replaces it.

But, now, how do I get all these neat references into the realm of XmiReferenceResolverImpl? Well, some more design and I hope the ArgoUML powered sequence diagram of the interesting part of loading a profile XMI explains it.

Profile loading sequence diagram.

Picture 7 – profile loading sequence diagram.

As with many sequence diagrams, I only kept the important steps, but, one significant is that there is a map of public to system references involved, which is kept at the MDRModelImplementation level. And this is important, since the XmiReferenceResolverImpl and its creator, the XmiReaderImpl are short lived - they are only kept around while the XMI is being loaded.

So, when I find myself working very hard at the debugger and hacking cycle I will try to stop and think. I recall already having stated this to myself some time ago, but, sometimes I forget this kind of things for which there is nothing like a bump with the head (or several as in this case) for one to remember the basics again ;-)

Saturday, March 08, 2008

ArgoUML's repository restructuring

ArgoUML core is undertaking a repository restructuring and I'm working in adapting the argouml-cpp build to the new structure.Issue 4625 is where the requirements for the changes are documented and there has been some dev mailing list activity on this. Linus Tolke is heading the effort.

We want to keep two build mechanisms:

  • Plain Ant build via command line and without eclipse.
  • eclipse based build, being the idea for this to make easier for new contributors to start.

I have been adapting the Ant build file to the new structure, but, I had some problems with making it work for both purposes. The big issue is to generate the source files from the ANTLR grammar. In the end we figured out a good way to do it and it is now documented in the ArgoUML cookbook.

Distributed version control systems

Recently I had to use Mercurial to checkout the NetBeans sources. Well, since the instructions were for the whole NetBeans repository, I followed them and I have a local checkout of it. Now NetBeans is big, so, you could think it would take me some hours to get the whole thing, even more, if you consider that it clones the whole repository with the full history. No, it was surprisingly fast and its command line interface is very easy to use.

Alas, I have currently no project where this or other distributed SCMs are used, but, when I get a break from ArgoUML and start experimenting with open source projects from common-lisp.net I'll have a good change that they'll be darcs based.

Debugging model-mdr

In the past 2 months I have been in and out working with other persons to fix the problems in the ArgoUML's subsystem model-mdr (see issue #4946). This is a core part of the ArgoUML implementation and it basically wraps NetBeans MDR into an implementation of the ArgoUML model subsystem.

MDR is based in JMI (a standard from the Java Community Process), which is itself based in MOF (a standard from OMG). I was more or less familiar with the ideas behind MOF, but, as always, the devil is in the details and I'm now reading the standard so that I'm not bumping so much on problems.

My lack of knowledge about MOF was made worse by the sources of the several jars from MDR not being included in the ArgoUML repository. Also, unusual for open source projects MDR doesn't make it available as a download - you must checkout the sources with Mercurial (more on this latter) or CVS. Even so, it doesn't contain the sources for jmi.jar and mof.jar. The MOF and JMI standards don't have a zipped javadoc to help when you bump into unexpected problems in the debugger. All this is making the whole exercise harder than needed!

TODO: get my hands on the jmi.jar and mof.jar sources!

Reader Shared items

Followers