Knowledge brings fear ... Prosthetic Conscious

Friday Jun 06, 2008

Virtual Box is amazing for an open source project. It comes close to VMWare in usability. Where it falls short is importing and exporting images. There's no support in the user interface for this. If you feel comfortable using the command line, you can export and import a disk image. Here's how,

To export:

  1. Shut down the VM
  2. Use the "VBoxManager clonevdi ..." CLI to copy the disk image. On my Mac this was at /usr/bin/vboxmanage

To import:

  1. Register the disk image: File>Virtual Disk Manager>Add
  2. Create a new VM, and use the disk image you added in step 1

The obvious problem is that the .vdi file is just a disk image. It doesn't capture the virtual machine. You must know the correct parameters to use when you create the VM in the import process or the disk image won't be able to run. It also doesn't capture the state of the virtual machine. 

Vbox has a very nice snapshot feature. If one could import / export snapshots it would be perfect.

Wednesday May 07, 2008

Portlets can be syndicated to existing websites to augment their dynamic content. Check out the WebSynergy project for a a demo of this.[Read More]

Thursday Jul 12, 2007

In an interview with businessofsoftware.org, Tim Lister defined three software project anti-patterns that are interesting if for no other reason than that they have colorful names.

A Project Slut is an organization that takes on too many projects ("it just can't say no" he says). The result is that nothing gets done, or nothing gets done well. I can say as a developer that this has a negative effect on team moral. The feeling that everything is a hack or quick fix and rushed out the door to users is not a good one. It's hard to take pride in your work. There's a lot to be said for picking fewer things and doing them well. Developer's productivity is in proportion to their pride in what they are doing. If they don't feel good about it, it's much less likely you'll see them there after hours making sure it's done well.

A Brownian Project is one has too many people added too early on. For example, the project might have too many people involved at the design phase such that the design progresses slowly as a result of trying to incorporate the ideas of everyone involved ... or worse, you end up with what I'd call a "compromise design". A compromise design sacrifices coherence to appease the people involved in the design. This is often the case with specifications that are designed by a committee of interested software development corporations.

Notice that I said "corporations". I am reminded of the JDO2 specification, which was controversial in it's time because it had overlap with an up and coming specification we now call EJB3. Reading the official "votes" from various companies, many were against it. Nevertheless, Sun pushed it through adding to later confusion of many users when JPA came to the scene. I'll never forget the Apache Software Foundation's comment though: "Let a thousand flowers bloom" (a yes vote).

A Dead Fish project is one that sets an unrealistic date, or impossible requirements, etc., and therefore is doomed to fail. This doesn't strike me as a useful pattern, or a pattern at all. A pattern is something you can use to help you solve a problem. No one starts a project with the foreknowledge that it's going to fail. Pick any project, and you can find at least someone that thinks it's going to fail, and someone that thinks it will succeed. This pattern can only be applied in hindsight, which makes useless.

Wednesday Jul 11, 2007

Most folks that have Macs own a notebook version. If you have a significant music / video library, you won't have the disk space on your notebook. This is one thing I never understood about iTunes. Any significant music collection is going to swamp the notebook's disk. The defaults are all set to store the library on the local disk, and to actually make copies of files you add to the library in the iTunes folder. For the latter, if you don't actually understand what's going on, you could wind up with multiple copies of files hanging around.

Another point is that most people want to share their library between users in their household. I think there's a way to share your iTunes library from your Mac (I've never tried it), but that assumes that any consumer of the media is also using iTunes. iTunes is not a general purpose media player. I have a lot of formats it won't consume, so I use other players like VLC in some cases.

After being an early adopter of several different types of digital audio players, the iPod model was a hard pill to swallow.  The basic approach is the iPod is a read-only device to everything except iTunes, and who's format and content is completely managed by iTunes. There's only one reason the iPod works this way: control. Apple can force you to go through iTunes, which is as much a storefront as anything else, to manage your library. The iPod could easily have been a standard USB mass storage device, and allow files to dragged and dropped onto it. But then you wouldn't be forced through iTunes, and the iTunes Store. To be fair, this would require more logic on the iPod to index the library, which might have been a technically harder problem. Also, the iPod only plays AAC format, so even if you import MP3 files into your iTunes library, they are converted to AAC before they are copied to the iPod. Again, this allows the iPod to be simpler in that it doesn't need to understand anything other than AAC.  It can rely on iTunes for that. This probably makes importing music slower, but that is not an everyday thing for most people. The only good thing here is that iTunes hides this detail from you.

Unfortunately, the iPod model is used by most other digital audio manufacturers (there are a few exceptions). The difference is that for them, the software is not iTunes, it's Windows Media Player. So when I was faces with the choice of purchasing on oddball brand that supports USB mass storage, a player that requires Windows, or an iPod, I chose the lesser of the three evils.

But anyway, back to the problems of disk space and sharing media. This is my best solution ...

To get around the limited disk space / sharing problem, the actual content of my library is stored on a large shared disk. I use a neat little NAS device which is essentially a drive enclosure that runs a slimmed down version of Linux with the purpose of running an SMB and FTP server (only, that's all it does). This particular device has been pretty darn stable for me. I chose it because it's an enclosure, not a sealed unit already containing a drive. This allowed me to buy a cheap 500GB drive and keep the cost down. The only drawback is that it is an ATA-100 interface, not SATA. You'd think this would be an advantage. ATA-100 is older, and the drives should be cheaper. However, it's so old that the drives are getting hard to find and they are about the same price. SATA is much faster, but that doesn't matter as ATA-100 is very much fast enough to keep up with either the USB or network interfaces to the drive.

A drawback of "all on the shared disk" is that the library doesn't leave the house with you. It not on your notebook. Well, that's why I carry the iPod around with me.

With the NAS, I can mount the SMB drive on any computer in the house and access the media in any way I want. For example, an integral part of my "media center" is an older Windows PC connected to my "TV" and some cheap computer speakers. I use this to play music and  video .avi, .mpg, streamed content from the internet, etc., movies. Of course the PC plays DVDs also so I could throw out my DVD player too. The PC just mounts the shared disk and plays the files from there. You don't need a powerful, "media PC" for this, and it doesn't have to be a high-tech expensive solution. Just about any PC manufactured in the last 6 years can play DVDs, .mp3s, and .avi files. It's a PC simply because I had one lying around. It could also be an Mac Mini.

As a side note, I purchased a nifty wireless keyboard for the PC. I set the fonts big, and I can sit on my couch and control everything. Very nice, even if the keyboard makes a rather large remote. This model is pretty small, and has a built in trackball mouse so the keyboard and mouse are one single unit. It's worked flawlessly, although you wouldn't want to do a lot of work with it as it's small and the trackball isn't the best. FYI, if you're looking at wireless keyboards, there are models w/ a range of "up to 10 feet" then there's the "up to 50 feet" models. Get the latter, even if you're within 10 feet of your media center, they get flaky at 3-5 feet.

For iTunes, I mount the drive via SMB and import the media from the shared drive. This must be slower, but I don't know how much because I've never done it any other way. I imagine it's a lot slower, as in this case it is accessing the shared drive over a wireless connection. Anyway, with about 20G on the iPod, it take about 5 minutes to do a no-op sync operation from iTunes. That's okay by me, as I can just connect it and walk away, and it's always done by the time the iPod is charged anyway.

One problem I ran into recently ... the shared drive is just a DHCP client, so it can potentially get any of the IP addresses in the block that is made available on my router. I could go into the router and force it to assign a particular IP address to the NAS each time, but the problem with that is I've needed to "reset" my router several times which makes it lose this type of configuration, and it's a pain in the arse to configure, so I just don't like to add any complex config to it.

So the other day, I needed to reboot the router. My NAS picked up a different IP, which was a different automount point (I am automounting the NAS SMB point). iTunes could no longer resolve any of my library. Neat. There is no way to fix this through iTunes itself, except by "locating" each individual file. There are no utilities I could find to do it either.

In retrospect, I should have created a symlink to the mount point, and then imported from that location. Then if the IP of the NAS changes, I can just change the link. I did this now, but I didn't think of that initially.

As it turns out, it's pretty easy to muck w/ the iTunes library. There's a binary formatted version, but there's also a XML backup. To solve this, I sed'd the XML library file and changed the "location" of all of the media to the symlink.

sed -e "s#file://localhost/private/Network/Servers/192.168.0.10[10]/PUBLIC#file://localhost/Users/jtb/mnt/PUBLIC#g" "iTunes Music Library.xml" > ../new.xml 

(Noticed that I used a different separator in the sed expression to avoid escaping all of the /'s) 

Then I removed all of the iTunes files, restarted iTunes, and did a File->Import Library operation on the new XML library I created. This took a long time to re-import everything and calculate "gapless playback" (whatever) but it seems to have worked.

One think that stuck for for a while was the "location" in the XML library. It's a file:// URL, so I originally tried ...

file://Users/jtb/mnt/PUBLIC (this is my symlink to /Network/Servers/...)

As it turns out, iTunes wants a HOST NAME in the FILE URL, like this:

file://localhost/Users/jtb/mnt/PUBLIC

Not what you'd expect.

Of course, the key to using iTunes this way is to set your preferences to NOT copy files, and NOT rename them (see Preferences->Adavanced). Basically, tell iTunes to leave the media files alone and just use them from their original imported location.
 

 

 


 

Thursday Jun 21, 2007

My new article just went live: Authoring Community Services with Portal Server. It explains, in great painful detail, what it takes to augment the stock set of community services.

While Portal Server comes with a stock set of services including blog, wiki, surveys, polls, discussions and file sharing, some users will want to add their deployment specific services. This article will help you do that. If you have any questions on the article or new need further elaboration, please feel free to contact me at: jeffrey.blattman@gmail.com, or subscribe to the OpenPortal users alias ... OpenPortal is the open source version of Sun Portal Server.

 

Thursday Jun 14, 2007

All software groups were given the task some time ago to go open source. Sun can tell the direction the wind is blowing. Many interesting open source projects have resulted from this effort, including the Glassfish application server, the OpenDS directory server (a 100% pure-java LDAP implementation), and OpenSSO. No one (well, that huddled masses at least) is sure Sun will be able to capitalize on this, but they are plowing forward full steam nonetheless. It's not that there isn't a plan, but no one is sure if the work of building an open source community will be rewarded in sales of products based on the project's code --- rewarded enough to offset the cost of building the community. We will see.

For Sun's Portal Server product, the mechanism to go open source was not clear. It essentially came down to two options: 1) throw what is there over the fence, or 2) re-architect the product and release it into open source as smaller projects. The product team initially went in the direction of option 2. There are many reasons for this, but in a nutshell the existing code base is, for lack of a better word, monolithic in nature. We (the Portal Server product team) didn't feel that option 1 would be a good for community building, as the large, interdependent code base would not promote understanding and therefore contribution.

Now, (external) contribution and community are not requirements for open source. It is perfectly valid to open source code and not build a community around it. This is probably not what people think of when someone says open source, and it is distasteful to software developers, but it does count as open source.  If nothing else, it allows existing product customers to look into the code to understand how the product works.

For some parts of product, option 2 went ahead as planned. The portlet container, WSRP, JSF-portlet bridge, and portlet repository projects were all spawned from the closed-source Portal Server code. But until recently, the bulk of the code still existed inside the firewall.

 A few months ago we came to the realization that option 2 would not yield a complete open source portal for some time, as modularizing the product is quite a daunting engineering task. So, we entered into the option 1 fire drill.  In early June, the Portal Server code base was committed to the OpenPortal project. OpenPortal is now buildable and installable outside the firewall, and will be the code base for Portal Server version 7.2 and beyond.

 Mainly due to some legacy C code, there are some rather nasty restrictions on building. And, it still has a dependency on the Sun JES stack up to Access Manager.

 We haven't given up on option 2, the complete modularization of portal, but we will be undertaking it in bits and pieces, working from the OpenPortal code base. It will happen in the open. A side affect of modularization will be a lighter-weight portal with an easier, more flexible installation. I won't be happy until I can install on OSX.

To stay tuned and for more information, join the OpenPortal project, and get on the aliases.

Tuesday Jun 05, 2007

I got my hands on a session pass at Java One's "community one" event, and decided to attend two session for which I am a newbie: JRuby and Matisse - both of which were under the "Netbeans Track".

 Both of the sessions were essentially a demo, which consisted of someone very well versed with both the technology and Netbeans quickly clicking and typing to produce some interesting application in an unreasonably short amount of time. Wow! What really gave me goose bumps was when the audience applauded the results. Not goose bumps because I was impressed, but the kind of goose bumps you get when you are embarrassed for someone else.

For any GUI-based development, whether it's portlets, EJBs, SWT applications, or whatever, there will come a point very quickly when you need to do more than the "hello world" component. At that point, you will need to have an intimate knowledge of the underlying technology. Now, the problems is that the GUI lets you get from 0 to 5 without any real knowledge. To do anything more, you need to go back and learn what the GUI did to get you from 0 to 5, which is more difficult than just going from 0 to 5 the "hard" way, by actually learning.

 Rapid GUI-based development tools make good demos. They impress product managers and sales folks. They even sell products. But they are not solutions for real developers.


Tuesday Mar 20, 2007

A Slashot article is reporting that in terms of total energy used over the life of the car, considering the cost of manufacturing, the Hummer is greener than the beloved Prius. Great stuff. And, as is pointed out in several article comments, the environmental impact of mining the materials for the batteries is horrendous.

And a comment on the article that I really liked:

The Prius was never for real environmentalists anyway. It's for lazy yuppies who want to put out an environmentally conscious image. Real environmentalists live close to work, bike, or take the bus.

It's also fairly well known that where the Prius excels in gas mileage is in-city driving. If you are getting a Prius to drive in city, then you can probably easily take a bus / train, walk, or ride your bike.

 

 

 

 

Monday Mar 19, 2007

If you've ever tried to add an onclick handler to a JSF h:commandLink component, you'll notice that the event isn't defined. The reason is that JSF uses onclick for it's own purposes, to POST the click where it would normally be a GET request. For example,

<a id="entriesTableView:feedForm:feedTable:0:deleteEntryLink" 
href="#"
onclick="clearFormHiddenParams_entriesTableView_feedForm('entriesTableView:feedForm');document.forms[ ... and so on ...

This makes it impossible to do one of the most basic onclick tasks: confirm an action. If you Google for this, the suggestion is to set the onmousedown handler, and use it just as you would onclick:

<h:commandLink action="delete" onmousedown="return confirmDelete(this);">

Nice idea, but it turns out that many browser do not treat the "return false" from the onmousedown event the same way as with onclick. Normally, the false return value means abort the user's click. However, it appears that it does NOT necessarily mean abort the onclick event handler. The result is that the onclick is executed regardless of the return value of the onmousedown event handler.

The solve this, you'll need to do some Javascript trickery. The basic idea is to re-assign the link's onclick handler to a new Javascript function that has a pointer to the original (JSF defined) function. The new function does the ok / cancel logic. An "ok" just calls the original JSF-defined onclick function. "Cancel" returns false from onlick, and aborts the click like we want.

... 
var deleteClick;
          
function assignDeleteClick(link) {
  if (link.onclick == confirmDelete) {
    return;
  }
               
  deleteClick = link.onclick;
  deleteMsg = msg;
  link.onclick = confirmDelete;
}
           
           
function confirmDelete() {
  var ans = confirm("Delete?");
  if (ans == true) {
    return deleteClick();
  } else {
    return false;
  }
} 
...
<h:commandLink action="delete" onmousedown="assignDelete(this);">

 Note that this re-assigns the onclick event every time the link is clicked. This is not necessary and it could be done once in the onload event. This would require hardcoding of the big long scary JSF component ID, which I do not like doing. This is the reason that the first lines of assignDelete() check to ensure that the assignment hasn't been done already.

 


Monday Feb 12, 2007

I just committed Blog Portlet to the Portlet Repository java.net project. Blog portlet allows portal users to manage their weblog from a portal page. It depends on the weblog implementing (and turning on) an Atom Publishing Protocol endpoint.

 

The intent is not to replace the native weblog user interface, but rather to provide a simplified one that allows users to perform the most common management operations from their portal page: post, edit, delete.

In addition, the portlet has a simplified interface for creating weblogs and weblog users. This feature depends on the AAPP admin interface in Roller - meaning, you have to point the portlet at a Roller weblog server.

There are a couple of caveats at this point ...

  1. The portlet is really a JSF application, and therefore depends on JSF Portlet Bridge. While this is called out in the portlet's pom.xml, the dependency is not available from any repository. Therefore, to build Blog Portlet, you need to get and build the JSF Portlet Bridge and populate the dependency into your local repository. Hopefully this will change in the near future.
  2. While the portlet is setup to use FCKEditor to create and edit weblogs, FCKEditor is also not available as a dependency. So, by default, FCKEditor won't be there, and you'll get a standard ugly text area. To make the portlet is FCKEditor, get the "fckeditor" directory into the web application. You could do this after you deploy the web app by just dropping the files into the right place, or you could do it in the build environment by copying ther directory into src/main/webapp. Or, alternatively, it should be easy to plug in whatever Javascript editor you like by making some small changes to the portlet.
  3. The portlet is only tested with Roller's APP implementation. APP is new and somewhat unstable, so I hope folks can help out and get this tested / working on other APP implementations.
  4. Documentation is slim. I hope to either upload some documentation, or point to the Sun Portal Server 7.x documentation for the portlet that should apply 98% to the open source version. This documentation is not yet posted to docs.sun.com however. In the meantime, if you have questions, please post comments, or better yet, post to the Portlet Repository user mailing list and I will be glad to help you out.

Have fun!

 

Thursday Jan 18, 2007

I've posted Flickr Portlet to the Portlet Repository project. Flickr exposes a (web) service API to their photos. This portlet simply consumes that interface and makes it available from a portlet user interface.

 

 From the portlet, you can browse your photos, upload photos, browse your contacts' photos, and search for photos. Well, the search part is just stubbed out for now.

The portlet is just a front end for Quickr, which does a nice job bridging the Flick services API to Java. One cool thing about the portlet is that it makes use of Lightbox JS to allow for asynchronous browsing of photos in a larger scale:

 

The Portlet Repository project does not have binaries right now, so grab the source and build it to get the portlet WAR. 


Monday Nov 20, 2006

Flickr has a robust set of web services for accessing their hosted photos, and more. There's already a wide variety of API kits to adapt the various response formats (XML-RPC, REST, SOAP) to different languages ... including .NET, PHP, Ruby, Python, Perl, and others. However, the Java contingent is a little weak. To support the Flickr Portlet I am developing for the Portlet Repository project, I started the Quickr Flickr project. This is essentially a Java wrapper around the Flickr REST services. 

I think I've done a fair job of making it simple to use the Flickr web services from Java. If you're interested in writing Java applications or web applications that build on Flickr, take a look at Quickr Flickr! It's not completely built-out yet (it doesn't map to all of the Flickr service methods), but it's getting there.

Wednesday Nov 15, 2006

After using the full-featured Sun Portal product to try and do portlet development for a few years now, I've been looking for something more light weight. Essentially, I needed something I can run on my OSX laptop. The obvious choice for me was Apache Pluto. It's been around for a while now. It's the core of Apache Jetspeed-2, and other portals. It's the JSR-168 Portlet RI. Here is my experience ...

First, Pluto 1.1 (beta) requires me to add some heinous blocks into my Maven2 POM in order to deploy. While I think this is a stopgap until 1.1 has a deployment tool, I have to outright refuse anything  that requires vendor-specific aspects to my portlet. So, I ruled 1.1 out immediately.

Pluto 1.0.1 has a palatable GUI deployment tool. However, I never got my portlet to run. Now, I accept the fact that this may be a result of problems in my portlet, but the container has to TELL ME what the problem is. Class not found? JSP compilation error? Nope. Pluto would only tell me that there was an "error in portlet":

Nov 8, 2006 4:03:16 PM org.apache.pluto.portalImpl.services.log.LoggerImpl errorSEVERE:
Error in Portlet
java.lang.NullPointerException
        at org.apache.pluto.invoker.impl.PortletInvokerImpl.invoke(PortletInvokerImpl.java:109)
        at org.apache.pluto.invoker.impl.PortletInvokerImpl.load(PortletInvokerImpl.java:80)
        at org.apache.pluto.PortletContainerImpl.portletLoad(PortletContainerImpl.java:218)

No other clue. I can hardly believe that there is not some way to get more information ... but I asked (twice) on users@pluto.apache.org and received no response. Also, as a side issue, Apache's spam filter rejects any email I send from my Yahoo! mail account. That makes getting help pretty difficult :)

Enter the java.net Portlet Container project. It's only been live since August 2006, and it's already superior to Pluto. It's simple to install and configure (requires Glassfish), and best of all, IT RUNS MY PORTLET, or if not, TELLS ME WHY.

 As a bonus, it actually lets you undeploy a portlet, something that Pluto 1.0.1 does not (you have to manually edit several XML config files).

Full disclosure: the Portlet Container project is Sun-sponsored and has been developed wholly by Sun employees. However, I want to make it clear that I really, really tried to work with Pluto. This is an honest assessment of the state of the art.

Wednesday Oct 25, 2006

The other day, I started working on a new JSF-based portlet app ... essentially, a JSF app that would use the JSF-Portlet Bridge so it can be sucked into a portal. Without going into details, the app needed to draw a table where each cell contains one object from a set of objects. For example, think of a photo album. Each table cell contains a photo and some meta data about the photo perhaps.

I would have really though this is a common enough pattern that it'd be straightforward in JSF. Well, it's not. The only tabular-type components in JSF are panelGrid and dataTable. panelGrid does not allow a dynamic data sets; you must call out all of the cells statically. dataTable only supports a "one object per row" scenario, as opposed to per-cell as I needed.

For example, suppose I had a tag called dataGrid. I'd want to use it like this:

<h:dataGrid var="photo" value="#{album.photos}" columns="6">
  <h:cell>
    <h:panelGrid columns="1">
      <h:graphicImage url="#{photo.url}"/>
      <h:outputText value="#{photo.title}"/>
      ...
    </h:panelGrid>
  </h:cell>
<h:dataGrid>


But obviously, this tag doesn't exist. Not only doesn't it exist, it's not even possible to do, at all, without writing a custom tag or binding say a panelGrid and building it's contents programmatically (which sort of defeats the point of JSF). Writing a custom tag is an option, but when faced with the decision of whether to spend a week writing a custom tag or writing the entire app in the same amount of time, I chose the latter.

Another thing one would like to do in such a situation is to mix JSF and JSTL for the desired result. For example, use a JSF panelGrid and the JSTL forEach tag:

<h:panelGrid columns="6">
  <c:forEach var="photo" items="${album.photos}">
    <h:panelGrid columns="1">
      <h:graphicImage url="#{photo.url}"/>
      <h:outputText value="#{photo.title}"/>
      ...
    </h:panelGrid>

  </c:forEach>
</h:panelGrid>

But JSF and JSTL don't like each other, and such intermixing is not supported. I don't know all of the technical reasons why this doesn't work.

Another possible solution would be to pick up a third-party component library that had what I needed. Since free is my only option, I have looked into MyFaces Components (AKA Tomahawk) in the past. However, I was not able to get it to work with the specific JSF-portlet bridge, JSF implementation (the RI), and portlet container I was already bought into. Of course, I never really looked into whether MyFaces Components had the component I needed anyway.

Alas, the app is being written with plain old JSP + JSTL
My article introducing the Portlet Repository open-source project went live today on developer.sun.com. Not exactly a technical article, but it's my first published, so it means something to me :)