Friday, June 8, 2012

Portable Workstation Update

Well it turns out the M350 case was not the right choice for the A8-3870K processor I bought. It ran hot and after 5-6 hours at idle it would pretty much overheat and lock up at 70C. I went to Frys and using some ad hoc engineering I was able to cram two 60mm fans into the case to assist in controlling the heat. While it help it could not stop the heat buildup loop.

I ended up buying a new Lian Li pc-q09fn case. I have always been a Lian Li fan but this case somewhat disappointed me. It does not have a PCI slot although there is space for one. This means this case is only useful for motherboards with integrated graphics. (I am sure one could dremmel a slot if needed). Bizarrely the front USB ports are connected to a USB cable extender that is suppose to pass through the case, out the back, and then plug into the external port instead of plugging directly into the internal USB pins. Ridiculous! I attempted to contact Lian Li but their support is non-existent.

The good thing is that the case is larger but it still fits in my ebag with my monitor. The case does come with a built in 300w power supply which means I don't have to worry about power consumption or lug around an external power supply. It is aluminum and is quite light weight. Perhaps if I had to pack the workstation everyday it would be cumbersome but for the limited times I have to travel this build has worked perfectly. I am looking forward to upgrading to the new AMD Trinity APU's later this summer :)

HD HomeRun Prime Quirk

Last December I created a HTPC using a HD Prime tuner and CableCard for watching TV. Tonight after a long day at work I wanted to sit down and watch HBO and to my dismay Windows Media Center (WMC) would not display any premium channels. Other channels worked fine. I was not sure if it was related to an automated Verizon Fios setup box reset command I used for another set top box or that I was updating my contract and my account may be in limbo. After reinstalling the HD prime software HBO would play for 5 seconds and then display an activation required message. I followed the activation steps but it ended with a message stating "Your Computer is not Digital Cable Ready" On the HDPrime management page in the logs I saw entries ending with " access = unspecified" I was thinking I would need to contact SilconDust support but then I started up my workstation running windows 8 customer preview and HBO played fine in WMC so I knew it was machine specific and not a problem with the tuner.

After reading this post it turned me on to WMC Digital Cable Advisor which can be access in WMC at Extras->Extras Gallery->DCA. After running it and going through the wizard I was able to watch HBO again. Yeah!!!!

Saturday, May 5, 2012

Portable Workstation

As an IT consultant working on a computer all day long is a part of my job. Additionally I may be called upon to travel at a moments notice. I need to keep my main computing environment mobile so that I can take all my current work with me and not have to worry about which computer has what data on it or bother with trying to keep multiple machines synchronized. Perhaps cloud computing will one day be a solution to my synchronization problem but right now I get trapped behind client firewalls and with large amounts of data (several hundred MB) it is impractical to try to shoehorn a terminal-server solution.

Seeing that a laptop should be my main tool of the trade logic would dicate that I invest heavily in a top of the line model considering the time of use. Back in late 2009 I spent a considerable amount of money on an HP dv8t laptop. It still of course was much less than a top of the line Apple laptop (how could it not be?). It has features such as an 18.4 LED 1080P monitor, 802.11n, bluetooth, 1.6ghz mobile i7 quad core processor, 250 GB hard drive, and 6GB of RAM. Unfortunately, it also had some unadvertised "features". When I first received the laptop occasionally the LED backlighting of the screen would go out and the display would be unusable. I tried to flash the latest bios version on it and then the fan would stay on at full speed regardless of load. With the screen out and the fan on high I RMA'd it and HP put a new motherboard in it. Then around summertime when the ambient temperature increased the touch button pannel would go haywire, muting and unmuting the volume but more annoyingly it would disable/renable wifi and bluetooth. This issue has persisted to this day, causing me grief while trying to VPN into a client's network only to be disconnected, or talking on a Skype call and being disconnected. Next the black screen problem returned. Sometimes at a client site in the morning I would boot up the machine only to find the display non functional. I would then have to shelve it and use netbook to try to stay productive. Also the heat produced by the laptop under load would make it intolerable to place on my lap.

The black screen problem has seemed to become more severe and with the age of the system I started to look into a replacement. My first option would be to invest in a new top of the line laptop. I have been spoiled by having a 18.4 inch display over the years and I would not like to downsize to a smaller screen so this would limit my choices. Also, over the past few years I have never actually placed my laptop on my lap. I always keep it on a desktop either at work or while away. At home I typically plug in a larger external monitor, keyboard, and mouse. I am also once bitten twice shy about investing in an expensive laptop given all the risk involved with transporting it (drop it, stolen, etc) or ending up in the same boat where the display goes out and it is cheaper to buy a new laptop than repair the broken screen of an older one. If only I could have the speed and low cost of a workstation yet the portablity of a laptop...

This thought led me to my latest experiment: build a fast Java development workstation but with the restrictions that it should be low cost and portable. Typically cost and speed are inverse proportional to size making my goal challenging. Fortunately, technology has come a long way.
My first challenge was to acquire a portable display greater than or equal to 18.4 inches but was portable enough to carry and travel on an airplane. It has been seven years since I bought expensive twin 20 inch Dell LCD monitors and I was shocked to see how portable and inexpensive LED monitors have become. After surveying the market I settled on purchasing an Acer S220HQLAbd 21.5 LED monitor from newegg.com. The most important aspects were it's dimensions (20x14.5x.5) and weight (4.5 lbs). It did not have an HDMI port but at $130 shipped it was a bargain and inexpensive enough not to fret over travel loss or damage. I was able to buy a cheap HDMI female to DVI-D male adapter so I could use a thin lightweight HDMI cable and more importantly play protected content such as Windows Media Center. When I got the monitor it was everything I wanted: thin, light weight, and as a bonus it seemed to be designed to be portable as the stand can easily be disassembled without screws or snap ins.

Next I needed a case to house my home built system. Obviously I would need use the smallest motherboard form factor available, mini-itx. After doing some research I located the smallest case I could find: a silver M350 case purchased from mini-box.com. This case is so small a power supply cannot fit in it and an external power supply is required. I ended up purchasing the picoPSU 150 & 105 watt power supply bundle.

As I am an AMD fanboy I decided I wanted to build an AMD based system as opposed to a intel one. AMD has an exciting new architecture called an APU which combines both a CPU and GPU on the same chip. While the CPU performance of the chip slightly lags behind comparable intel ones the reviews of this chip have been greatly positive for the value and graphics performance compared to other integrated graphic solutions. Given the form factor of the M350 will not allow any expansion card the APU is necessary for the kind of portable system I wanted to build. Additionally, if for some reason the portable workstation concept failed I could still use this new system to reliably act as a set top box/dvr playing Windows Media Center content streamed from a Silicon Dust HD prime CableCard tuner I purchased.

I ended up purchasing a A8-3870K APU, ASRock A75M-ITX motherboad, 2x4GB AMD branded corsair 1600 DDR3 RAM, and an OZC 120GB solid state drive. Since the motherboard did not have wireless or Bluetooth support I purchased a Pivos 802.11n and an Asus USB-BT211 USB adapters each reasonably priced at $10. I decided to re-use my existing Logitech Bluetooth mouse and purchased the Microsoft mobile 5000 Bluetooth keyboard.

Once I got all the components in I assembled the system. The first thing I noticed was the stock CPU cooler that came with the A8-3870K did not fit inside the 350M case. While I could have cut the cooler fan feet and made it fit the CPU is right in the middle of the board and part of the 2.5 drive has to partially cover it. In the mean time I left the case lid off and used the stock cooler for the time being. I was able to successfully boot the system. This is the first motherboard I used that uses UEIF instead of the 20 year old BIOS and it was a welcome surprise. When I tried to boot into Ubuntu 12.04 to install it the screen went blank and I thought the system hanged due to either heat or low power. I was a bit nervous that the 105 power supply was not enough so I shutdown may main HTPC and then reconnected the HTPC's 500w power supply to the new itx board and installed window 7. Windows installed lightning fast and I ran futuremark 3D 2011 and got a score of around 1078 I think. After that I reconnected the picoPSU and 105w power supply and the system ran fine. I did run futuremark 3D 2011 one more time and got a score of 750 so I knew for sure the system was under powered. I ordered the biggest 194w power supply from mini-box.com. I would recommend the 194w/160w picoPSU combo for anyone attempting to build a similar system. Finally I received the power supply and the Akasa AK-CC1101EP02 low profile CPU cooler and was able to close the system up. I was a bit disappointed with the loudness of Akasa fan noise. Also the 194w power supply used a large four pin adapter instead of the smaller pin adapter of the 105 power supply that nicely fit in the 350M case. I ended up drilling a hole in the I/O plate as there was plenty of space to the left of it on the A75M one. The hole was near the memory but there was sufficient space. I didn't leave a very aesthetically pleasing form given my drill bit was half the size I needed and I was manually grinding it larger with the plate situated on some left over Styrofoam from the monitor packaging.

Anyway, with the system fully powered I updated to Windows 8 consumer profile and installed Virtualbox 4 on it along with one of my VMs. The system was lightning fast comparable to my HTPC and faster than my dv8t laptop. I was very pleased with it.

Next for transportation I bought a Weekender eTech Convertible from ebags.com sized at 22X14x9, big enough to fit the monitor. I also bought a series 636 attaché like case from casesbysource.com but this ended up being a mistake. The screen did not fit flat in the case (apparently the screen is wider than 20inches) and the case is 8 inches deep making it too big to fit under the set in front of me on an airplane. My wife was kind enough to sow a custom protector for the monitor using materials from Hobby Lobby: a 20inch zipper, enough flannel to encompass the monitor and a 1 inch foam insert. At hobby lobby I also purchased an art carrier styled similar to an attaché case. I may use it in the future as a means to transport the monitor locally while using a laptop bag to transport everything else.
I went on my first trip with the portable system and I would have to say overall it was a success. With everything in the eTech it was very heavy, close to 18lbs. I am a big guy so this didn't bother me much wearing it on my back but it may be a non-starter for others. I was able to go through TSA security in both directions without incident, being sure to remove the monitor and case from the bag and placing them in separate containers. I used a second smaller backpack to pack my cloths in and on the plane I put the eTech in the overhead bin and my cloth bag under the seat in front of me.
There is one last issue that I need to deal with in order to say my goal was fully accomplished. The workstation runs very hot, 61c at light continuous load with the case closed. Given everything that is crammed into this tiny case there is little to no airflow but if I remove the case top it returns to an acceptable 48c level. With the case enclosed it is as if it gets into heat feedback loop that it cannot recover from. I have ordered another HD insert and two fans to see if I can add some additional cooling. This could be the Achilles heel of this build and I will update this blog if it becomes a dire problem. Right now I am eyeing the Lian Li Lian Li PC-Q9FN as a potential replacement. It is much taller than the M350 but I think I can fit it and the monitor in the 9 inch eTech backpack and it has a 300w power supply and superior cooling as well as potential space for a PCI card.

When the new AMD trinity APU processors and motherboards come out I may try to build another similar system. After all, I can get two portable workstations for the price of one high end laptop.
One more thing is that I also purchased an over the bed table, the kind you see at a hospital. I put the monitor on this and then wheel it around so I can program from the living room in my armchair all the while having a line of sight to the family TV. A nice leisurely Open Source programming environment :)

I also found out the Microsoft 5000 Bluetooth keyboard needs to be placed on a table and does not work very well at all when used on ones lap as I originally desired.
In summary, I would recommend the following:

  1. the M350 may be too small to support a 100w processor, both in power and heat dissipation.
  2. One could pair the monitor, Bluetooth mouse&keyboard with a moderate laptop to get a lightweight ergonomic portable working environment.
  3. I spent an enormous amount of my personal time researching components, ordering, assembling, and configuring the system. I also made several costly mistakes (accidently ordered the wrong size ram, case, and power supply). Such an effort is not for the faint of heart.




Sunday, April 22, 2012

Custom CDI Scopes

Sometimes when working with Dependency Inject (DI) there arises a reason to develop a custom DI scope. For example, if an application has a graph of objects that it will build out, utilize, and then dispose of during the lifetime of the application a custom scope would make sense. Or, if an application is context aware and DI should be performed based on the context a segment of code is running in then a custom scope also makes sense.
For example, when developing the ODE-X project I observed several different code contexts I wanted to support to realize a virtual machine metaphor:
  • Executable - XML is parsed building an object graph consisting of Blocks containing a sequence of Instructions. The executable objects themselves are stateless so they can be utilized in more than one program but they can have DI injection at runtime of the current context. Executables are loaded/unloaded at runtime and if an executable is no longer references by an active program it can be unloaded removing it from memory. Executable PostCreate and PreDestory methods should be invoked when execuables are loaded and unloaded respectively
  • Program - A runtime specific configuration for a set of executables. Programs may be installed and uninstalled and provides a scope of global memory and runtime state for all included executables. Business Process Monitor (BPM) configurations should be specified in this scope.
  • Process - A distinct instance of a business process. Provides process level global memory for a business process that may be shared among member threads
  • Thread - A path of execution maintaining a stack of state. The core premise of ODE-X relies on the ability of removing a virtual thread state from physical memory and persisting it to XML in a database and then rehydrating and resuming execution at some distant point in the future.
  • Instructional - per instruction DI based on the current execution state. At the beginning of instruction execution instructional objects are created and provided t to the executable and then afterwards all objects in the instructional scope are discarded


In this architecture a virtual processor would execute each Executable Instruction with the following scope hierarchy : program->process->thread->instructional->executable.

To summarize, this application will maintain the lifecycle of a set of objects participating in DI and it needs a way of notifying the DI container when a set of DI obtained objects are no longer needed. Additionally, to simplify the architecture and take full advantage of DI, the application would like to configure DI such that objects defined in a higher level scope can be injected into objects defined in a lower level scope.
Fortunately the talented specification leads of JSR 330 (DI for Java) and JSR 299 (CDI) had the prescience to allow custom scopes. While some of my posts about perceived defects in CDI and Weld may be pointed I sincerely am impressed with CDI extensions and it truly does unleash JavaEE. I have written a simple example illustrating a custom CDI scope with the bonus of a scope qualifier.
For this example I disabled CDI auto discovery in favor of manually declaring CDI bean classes which is my personal preference. The key points of the sample is the CDI extension declaration of the sample DI actors

public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd, BeanManager bm) {
  bbd.addAnnotatedType(bm.createAnnotatedType(FooCDIInstanceProducer.class));
  bbd.addAnnotatedType(bm.createAnnotatedType(FooScopeContext.class));
  bbd.addAnnotatedType(bm.createAnnotatedType(Foo.class));
  bbd.addAnnotatedType(bm.createAnnotatedType(Bar.class));
  bbd.addQualifier(FooInstance.class);
  bbd.addScope(FooScope.class, false, false);
}

public void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
  abd.addContext(new FooCDIContextImpl());
}

The use of the custom scopein the code:

FooScopeContext fooScope = ..
fooScope.create();
try {
fooScope.begin();
...
} finally {
fooScope.end();
}
fooScope.destroy();

and the finally the integration of the application scope with the CDI scope Context. Notice the use of Java ThreadLocals so that the application representation of the scope maintains the actual instances of the Objects and then passes those references to the CDI Context implementation so that they in turn can be passed back to the DI container for injection. While I am not a fan of ThreadLocals they are the ideal solution for custom scopes and I don't think one could make a CDI scope without them.

I came across an additional challenge with CDI custom scopes in that I wanted to add qualifiers to custom scoped objects so that injection point information could be passed into the custom scope Context and based upon the qualifier information the appropriate scoped object could be returned and injected. The solution I ended up at involved creating a custom qualifier producer and then passing the qualifier information on to the scope Context using another ThreadLocal variable. While I think the most ideal solution would be for the scopeContext provider to be presented with the InjectionTarget information if present this approach does have the benefit of separating scoped object creation from qualifier instance modification. For example, the scopeContext simply creates and tracks the lifecycle of the object whereas the Qualifier Provider can mutate the returned object based on the qualifier information.

One final thing to keep in mind with CDI custom scopes is that it adds more utility to the JSR 330 Provider interface. Before I though the Provider interface was only useful for obtaining references to brand new instances of DI objects on demand. In the context of a custom scope using the Provider interface may mean that the returned instance is not a new instance but a handle to an existing scoped object. For example, I will use the Provider interface in Executable and Instructional scoped objects so that contextual instances of objects in the higher Program, Process, and Thread scopes can be retrieved and utilized for contextual execution of the instruction.

Saturday, April 14, 2012

Binding a custom XmlJavaTypeAdapter to the JAXB XJC Code Model using JAXB Binding Customizations

Recently I have been working on an application that heavily utilizes XML schema and JAXB. Since I chose XML Schema as my typing framework I desired to use JAXB's XJC code generator to keep Java model classes in sync with changes I made to the XML model. While 90% of the XJC generated code was sufficient there was 10% that I wanted to customize so that the Java model classes functioned more seamlessly with my framework. XmlAdapter seemed to be a perfect fit for my needs but the problem was how do I generate a reference to my custom XmlAdapter right in the middle of the XJC generated object model?

While there are plenty of trivial examples of using an XmlAdapter to convert a non-mappable Java object to XML all the ones I read utilized a complete handcoded JAXB object model and not one generated from XJC. After much research and head banging I came across two methods of introducing a XmlAdapter or any other valid hand coded JAXB object into the XJC generate code model using  JAXB XJC customizations in an external binding file.


Complete Simple or Complex Type Replacement using jaxb:class ref="..."


The standard <jaxb:class> custom binding actually supports a ref attribute so that a Simple or Complex type can be directly mapped to an existing Java class. The class must be a valid JAXB annotated object or mapped to an XmlAdapter via an XmlJavaTypeAdapter annotation at the package or class level. This technique is actually used extensively inside JAXB episodes for multi schema separate compilation. This seems to be an intuitive means of mapping hand coded JAXB objects into XJC generated code but surprisingly enough there is little documentation on it. If one does a google search on "JAXB bind customization" the first link to the Oracle documentation site completely omits all references to the ref attribute. Below is an example of how I used the jaxb:class ref attribute to bind interfaces to the XJC object model:

XSD:

 <simpleType name="srcIdType">
  <restriction base="ID">
   <pattern value="s\d+" />
  </restriction>
 </simpleType>
 
 <simpleType name="srcIdRefType">
  <restriction base="IDREF">
   <pattern value="s\d+" />
  </restriction>
 </simpleType>

 <complexType name="sourceType">
  <attribute name="src" type="tns:srcIdType" use="required" />
 </complexType>
XJB:

 <jxb:bindings node="//xs:simpleType[@name='srcIdType']">
  <jxb:class ref="somepackage.SrcId" />
 </jxb:bindings>

 <jxb:bindings node="//xs:simpleType[@name='srcIdRefType']">
  <jxb:class ref="somepackage.SrcIdRef" />
 </jxb:bindings>
 
Custom Java:

@XmlJavaTypeAdapter(SrcIdAdapter.class)
public interface SrcId {
 
 String id();

}

@XmlJavaTypeAdapter(SrcIdRefAdapter.class)
public interface SrcIdRef {
 
 String id();

}

public class SourceId implements SrcId, SrcIdRef {
 public SourceId() {
 }

 public SourceId(String id) {
  this.id = id;
 }

 private String id;

 @Override
 public String id() {
  return id;
 }

 public static class SrcIdAdapter extends XmlAdapter<String, SrcId> {

  @Override
  public String marshal(SrcId id) throws Exception {
   if (id != null) {
    return id.id();
   }
   return null;
  }

  @Override
  public SrcId unmarshal(String id) throws Exception {
   return new SourceId(id);
  }

 }

 public static class SrcIdRefAdapter extends XmlAdapter<String, SrcIdRef> {

  @Override
  public String marshal(SrcIdRef id) throws Exception {
   if (id != null) {
    return id.id();
   }
   return null;
  }

  @Override
  public SrcIdRef unmarshal(String id) throws Exception {
   return new SourceId(id);
  }

 }

}



XJC Generated Java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "sourceType", namespace = "somenamespace")
public class Source {
...
@XmlAttribute(name = "src", required = true)
protected SrcId src;
    

Using the custom code:

Source s = new Source();
s.setSrcId(new SourceId("b0i0"));

Here is an example of binding a default java class to a simpletype and using a package level annotation to associate the XMLAdapter
XSD:

<simpleType name="bondURIType">
 <restriction base="anyURI" />
</simpleType>

<complexType name="executionConfigType" abstract="true">
      <attribute name="uri" type="tns:bondURIType" use="required" />
</complexType>
XJB:

<jxb:bindings node="//xs:simpleType[@name='bondURIType']">
 <jxb:class ref="java.net.URI" />
</jxb:bindings>
 
Custom Java:

//URIAdapter.java
public class URIAdapter extends XmlAdapter<String, URI> {

 @Override
 public String marshal(URI uri) throws Exception {
  if (uri != null) {
   return uri.toString();
  }
  return null;
 }

 @Override
 public URI unmarshal(String uri) throws Exception {
  return URI.create(uri);
 }

}

//package-info.java
@XmlJavaTypeAdapter(URIAdapter.class)
@XmlSchema(namespace = "somenamespace", xmlns = { @XmlNs(namespaceURI = "somenamespace", prefix = "myprefix") }, elementFormDefault = XmlNsForm.QUALIFIED)
package somepackage; //needs to match XJC package declaration, XJC -npa flag should be set to not generate a package-info.java file

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;


import somepackage.URIAdapter;

XJC Generated Java:

 @XmlAttribute(name = "uri", required = true)
 protected URI uri;
    

Property Replacement using jaxb:property/jaxb:baseType name=".."


Another scenario to consider is when one would like to use XJC to generate JAXB objects from a schema but then use a XmlAdapter to map a non-compliant Java object to the XJC generated classes. For example, I wanted to bind a Java Map to a custom complexType I wrote. It turns out that if one wants to change the Java type of a property one can use the property/baseType combination. Again, this was not very intuitive and I didn't find many examples on the Internet of this use case.


XSD:

 <element name="Root">
 <complexType>
  <sequence>
   <element ref="tns:TestVariables" minOccurs="1" maxOccurs="1"/>
  </sequence>
 </complexType>
</element>
 
<element name="TestVariables">
 <complexType>
  <sequence>
   <element name="TestVariable" minOccurs="0" maxOccurs="unbounded">
    <complexType>
     <attribute name="name" type="string" />
     <attribute name="value" type="string" />
    </complexType>
   </element>
  </sequence>
 </complexType>
</element>

XJB:

<jxb:bindings node="//xs:element[@name='Root']//xs:element[@ref='tns:TestVariables']">
 <jxb:property>
  <jxb:baseType name="test.TestMap" />
 </jxb:property>
</jxb:bindings>
 
Custom Java:

@XmlJavaTypeAdapter(TestAdapter.class)
public class TestMap extends LinkedHashMap<String,String>{ 

}

public class TestAdapter extends XmlAdapter<TestVariables, TestMap> {
 @Override
 public TestMap unmarshal(TestVariables value) {
  TestMap map = new TestMap();
  for (TestVariable var : value.getTestVariable())
   map.put(var.name, var.value);
  return map;
 }

 @Override
 public TestVariables marshal(TestMap map) {
  TestVariables vars = new TestVariables();
  for (Map.Entry entry : map.entrySet()) {
   TestVariable var = new TestVariable();
   var.name = entry.getKey();
   var.value = entry.getValue();
   vars.getTestVariable().add(var);
  }
  return vars;
 }

}


XJC Generated Java:

@XmlRootElement(name = "Root", namespace = "urn:test")
public class Root {

    @XmlElement(name = "TestVariables", namespace = "urn:test", required = true, type = TestVariables.class)
    protected TestMap testVariables;
    

Using the custom code:

Root root = new Root();
TestMap map = new TestMap();
root.setTestVariables(map);
..
m.marshal(root, writer);

There it is, two ways of injecting your own custom JAXB objects into the XJC generated object model. Now one can enjoy the full benefit of using a XML schema first development approach utilizing XJC to rebuild corresponding Java objects all the while having the flexibility to drop down to hand crafted JAXB objects when appropriate.

Windows Update Forced Restart Woes

Yet again I resumed my netbook only to have Windows Update shutdown my computer losing all my work, probably thirty minutes worth. All these tech companies are so adamant about piracy and losing revenue due to other people's actions. I wish these same companies would be held liable for their own reckless actions that cause lost revenue for people like me.

JAXB Custom XJC Plugin Limitations

I recently attempted to write my own JAXB XJC plugin which I thought would solve some schema derived code generation enhancements that I wanted to implement. It turns out Custom XJC Plugins are worthless beyond adding code to already defined generated classes or adding new classes. It turns out plugins are only invoked after the schema has been parsed into a schema model (Outline) and after all the JAXB classes have been generated in memory (CodeModel). While it is possible to remove fields from an existing class and perhaps even remove methods one cannot completely redefine a class because the schema and code models have been finalized by the time the plugin is invoked. Instead of having a plugin that could interact with the models at various phases it seems XJC plugins were an afterthought. Additionally I found the XJC code difficult to decipher albeit mapping one typed language to another one is not easy. I can now clearly see why the JAXB project has bugs that have not been addressed in six years. Beyond generating simply utility methods on generated classes expect no further value from writing an XJC Plugin.

Thursday, March 15, 2012

In Home Private Cloud

I am an IT consultant who works for various clients. One practice I have developed over the years is to create a dedicated VirtualBox virtual machine instance for each client. There are several reasons for this:

  1. I can keep the base OS of my laptop more pristine and reduce the number of applications installed on it by installing all the applications needed for a particular task in the VM.
  2. Most clients provide a remote VPN solution for working remotely and by installing the client on separate VM's I can avoid conflict. For example, if a work for two clients that have different versions of the Juniper SSL VPN I don't have to wait for each client to re-installed when I switch between the two.
  3. I can easily clone the VM and provide it to a colleague who has recently been on boarded to the project allowing them to become productive right away without having to laboriously setup a new environment.
  4. I can tailor the build process and development environment to each specific client without worrying about conflicts. i.e. I have an install of eclipse per VM with the necessary plugins installed for each project.
  5. Once I roll off the project I can archive the VM and then remove from my laptop to clear up space for a new machine.
  6. With VirtualBox I can RDP directly into the VM regardless of OS
#6 is  where the private cloud comes in. I have a heavy desktop replacement laptop that I use that has a horrendous battery life, weighs over 10lbs, and runs very hot. Alternatively, I have an inexpensive Acer netbook that is very light and has a great battery life. By docking my laptop and then connecting to it using RDP over Wi-Fi I get the best of both worlds: the extreme portability of a netbook with the power of a laptop.

I applied this same concept to a virtual machine I am using for an Open Source project. I built an HTPC over the Christmas break that has 8GB of RAM and an AMD FX-4600 processor. I am really surprised that in one room I can watch HDTV and then over WiFi run a large maven build in a VM at blistering speeds on the same machine with no noticeable impact.

I suppose I could migrate all my VM's to a public cloud like EC2. However, my VM's are several GB's and it would take several hours to upload it, not to mention installing any software on it or backing it up locally. I also have to pay for it and I would constantly need to worry about stopping them when I am not using them. Then there is the ambiguous question of software licensing where if I have a license for home use or in my rush accidentally install single use software on multiple VM's I have more legal risk if I export that VM to an external cloud provider than if I run the image at home.

For now I am content with running multiple VM's in my home environment for accessibility and speed.

Saturday, March 10, 2012

Coding as Entertainment

I am really blessed in that I am in a profession where I absolutely love what I do for a living. The old adage "find something you love to do and you'll never have to work a day in your life" is certainly applicable to me. In fact, strange as it sounds I actually find many aspects of my career so enjoyable that in my spare time I perform those activities as a form of entertainment!

 I am an avid video gamer who goes on gaming binges every once in a while playing the same game for hours on end. There are several reasons why I like to play video games, including interacting with intriguing story lines and character evolutions, the thrill of experiencing new environments and situations, and the sense of accomplishment in achieving victories and completing sagas.

Upon further self reflection I learned that I could experience many of those same positive aspects of gaming through Open Source coding. Solving complex design challenges  provides mental exercise and satisfaction. I personally receive a thrill when I successfully integrate multiple software components together to accomplish the implementation of a functional system. As I write the code and the software evolves it is as if it were a novel unfolding before me. A creative canvas that I can test new ideas and theories on resulting in a unique body of work, much more valuable than a list of XBox360 or PS3 achievement medals!

The take away from this is that don't let other people decide for you what is enjoyable or not. Too often there is a stigma attached to intellectual achievement in society which in reality is a petty excuse for mediocrity.  Focus on maintaining a positive attitude that will motivate you to maximize what you are capable of doing.

"Nothing can stop the man with the right mental attitude from achieving his goal; nothing on earth can help the man with the wrong mental attitude." Thomas Jefferson

Giving Back

After all these years of doing Internet searches to find solutions to technical hurdles I have come across I decided that I should finally contribute back with my own approaches to addressing difficult technical challenges.