Friday, March 4, 2011

Reflections on (Java) reflection - isn't there another way?

In general, I am suspicious when I see much use of reflection - especially when creating objects or accessing fields.  It sure seems that there ought to be a better way with a proper object hierarchy.

In any case, I came across an interesting use case.  In this GUI application, the requirement is to create only one window of any given type.  So the class is passed into a window manager class.  It looks up in its table to see if one has been created and if not, creates one.  It does this by being passed the class of the window to create and uses reflection to instantiate it.

There are a couple valid justifications for this:

  1. you would like the window management encapsulated in one class.  
  2. you would like to not instantiate one if one already exists.  Using reflection enables this without having to resort to multiple method calls (although it wouldn't be the end of the world).

The other option would be for every window class to implement a singleton pattern.

Isn't there another way?

In fact, the benefits of Scala come to mind.  All you would need is to pass a bit of code to the window manager which it would execute to create the window in lieu of finding the constructor from reflection on the class definition.

Or, in JDK 7 terms, pass in a closure (from what I've heard of the various proposals).

One could also emulate this with a one-method interface.  Having written all this, it seems it might be useful for each window to implement a singleton pattern, especially if there are various places where the window is being created.  But, that might be a bad sign in its own right.

BTW - why do I not like reflection?  Primarily because I tend to use the "Find References" feature of my IDE-of-the-project.  And it doesn't catch uses of reflection.  (N.B. does FindBugs?)

Of JTables and ScrollPanes

While working on a Swing app today, I came across some interesting code where a class named RowHeader extended JTable.  WTF? In looking at it more closely, it seemed - aha! - they're creating a table to serve as the row header in the JScrollPane.  Makes sense - that way when the table is the viewport of the scroll pane, the column headers don't scroll with the table... just what you want.  I need to do that everywhere.
But wait - it already does that.  How do it know?  My tables don't do that, yet the scroll pane knows to put the row header outside the scroll view port.  Even the simple example here doesn't do anything special to accomplish this task.  I browsed through a bit of the source code to JScrollPane, it must be looking for a JTable instance, but I don't see where right off hand.
So I suspect this is relatively new functionality and the "legacy" code was doing the same thing before Swing did it automatically.

Now, to just get the sorting to show...

Thursday, August 19, 2010

GUI Development


A review of implementation and deployment strategies for GUI applications

The overall GUI implementation space:






Desktop
  1. more secure due to limited access, not using well-known ports
  2. easier implementation of advanced UI interactivity features
  3. requires installation (unless using WebStart; see below)
  4. possible to distribute load: business logic components run locally, no web browser required (see architecture drawings)
  5. more control over context (i.e. no browser compatibility issues, no platform issues if Windows-only)
  6. implementation platforms:
  1. Sun/Oracle Java Virtual Machine (JVM) based
  1. Java/Swing
  2. Scala/Swing
  3. JavaFX (Sun/Oracle alternative to Flex)
  4. Groovy/Griffon/Swing (Rails-like framework for Swing)
  1. Microsoft .Net-based: any CLI language
  2. Adobe AIR-based: Flash or Flex
(Visual issues between these are addressed below.)
Non-browser based Web App (Java Web Start)
  1. requires web server for initial installation
  2. subsequent executions local
  3. crosses lines between Applet (in-browser app) and Application (desktop)
  4. implementation is Swing or JavaFX
  5. full interactivity as in desktop app
  6. could use heavy-weight client to integrate portions of backend
  7. use light-weight client calling a higher-level API on web server
  8. Ref: http://www.oracle.com/technetwork/java/javase/architecture-138566.html
Browser-based Web App - with Plugin
  1. offers rich interactivity, near desktop
  2. avoids browser issues
  3. requires web server for download
  4. could distribute load by running business logic in client (JVM plugin), or use higher-level API on web server
  5. implementation platforms:
  1. Microsoft Silverlight: zillions of CLI languages
  2. Adobe Flash: Flash or Flex
  3. JVM: any jvm language supporting Swing
Browser-based Web App - no plugin
  1. generally less rich interactivity
  2. AJAX for partial updating
  3. Comet for server-push
Web App, no plugin - JVM-generation of pages
  1. requires app server with business-logic code
  2. relying on framework provided client-side interaction (JavaScript)
  3. implementation platforms:
  1. Java/JSP (Struts, etc.)
  2. Java/JSF
  3. Scala/Lift - what we have now
  4. Scala/Other (See Appendix A)
Browser-based Web App - no plugin, “stand alone” pages
  1. requires web server supporting a high-level API (e.g. a REST API)
  2. requires larger code base in JavaScript, either:
  1. hand coded: optionally with framework such as jQuery and its plugin family
  2. generated: as in via Google Web Toolkit (GWT) Code in Java, compile to JavaScript
Visual Issues
Desktop
  1. JVM - Swing: traditional ‘native’ widget/form applications with roughly the same appearance
  2. JVM - JavaFX: much more graphic design
  3. .Net - native Windows L&F
  4. AIR - Flash or Flex components
Web Apps with plugins essentially look like desktop apps
Web Apps - without plugins
  1. jQuery - http://plugins.jquery.com/
  2. GWT: http://advanced-gwt.sourceforge.net/demo/index.html and http://code.google.com/apis/visualization/documentation/gallery/gauge.html
  3. HTML5: http://html5gallery.com/ [N.B. there browser issues here - as in partial I.E. support]
Alternative Dimensions
App server vs. web server
The top, left box is a more traditional Swing application.  The web server would not be an app server, meaning it would not need to run a JVM.  It exists primarily to deliver the applet and its jar files.


App server with page generator (like JSP or equivalent)
In this scenario, the web pages are generated from templates and values are filled in by querying the backend business logic at page generation time.  The JavaScript code in the page manages the AJAX calls to update the pages.
App server with no web framework
In this scenario, the web pages are not generated from templates and in that sense are ‘static’. The page values are filled in by querying the backend business logic at page rendering time.  The JavaScript code in the page manages the AJAX calls to update the pages, but the knowledge of the page structure is not known by the server.  All clients use a “simplified” API such as the REST API outlined below.  No internals of the back-end system are exposed, just the data model.


Conclusions and recommendations
The app server with no web framework is clearly the most flexible architecture.  The API is simple and a variety of clients support it.  For that reason, many applications are moving to this type of implementation.  This architecture achieves greater separation of concerns in that the server has no knowledge of the client.  It is straightforward to implement the server-side and requires much less code, therefore putting less load on its host.  This architecture does not limit the client-side implementation, although it may require a team member who knows JavaScript.

None of these solutions are an order of magnitude better or worse than any other.  Any of the outlined implementation plans could work.  Each optimizes a different combination of platform support, skills usage, visual and design sophistication, etc.
Misc Issues
Authentication
To accomplish userid and password authentication in a REST-world, you would pass userid and password via an https request to an API which would validate them and return an authorization token for future API calls.
Appendix A. - Scala Web Frameworks
Lift has been under development since 2007 (http://liftweb.net/team.html) and is used by such large sites as foursquare.com (http://www.scala-lang.org/node/5130)
Cons: mentioned above
Pros: provided support for Ajax, Comet, client-side graphs (Flot)

SSP (Scala Server Pages):
More basic framework; may avoid server-side memory issues, would have to roll our own support for Ajax, Comet.
Pinky: REST/MVC glue web framework built on top of Guice and Guice Servlet 2.0.

Appendix B - REST API
A REST-notation API passes all arguments in a URL call over HTTP.  The result is returned generally in XML or JavaScript Object Notation (JSON).  A domain model which is hierarchic is easily supported and mapped to a set of URL calls.
Additional Background Notes:
Scala has been under development and in use since 2001 (http://www.scala-lang.org/node/25)

REST and JSON is an evolving area of development.. c.f. http://asserttrue.blogspot.com/2010/08/jsop-idea-whose-time-has-come.html

Friday, December 25, 2009

Google Data API, Google App Engine and Scala/Lift

Recently I decided to bite off this chunk of coding. What followed really emphasized and reinforced the title of this blog. It was quite frustrating at times, frequently interesting and in the end, rewarding. I did finally get most everything to work, so here are my notes...

The objective of the particular web site I did was to have the user enter a handful of values via the web page, run a model calculation based on those values and display the results. Prior to my involvement, my colleague had done all the modeling in Excel and VB. His next step was to export the data to XML files and re-code the calculations in Java.

My first step was to make the site run with Scala and Lift and let the Java code read the XML files. No problem.

Step 2: host the app somewhere. I had read a lot about Google App Engine (GAE) and knew people who had good luck with it. Great idea.

First roadblock: I had read GAE doesn't support static data files, but that's no problem there's the GData API, and all these XML files came from spreadsheets anyway, so how hard could it be?

First sidetrack: instead of reading static files and short of migrating to the GData API, it seemed I should be able to read XML files from the Jar files: ClassLoader.getResource("xmlfile_name"). I spent many hours and never did get this to work!

At this point it became clear - the GAE support for Java seems to be WAY behind the Python support/documentation/functionality/etc.

GoogleData API
It seems there are several variations on this, but the REST API model seems to be quite adequate. There are however a handful of glitchs/gotchas it seems.

1) I created a user which had only view authority on a spreadsheet. Unfortunately, it could *not* read that spreadsheet with the REST api.
2) Everything comes back as a string. This is not too bad, but it seems a more "robust" API would provide a bit more flexibility.
3) The column headings are used as the key to a map of the values in each row. This is a decent strategy, however I would like access to the actual value in the header, not the munged value used in the key. Again, not a complete deal-killer.

Google App Engine
I did get everything running just fine with the Gdata api within those constraints. Now it was time to deploy. I had read several people deployed with no problem and sure enough, there are a handful of apps running with Scala/Lift.

Would mine deploy? Of course not. It generated a couple stack traces indicating problems in the LiftFilter, but seemingly in the configuration of the logging. Might that be just a 'warning'? You would think so, but NO. What the heck? Well, 5 combo boxes aren't that big a deal, so I rewrote them in JSPs and it deployed just fine. As always, appetite grows while dining and the client wanted the drop downs to repopulate based on certain selections. No problem - but wait! That was why I wanted to use Lift in the first place! Ack. The long and the short of it was all I had to do was get a more recent version of Lift (specifically 1.1-SNAPSHOT), and it deployed just fine!

Miscellaneous Glitches
Because it is a proprietary application, I set the security of the main site to be limited to the registered users of a domain I had authorized in Google Apps. This works quite well - the user is redirected to a login page, then to the web site. Cool. Now I added a page to allow an admin user to reload the app. The documentation describes a really easy way to do that. The fine print I didn't digest the first time around is that the members in the admin role are those users defined as admins of the application. Oops. I'm the admin of the application and I created it from my main Google account which is NOT in the aforementioned domain. Oh, I can add admins, so email has been sent inviting another user I created in that domain. Now, where did that email go?

Pleasant Surprise
All the while I was developing the app, I was wondering about releasing new versions after it was in production. I only uploaded code a couple times before I encountered the concept that GAE has the idea of versions of your application. Several versions can be stored on the server and run independently and simultaneously! Well done, GOOG.

Bottom line: Google App Engine and GData API are a good way to go. Better if you're using Python, which is not a bad choice. I just have a lot of legacy Java code, so I'm really liking Scala and Lift. Now I know, those are GAE-compatible also, so life is good.

Wednesday, November 4, 2009

Another Reason to look at Scala for GUI

It's just a simple thing - a form GUI to edit domain objects stored in XML. We even have a schema to describe those docs pretty well. Certain tags have one of a pre-defined list of values ("restriction" in XML schema terms). To edit this, a drop-down list is a very handy thing. How would you populate that? Well an enum sure looks like an attractive thing and these days in Java, enums have come a long way so that you can give the enum a handful of properties.

So I copied each set of restricted values out of the XSD file into a Java file and created enums - dandy! The first small problem we created for ourselves is that the restricted values have dashes. Gosh, as enum identifiers dashes look a whole lot like minus signs. So now I have to map the XML value to the enum value somehow.



enum SensorType {
accelerator,
altimeter
}

But it's very easy to populate the combo box:



inputSensorCombo.setModel(new DefaultComboBoxModel(SensorType.values()));


So I have to add the mapper, but while I'm at it I would like to have a different
display value in the combo box that has blanks!


Still not a big problem - create the enum class with a display value and XML tag value:



enum SensorType {
accelerator("Accelerator", "accelerator"),
altimiter("Altimiter", "altimiter");
final String displayValue;
final String xmlTagValue;
SensorType(String displayValue, String xmlTagValue) {
this.displayValue = displayValue;
this.xmlTagValue = xmlTagValue
}
@Override
public String toString() {
return displayValue;
}
}



With the toString override, populating the combo box is still the same. Pretty good, yeah? Now, I have about 4 of those. We're OO so just make a base class, right? Sorry. As 'syntactic sugar' enum already extends Enum, so we're SOL.



Bummer. Let's try Scala.... next post.

Tuesday, August 11, 2009

Do developers know branding?

I think we learn branding or marketing "spin" at an early age. Here's an amusing post in Toni Epple's blog showing he clearly has: "122 Platform Exercises New & Free - First-come, first-served!"

Saturday, May 23, 2009

The evolution of SCM or Why I would like any teams I'm on to use Git

Back in the olden days of Source Code Management (SCM) there was SCCS and the original Unix things. These depended on developers checking out code with a LOCK. Because, after all, if you didn't have a lock and you changed things, badness would follow.

Well, then along came CVS and out went the idea of locking. Why? Merging became easy - in fact CVS would do it for you. Ok sure, sometimes there are conflicts and you have to merge yourself... but in fact, this is rare (at least for small to medium teams I've been on).

So then we upgraded to Subversion - not really substantially different than CVS - still lock-free central repository.

In this world (at least on the projects I've been on) you always check in against the trunk - i.e. the main line of code. Branching the code is still icky and to be avoided.

Now, along comes Git. (N.B. this discussion may apply to Mercurial also, i have no experience with that, but I know it's popular in many Java (i.e. Snoracle) circles). I don't have tons of experience with Git yet, and I may have forgotten the wonderful things the guys from Everlater.com came over to @iVolunteer to teach us (http://tr.im/gitevrl8r) - BUT I'm convinced of the Git-goodness!

There are two basic revolutionary aspects to it, from what I can tell:
1) no central repository. In some sense you use convention over configuration to determine who has the "central repository". Yes, you need to take backups somewhere. Yes, you need to figure out which repository to check out from for doing a build. However, the good news is that this can be *anybody* "in the network". Because everybody has a copy of the whole history (more or less), *anybody* can do the build.
2) local repository. This means several things, not the least of which is that if you're developing code you can check in locally and not break the build. How does that work? You have the whole repository. But what about everybody else's code? You have all the history you've requested from them. If you haven't "pulled" from their local repository, yes, you're hosed. So pull it and then do a build. Or have them pull from you and do a build - it just doesn't matter - and that's the beauty of it. So just as CVS got rid of the notion of merging being hard, Git gets rid of the notion that branching is hard.

Variations on a theme:
- sure, it's nice to have a publicly accessible, backed up, repository. That's where Github comes in (and presumably whereever you want to install the equivalent. But wait, doesn't that make it just like SVN? Well, ok - yes, to some degree.
- there is much finer granularity of changes. because you can check in locally, and then I can pull from you, I can't get changes from someone that I might want to integrate with before (possilby) screwing up the whole thing.
- and even finer, (this may be a GitX thing) you can check in just *some* changes to a file. I had occasion where I changed a properties file (IIRC) and wanted to check in the new properties, but NOT the hard coded path to my specific files. I checked in just some of the changes to the file - sweet.

now back to figuring out how to update and check in...