Tuesday, November 29, 2011

Auto install of Java on Ubuntu

We recently had an issue on our appliances for builds that was causing a problem when it came time to install Java via apt-get on Ubuntu.

Found this gem that should save a lot of time:

sudo sh -c ‘echo sun-java6-jre shared/accepted-sun-dlj-v1-1 select true | /usr/bin/debconf-set-selections’;

sudo apt-get install —yes sun-java6-jre;

http://www.davidpashley.com/blog/debian/java-license

Wednesday, November 9, 2011

Change in 'angular.compile()'

In our app we load in partial GUI's via OSGi bundles that angular then compiles/bootstraps after the pull from the bundle via calls similar to:

$('#eiAuditUI').load(eiAuditURL, function(responseText, textStatus, XMLHttpRequest) {
    if (textStatus == 'error') {
        $('#eiAuditUI').html('Unable to contact the Audit Tool.
');
    } else {
        angular.compile($('#eiAuditUI'))();
    }
});
$('#eiAuditUI').show();

This was with angular up to 0.10.3. As of 0.10.4, needed to apply '$apply()' to the compiled element, since angular.compile does not call $apply on the linked scope.

Being that we are bootstrapping the partial being pulled in itself, we need to now append the calls to compile from:

angular.compile($('#eiAuditUI'))();

to:

angular.compile($('#eiAuditUI'))().$apply();

What this was causing was that when the scope was called/compiled, the rendering didn't happen as was previously, unless some even happened, such as starting to fill out a form or moving a select list.

With the above change - everything back to normal.

Monday, October 10, 2011

angular select list options

Angular allows filling in of selection lists via different data structures, but can be a bit confusing as to how to build them sometimes.

I have had to make certain data structures available as angular services to our developers, making the calls as simple as possible.

Say we have a straight JSON object such as:

{
  "33":"Bed",
  "44":"Call",
  "66":"Emergency"
}

I take this call from an $xhr request:

getDatasets: function(ctrl) {
  $xhr("GET", CURRENT_DATASETS_URL,
    function (code, response) {
      processDatasets(ctrl, code, response);
    },
    function (code, response) {
      processDatasets(ctrl, code, {});
      showError("Unable to load ...");
    }
)};

and inside 'processDatasets()' method - manipulate data structure so turns out such as:

self.datasetsArray = [
  {label:"Bed",value:33},
  {label:"Call",value:44},
  {label:"Emergency",value:66}
]

We can render a select list easily with:

<select name="dataset" ng:model="form.dataset" required 
        ng:options="ds.value as ds.label for ds in datasetsArray">
</select>

Giving us the labels and values needed.

Another challenge for this came up as wanting to utilize groups for values as well. For example, a structure coming in from a service call would come back as:

{
  "MainMenu":  {"Menu Item 1": 5},
  "AlertMenu": {"Alert Item 1": 9, 
                "Alert Item 2": 2, 
                "Alert Item 3": 7, 
                "Alert Item 4": 23
  },
  "TrackMenu": {"Track Item 1": 55, 
                "Track Item 2": 1, 
                "Track Item 3": 8, 
                "Track Item 4": 6, 
                "Track Item 5": 10, 
                "Track Item 6": 3
  }
}

Manipulating this structure in our callback from the service (like above), we create an array such as:

var menuGroups = [
  {group:"MainMenu", label:"Menu Item 1", value:5},
  {group:"AlertMenu", label:"Alert Item 1", value:9},
  {group:"AlertMenu", label:"Alert Item 2", value:2},
  ...
  {group:"TrackMenu", label:"Track Item 1", value:55},
  {group:"TrackMenu", label:"Track Item 1", value:1},
  ...
]

We can now use this to create a select menu with the 'optgroup' already in place:

<select name="menuPage" ng:model="form.menuPage" ng:format="number" required 
        ng:options="mp.value as mp.label group by mp.group for mp in menuGroups">
  <option></option>
</select>

** Updated for changes in form processing with angular 0.10.3+.

Thursday, September 29, 2011

Love of angular

Over the past few months (18+ months now) I have been working on a project that has become pretty involved, being a hybrid Java EE/OSGi app, with a lot of javascript and "trickery" involved.

One of the core goals of this project was to have a central "Core" app that would be the persistence layer, with the ability to create pluggable interfaces that could interact with this layer.

The "Core" layer also houses an Admin Console, which an admin uses to setup and administer these interfaces, so that they can communicate properly.

The legacy app of this involved a combination of Ruby On Rails to house the entire admin console and send information via JMS to the standalone interfaces that were each running in their own space.

When an interface was to be created, that involved not only writing the java code for the interface itself, but much code to be written in the ruby side of the app to support this, including the GUI that would be specific to the interface in question.

With the new architecture, we wanted to make sure that when interfaces are built, that they be completely self contained, so if there were updates needed, only the interface bundle itself would need to be deployed, not any of the surrounding parts.

A huge challenge to me was not only setting up the framework to handle the communications between these interfaces and the core app, but the GUI piece was proving to be an immense challenge.

Then came 'angular'.

I had been following it for a while. One of the guys on my team at Sun (Igor!) had went to work for Google, and I saw this library he was working on - and started messing around with it.

It is an *incredible* library for building client side apps.

Creating a resources bundle that housed the angular library and our custom libraries that the interface bundles could rely on (via manual registration of them via the OSGi HttpService), we were able to make the persistence of the interface data straight JSON objects (which the core app doesn't care about - only cares about saving the data itself), and have that pulled back and manipulated via angular binding.

I will be following up with some of the details of the work that was done, which could be a valuable reference.

I couldn't be happier with how this library has helped in this transition, and made it possible to build the beginnings of a rich SDK for interface developers to use.

Monday, June 20, 2011

@ManagedBean inside OSGi bundle in GlassFish (3.1) - part 2

In previous post talked about utilizing javax.annotation.ManagedBean to create a ManagedBean in an OSGi bundle deployed in GlassFish.

A different (better) route would be to use CDI (Contexts and Dependency Injection) and utilize @Inject annotations instead of @Resource and @EJB for injecting the resources.

For this to work, there must be a 'beans.xml' file present. According to the docs:

An application that uses CDI must have a file named beans.xml. The file can be completely empty (it has content only in certain limited situations), but it must be present.

To make this possible in our bundles, added a 'META-INF' directory to the 'src' dir, with an empty 'beans.xml' file underneath.

Then in our bnd definition file (which builds the OSGi bundle for us), we define the resource to be included in our bundle:

Include-Resource:  META-INF/beans.xml=src/META-INF/beans.xml

With this in place, we no longer need to reference the 'com.sun.ejb.containers, com.sun.ejb.spi.io' libraries in our 'Import-Package' entry (since we are not using the ManagedBean annotation directly).

We can now replace all the @EJB and @Resource calls to @Inject.

@ManagedBean inside OSGi bundle in GlassFish (3.1)

Was struggling getting a @ManagedBean to be able compile correctly under GlassFish - needed to add the following packages to the Import-Package entry of the Manifest:

com.sun.ejb.containers,com.sun.ejb.spi.io

This allowed us to have a ManagedBean in the bundle.

For example - want to have a @Singleton class for some processing.

@Singleton
public class TestSingleton {
    public String testMySingleton() {
        return "This is a test from my singleton!";
    }
}

(this would be a javax.annotation.ManagedBean, not a Faces ManagedBean):

@ManagedBean
public class SingBean {
    @EJB
    private TestSingleton testSingleton;

and for testing purposes - within the MDB:

@MessageDriven(mappedName = "jms/MyQueue", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class ExtIncMDB {
    @Resource
    SingBean myBean;

Coming back...

Haven't written to this blog in a while - getting caught up with getting the project I have been working on working, but with some of the issues we are finding and the solutions to those issues, I really need to document them for future reference.

I have also been getting deeper into iOS and Android development, and have figured out some cool things there to start documenting and keeping around.

So major posts coming regarding Java EE 6/OSGi hybrid apps, iOS and Android development (as well as anything else I want to blab about just to keep record).

If others can find some of the snippets to help like I did searching around - would be great.