Friday, February 11, 2011

Disk Utility: Failed to create disk image (resource busy)

Been a long time since I have blogged. A quick post about what I just found out. Hope it helps someone else out there.

I was trying to setup the Android dev environment on my Mac and had to create a case-sensitive disk image using "Disk Utility". Every time I tried to create the disk it would end up with a "resource busy" message.

Simple solution:
Disk Utility -> Preferences
Uncheck the "Automatically mount read/write images"

Now, recreate image and things should go through smoothly.

p.s.: I am running on Snow Leopard

Sunday, February 15, 2009

A Case Study: Modularized Application Development with Struts2

In today's development world, it is not uncommon for mid-to-large scaled projects to have multiple sub-modules which are then assembled for the final product deliverable.

One of the common challenges involved with such development is pretty much the integration piece. Integration can be defined in a multitude of ways and as such there is no "one size fits all" solution. Let's scope our scenario down further. Let's say that our finished product is a web application which is composed of multiple sub-modules, where each module represents a service and this service can have an optional view layer that needs to be pulled into the finished product with all the linkages being proper. Personally I do not have a lot of work experience, but I have been faced with the same problem in two different companies, to make me believe that this could be a common scenario for quite a few other folks out there.

In my previous project, I had a similar situation. At that time I was the architect, build-boy, source control administrator, module lead, business-analyst, client connect.... basically one-guy-fits-all-positions!! And to make things worse, the technology stack for the project was already defined and the view layer would be completely written in Struts2. No offense to Struts2 what-so-ever, just that I was a Faces boy (not knowing anything about Struts except for the concepts) and here I was ... working in alien technologies :)

Coming back to the subject, each of the sub-modules were publishing pages that needed to be integrated in the final application and linked via the menus too. During the earlier builds, the integration process was a nightmare, where we would pull in all the code, merge all the struts.xml files, update links on the menu-sections of the page - in one phrase - inefficiency at its best :)

Just about when I was about to give up on the hopelessness of the situation, I decided to have a closer look at what Struts2 had to offer and I was pleasantly surprised that I could have the flexibility of distributed configurations (the type that I was used to with Faces) right within Struts! The key was the struts-plugin.xml file!!

So the first thing I had to do was rewire our current modules a little bit. Let's take the following sample layout for a module:



Let's assume that each module has a DAO layer, a model / API layer, and a web layer. First thing that I had to do was ensure that my web-tier projects are creating jars instead of bundling the compiled code in the classes directory. Next, I moved over the struts.xml for the module to src/java/struts-plugin.xml. This would mean that my-module-view.jar would contain the struts-plugin.xml in its root directory. And anyone who has written plugins in Struts2 would know that the all struts-plugins.xml files available on the classpath are loaded up when the struts application starts.

Neat. So I have one problem taken care of, which was the manual merging of the struts XML files. But I've still got one more problem to fix. The whole manual setup of the menu layouts in the application. Now why did we have to do this? 'Cause there was a need to make releases which had only a certain subset of modules available.

This is where I got thinking ... each of my menu items opens up in to a page / view of the underlying module. And each of this menu items is pointing to an Action link ... so would it be possible to read all actions, and add a custom attribute to the action definition in the Struts xml file ... and then use this information to construct my menu??? Sounds logical, and yes ... it is absolutely doable!!

All menu related actions were augmented with additional attributes in the struts xml file. So, now my struts XML files started to look as follows:



<struts>
<package name = "/mymodule/manage/">
<action name = "ModuleSettings" ... >
<result ...>...</result>
<param name="menu.id">My_Module_Settings</param>
<param name="menu.parent">ROOT_MENU</param>
<param name="menu.order">3</param>
<param name="menu.display.name">My Module Settings</param>
</action>
....
</package>
</struts>

Once I had all the required parameters, it was now about reading these action files and setting up the menu model in memory. This can be easily achieved using the following lines of code:



function loadMenuItems() {
Configuration configuration = Dispatcher.getInstance().getConfigurationManager().
getConfiguration();
Set<String> packageNames = configuration.getPackageConfigNames();
for (String pName : packageNames) {
parsePackages(config.getPackageConfig(pName));
}
}

function parsePackages(PackageConfig packageConfig) {
Map<String, ActionConfig> actionConfigs =
packageConfig.getActionConfigs();
String namespace = packageConfig.getNamespace();
for (String aName : actionConfigs.keySet()) {
parseActionConfigs(namespace, aName, actionConfigs.get(aName));
}
}

function parseActionConfigs(String namespace, String aName,
ActionConfig actionConfig) {
// Check if the action config represents a menu element.
Map<String, Object> params = actionConfig.getParams();
if (params.containsKey(MENU_ID)) {
// MenuAction found.
String menuId = (String) params.get(MENU_ID);
String parentId = (String) params.get(MENU_PARENT_ID);
String displayName = (String) params.get(DISPLAY_NAME);
String menuOrder = (String) params.get(MENU_ORDER);

// Now go ahead and create the menu item from the above information
// and setup the menu context.

}
}


Once I had the menu context initialized, then all I had to do was just rewrite the menu handling pages to use the menu context and publish information. The rest of the work of merging the wars into a single project was left to the build system =)

Note: The above parameters are just an illustration and if you choose to leverage a similar approach, then you could potentially introduce other parameters, like security related information (ROLES / PERMISSIONS / etc).

And obviously, due IP constraints, I will not be able to publish any of the code base, but here is something interesting... Among all the folks that I have interviewed in the past, almost all of them have no idea what Swing is all about and believe that Swing is purely for desktop. Yes, predominantly it is for the desktop, but hey... there is a javax.swing.tree package and this package incidentally has a fullfledged Tree implementation!! What if I created a MenuItem that extended from DefaultMutableTreeNode ?? Don't you think that the whole effort of ordering and traversal could be completely ignored?? ;-)

So this was the way I went about resolving a rather nagging problem in my development project. Do you have any interesting experiences / ideas that help solve similar situations??

-Rogue

Tuesday, July 24, 2007

The Problem of Many

The open source world of "Applications" is a funny & paradoxical collection of illustrations. On one hand, people unite together to get away from the clutches of those who tend to constrict users, whilst on the other petty differences in opinions leads to the creation and availability of a multitude of applications performing the same task, albeit in slightly differing shades. Some folks look at this as "the freedom to choose". I look at it as the lack of a concerting effort to amalgamate the best of features, in turn, producing the best-of-breed applications.

Now, this does not mean that I am against the open-source concept or the proliferation of applications. I am just trying to explain a problem that I have noticed -- "The Problem of Many"

I have Fedora 7 installed my laptop, and like most users I have installed various media related applications that are not installed/shipped by Fedora - like MPlayer, Xine, Helix, Real Player. Similarly on the audio front I have Amarok[1], XMMS. Now these are in addition to the default set of applications - Totem, GNOME-CD, Rhythm Box, Sound Juicer, etc.

Each application has its pros and cons and I definitely do not wish to get into a competitive analysis of each of these. What I would like to highlight is the cluttering of my menus. Currently my "Sound & Video" menu contains a plethora of applications (which of course I had installed) which pretty much do the same job[2]. See the following image inset for details.


Now I have been thinking, what if we could collapse all the similar applications into one extended-menu-item ?

What I really mean by that is, what if my "Sound & Video" menu opened into top level extended-menu-items. These extended-menu-items could be used to execute the user-configured actions or could also be used to further drill down into options. The following images should highlight better what I have in mind.











When I say user-configured I am talking more on the lines of configuring your favorite application via one central UI -- like the current "Preferred Applications" UI in the GNOME install.

I guess my idea does not really solve the problem-of-many; it merely hides it, but I do believe that a solution such as the above could bring about an ease of application manageability within the desktop and of course I would happy with it :)

What do you think about it?


[1] - Amarok though shipped with the install media is not installed by default on a GNOME desktop
[2] - I am aware that most of the applications that I mentioned primarily target a specific media type, but my point is that this difference would soon be blurred out in the near future as each application tries to improve its support for the other media types.

Saturday, May 12, 2007

Running Sun Secure Global Desktop (a.k.a. Tarantella) on your Fedora Core desktop

I have spent hours trying to understand why the Tarantella client does not work on my GNOME install. Every time I run the ttwebtop command, I would see a whole lot of warnings on the console and the end result was that I would not be able to type in anything in the login dialog.

After a lot of Googling and reading bugs, I chanced upon the possibility of a mismatch in the location of the XKeysymDB file. This file is available as part of libX11 which is present on the system by default. The client tries to load up this file from the location /usr/openwin/lib/XKeysymDB, but the file is actually present at /usr/share/X11/XKeysymDB. In order for the application to pick it up, you need to define this new location as an environment variable - XKEYSYMDB. Once you set this variable, the client loads up fine, and I can start working from home again :-)

As a solution, I have this variable defined in my ~/.bashrc file as follows

export XKEYSYMDB=/usr/share/X11/XKeysymDB

And I can start working from home again :-)

Note: The client in consideration is the Sun Secure Global Desktop version 4.2

Monday, January 29, 2007

Necessity is the mother of all inventions

Who ever said it, couldn't have been more right. I find myself building utilities and applications everytime I don't find the right one :) .. During the past few days, I built a similar utility plugin and I thought I might as well share it with the rest of the world.

A little background... I work on a myriad set of applications and technologies, and this requires me to keep doing a lot of activities on different applications parallely. So off-late I have been working on providing a JSF component that pulls in a user's presence information from a backend RTC server. In this case the backend happens to be Microsoft's Live Communication Server. As you might have guessed, I have a .NET component that is doing all the talking with the LCS instance and this component exposes its features as a set of WebServices which are then consumed by the Java layer and published to the application via a JSF component. No points for anyone guessing that this can be a mess to handle all alone :-p

Everytime I need to perform some quick and dirty work, Netbeans is the IDE of choice. One day I was trying out something on similar lines, I needed to import only a subset of the Java classes into a project. And I knew that the IDE did not present me a feature where I could pick and choose. The only option I had was to copy the files over manually outside the IDE and then delete those that I didn't require. That can be quite painful at times! I dearly wished I had an option where I could look at the files being imported in a tree structure, where I could just (un)select the files I wanted.... So I built myself one of those things :-D ... Here is a screenshot of the module in action..


As a part of my work, I ran into a hard-to-trace, intermittent bug that would cause the .NET layer to crash once in a while. One rather good thing that I did do was use Log4Net's logger within the entire .NET code. So I whipped out my IDE of choice, built the test-bed and began the debugging. Everything was fine and going smooth, except that I had to switch between two applications to keep monitoring the output. That is when I though... "How I wish I had a module that could tail this file and show me the data within the IDE itself!". I took a measure of the expected effort, realized it wasn't much, went ahead and built myself exactly what I wanted. Check it out in action....


Like what you see? Get it here.

Thats all for now, later!

Saturday, January 20, 2007

Java6: GroupLayout and a small gotcha


The new layout manager, GroupLayout, which is part of the JavaSE 6 bundle is great and coupled with Netbeans' Matisse component, makes a killer combination. Today I would like to talk about an issue that I ran into and hopefully would be able to help others running into the same issue.

Anyways, if you try hand-coding this layout for your components, there is a rather subtle thing to remember. In Java 5, if you wanted to add a component to a container like JPanel, you would do something like:

....
JPanel jp = new JPanel();
JButton button = new JButton(...);
jp.getContentPane().add(button);
....


The key point to notice is that you would explicitly get hold of the content pane and then add the component to it. Now with Java 6, the good old ways of adding a component directly to the parent are back (which internally ensures that the component is added to the content pane), i.e., the same example above could be simplified as:

jp.add(button);

All this fine and nice. Now when using GroupLayout, the code might look as follows (in Java 5):

GroupLayout layout = new GroupLayout(jp.getContentPane());
jp.getContentPane().setLayout(layout);
... // add the component to the layout

Since I was working with Java 6, I decided to use the simplified notation and did the following:

GroupLayout layout = new GroupLayout(jp);
jp..setLayout(layout);
... // add the component to the layout

And was I in for a shock when I ran the code !!! I kept seeing the following stack trace on my screen :-O

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException:
GroupLayout can only be used with one Container at a time
at javax.swing.GroupLayout.checkParent(GroupLayout.java:1095)
at javax.swing.GroupLayout.invalidateLayout(GroupLayout.java:987)
......

It took me a while (which involved going through the source-code of GroupLayout) to figure out that the problem was actually with the way I am initializing the damn GroupLayout instance! The layout instance considers that it is being applied to the container ( JPanel in our case) whereas, the setLayout() method delegates the call to the content pane. And GroupLayout does a check to see that the host and owner are the same, if not, it throws a rather undecipherable exception like the one above. The key to getting it run was just simply to pass the content pane to the constructor of the GroupLayout instance.

GroupLayout layout = new GroupLayout(jp.getContentPane());
jp..setLayout(layout);
... // add the component to the layout

This experiment sure was good learning, but it would have been great if the implementation of GroupLayout threw a more meaningful exception stating the obvious rather than leaving us to figure out the obscure bits!

Thats all for now.

Google Pages

Since I am adding an article on to this blog after a really long time, I just thought I would mention about my small space on the Google Pages site. I should say that I am seriously impressed with the simplicity of the application.

Anyways have a look at it cos that is where I am pushing all my spare-time projects.

Thursday, April 06, 2006

Getting your ZeroG installer to work on your latest and greatest Linux distro

Certain versions of the ZeroG installers have a serious issue when installing software on the Linux desktops. You start seeing a variety of errors like

"/bin/ls: error while loading shared libraries: librt.so.1: cannot open shared object file: No such file or directory"

... and many others, while you can very clearly see that the library files are present on the file system.

I face the same issue while installing Oracle Calendar desktop client on my FC 5 Linux distro. When i started googling for the errors encountered, i started to see a lot of rather half-answered posts which did not work for me. Sufficient enough to piss me off, i started debugging the installer by setting the debug param to true.

>LAX_DEBUG=1 sh cal_linux

This gave me some leads and i finally figured that there was some kind of work around being applied because the installer kept thinking that the JVM being used had a version less than 1.4, which was inturn caused by the fact that the installer was setting the LD_ASSUME_KERNEL variable to 2.2.5 ...

The version information was pulled of from a set of variables called v_major, v_minor, etc.. Fix these values and you are good to go :)

>v_minor=4 sh cal_linux

voila!! the installation goes through smoothly :)

If you would like to further customize the installation by specifying the JDK to be used, then you could achieve the same by the following command:

>v_minor=5 sh cal_linux LAX_VM /usr/java/jdk1.5.0_06/bin/java

Hope that helps you folks out there.