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...
Saturday, May 23, 2009
Monday, April 13, 2009
It's TOO great a time to be a geek!
... especially if you can't decide what to do first. I was about to Tweet:
Last time I whined about that or similar, the reply I got (you know who you are!) was why not do one (write a client) yourself? OK, OK - i will. But that's the problem: I'm taking the Stanford class on iPhone development (http://www.stanford.edu/class/cs193p/cgi-bin/index.php), where a big homework assignment is to write a Twitter client, but that's 4 weeks starting 4/20.
But, wait - Dave Briccetti published a cool sample app showing how to do this in Scala (http://briccetti.blogspot.com/2009/03/simple-twitter-client-bay-area-scala.html)
And of course, there's the JavaFX version - TwitterFX (http://kenai.com/projects/twitterfx)
But that's after the iVolunteer project I signed up to help, and my day job!
Bottom line: Less Twitter *reading* and more Twitter *doing*!
STILL looking 4 desktop or web client that shows msg thread: TweetDeck- click on "in reply to" Nambu shows *future* replies. Huh?
Last time I whined about that or similar, the reply I got (you know who you are!) was why not do one (write a client) yourself? OK, OK - i will. But that's the problem: I'm taking the Stanford class on iPhone development (http://www.stanford.edu/class/cs193p/cgi-bin/index.php), where a big homework assignment is to write a Twitter client, but that's 4 weeks starting 4/20.
But, wait - Dave Briccetti published a cool sample app showing how to do this in Scala (http://briccetti.blogspot.com/2009/03/simple-twitter-client-bay-area-scala.html)
And of course, there's the JavaFX version - TwitterFX (http://kenai.com/projects/twitterfx)
But that's after the iVolunteer project I signed up to help, and my day job!
Bottom line: Less Twitter *reading* and more Twitter *doing*!
Tuesday, January 27, 2009
Java WebStart success?
Just maybe, I'm on the verge of success gaining the Holy Grail: automatic continuous integration of a Java WebStart application! What are the pieces?
Ant and Maven
I like Maven for the convention it brings (as in Convention over Configuration). The repositories and versioning of dependencies are wonderful. The bad news is that a WebStart application isn't the traditional JAR or WAR build that Maven knows about. (N.B. - I may come back to this, since using the JNLP servlet, it *could* be a WAR file.) The good news would seem to be that of course, there a couple plugins that do neat WebStart things - including building the JNLP file from the dependencies. You know, DRY! The first one from CodeCrate offers great promise - handle the simple case! Cool. Well, it's a fail straightaway since it can't seem to find the dependencies at all and gets a ClassNotFoundExeception. Bummer. So I go for the full Monty - Maven Webstart Plugin . There's a "cookbook recipe" which shows a "Getting started" page. But no examples for the simple case - they go straight to WAR bundles. :( And the Maven jar signing plugin will only sign the main artifact - not all the dependencies. Double fail.
Ant to the rescue! Fortunately, Ant knows how to sign jars and Hudson will run multiple steps in the build, so it is easy to mix Ant and Maven. Ant will sign the dependency jars and Maven will build the rest of the project. The only loss is not generating the JNLP from the dependencies.
Artifactory, Hudson and Jetty
Both of these are handy web-based tools. Each is easy to install and configure - UNLESS you want password protection. My first thought is to bundle both into a Tomcat instance. Should be easy enough - both give instructions on that. Password protecting Tomcat sites should be easy enough. OK, start with Artifactory. Endless headaches, fails, NullPointerException, etc. Finally come across a suggestion to never use pre-installed Tomcat instances on Linux boxes. Oh! OK - download and install Tomcat 6.0.18 - works great! The password protection works. Now, just have to add the Hudson webapp. FAIL - OutOfMemoryError out the gazoo. Having used Jetty before with good success, I revert to separate Jetty installations - one for Artifactory, one for Hudson. Even with password protection!
JNLP Servlet
Providing links to a JNLP file and having it link all its resources works fine. Just one problem: the JNLP has the codebase in it, so at build/deploy time you have to know where you're deploying to. A bit of a problem if you want to build and deploy to a test server, then promote to production. But wait, the JNLP Servlet to the rescue: it filters the JNLP and drops in the proper codebase for you. Nice! Now let's see - where's the JNLP servlet?
The JnlpDownloadServeltGuide from the Sun JavaSE 6 TechNotes says: "The servlet is packaged into the jnlp-servlet.jar file, which can be found in the SDK under
Nothing. Hmm... Oh, update 11 is out - let's download that. And there's a nice document in the Java Web Start Reference pages called "Packaging JNLP Applications in a Web Archive" - sweet. That's interesting, there's a "sample" directory in this JDK. Oh, even a "jnlp" directory under that. Cool - cooking with gas now. Follow all the instructions about deploying, etc. FAIL - java.lang.ClassNotFoundException: com.sun.javaws.servlet.JnlpDownloadServlet
WTF?
jar -tvf WEB-INF/lib/jnlp-servlet.jar
Oh look! All of them are "jnlp.sample" package, not "com.sun.javaws"! Thanks a lot. So change the servlet definition in the web.xml. Finally - success!
The only remaining piece is to have Maven or Ant copy the proper files to the Jetty webapp directory. How hard can that be?
- Maven and Ant
- Artifactory
- Hudson
- Jetty
- JNLP servlet
Ant and Maven
I like Maven for the convention it brings (as in Convention over Configuration). The repositories and versioning of dependencies are wonderful. The bad news is that a WebStart application isn't the traditional JAR or WAR build that Maven knows about. (N.B. - I may come back to this, since using the JNLP servlet, it *could* be a WAR file.) The good news would seem to be that of course, there a couple plugins that do neat WebStart things - including building the JNLP file from the dependencies. You know, DRY! The first one from CodeCrate offers great promise - handle the simple case! Cool. Well, it's a fail straightaway since it can't seem to find the dependencies at all and gets a ClassNotFoundExeception. Bummer. So I go for the full Monty - Maven Webstart Plugin . There's a "cookbook recipe" which shows a "Getting started" page. But no examples for the simple case - they go straight to WAR bundles. :( And the Maven jar signing plugin will only sign the main artifact - not all the dependencies. Double fail.
Ant to the rescue! Fortunately, Ant knows how to sign jars and Hudson will run multiple steps in the build, so it is easy to mix Ant and Maven. Ant will sign the dependency jars and Maven will build the rest of the project. The only loss is not generating the JNLP from the dependencies.
Artifactory, Hudson and Jetty
Both of these are handy web-based tools. Each is easy to install and configure - UNLESS you want password protection. My first thought is to bundle both into a Tomcat instance. Should be easy enough - both give instructions on that. Password protecting Tomcat sites should be easy enough. OK, start with Artifactory. Endless headaches, fails, NullPointerException, etc. Finally come across a suggestion to never use pre-installed Tomcat instances on Linux boxes. Oh! OK - download and install Tomcat 6.0.18 - works great! The password protection works. Now, just have to add the Hudson webapp. FAIL - OutOfMemoryError out the gazoo. Having used Jetty before with good success, I revert to separate Jetty installations - one for Artifactory, one for Hudson. Even with password protection!
JNLP Servlet
Providing links to a JNLP file and having it link all its resources works fine. Just one problem: the JNLP has the codebase in it, so at build/deploy time you have to know where you're deploying to. A bit of a problem if you want to build and deploy to a test server, then promote to production. But wait, the JNLP Servlet to the rescue: it filters the JNLP and drops in the proper codebase for you. Nice! Now let's see - where's the JNLP servlet?
The JnlpDownloadServeltGuide from the Sun JavaSE 6 TechNotes says: "The servlet is packaged into the jnlp-servlet.jar file, which can be found in the SDK under
samples/jnlp/servlet/"
OK - I've got lots of JDK/JRE installations.find /usr/java -name samples
Nothing. Hmm... Oh, update 11 is out - let's download that. And there's a nice document in the Java Web Start Reference pages called "Packaging JNLP Applications in a Web Archive" - sweet. That's interesting, there's a "sample" directory in this JDK. Oh, even a "jnlp" directory under that. Cool - cooking with gas now. Follow all the instructions about deploying, etc. FAIL - java.lang.ClassNotFoundException: com.sun.javaws.servlet.JnlpDownloadServlet
WTF?
jar -tvf WEB-INF/lib/jnlp-servlet.jar
Oh look! All of them are "jnlp.sample" package, not "com.sun.javaws"! Thanks a lot. So change the servlet definition in the web.xml. Finally - success!
The only remaining piece is to have Maven or Ant copy the proper files to the Jetty webapp directory. How hard can that be?
Tuesday, November 11, 2008
Why Swing UIs are so hard...
I'll tell you why - ok, well at least with issue I'm having now, which seems to be a common issue - LAYOUT.
How do you nicely lay out components? I've been reasonably happy with the layout tools NetBeans puts in for you. But I have a main window with 9 sub-panels, almost like portlets. Not all are the same size - and I want to have the user re-size them. Splitters? No, not the JSplitPane - too much overhead, can only split 2 sides. Enter the MultiSplitPane from SwingLabs - quite nice! An arbitrary grid layout even with custom split bars. BUT - how to specify a nice division. Well it provides "weight" - that's where the extra space goes. But what about the initial size? It uses each component's "preferred size" - seems like a good idea. But how do the components set their preferred size? This gets to the basic issue:
Layout - Bottom up or top down?
I attempted to have a component (tree control) set its preferred size based on the text and font it is assigned. Seems like a fine idea with good control, precision, etc. Nope! NullPointerException - the graphics aren't assigned at constructor time. Put in nice code:
String name = net.name;
FontRenderContext frc = ((Graphics2D)this.getGraphics()).getFontRenderContext();
TextLayout tl = new TextLayout(name, networkTree.getFont(), frc);
setPreferredSize(new Dimension((int)(tl.getBounds().getWidth()*1.5), 0));
NullPointerException at the line with getGraphics.
Top down...
Seems like Swing should learn from HTML/CSS - why can't a table support column widths in percentages? Seems like a simple enough thing - so I'm off to try banging that into MultiSplitPane.
How do you nicely lay out components? I've been reasonably happy with the layout tools NetBeans puts in for you. But I have a main window with 9 sub-panels, almost like portlets. Not all are the same size - and I want to have the user re-size them. Splitters? No, not the JSplitPane - too much overhead, can only split 2 sides. Enter the MultiSplitPane from SwingLabs - quite nice! An arbitrary grid layout even with custom split bars. BUT - how to specify a nice division. Well it provides "weight" - that's where the extra space goes. But what about the initial size? It uses each component's "preferred size" - seems like a good idea. But how do the components set their preferred size? This gets to the basic issue:
Layout - Bottom up or top down?
I attempted to have a component (tree control) set its preferred size based on the text and font it is assigned. Seems like a fine idea with good control, precision, etc. Nope! NullPointerException - the graphics aren't assigned at constructor time. Put in nice code:
String name = net.name;
FontRenderContext frc = ((Graphics2D)this.getGraphics()).getFontRenderContext();
TextLayout tl = new TextLayout(name, networkTree.getFont(), frc);
setPreferredSize(new Dimension((int)(tl.getBounds().getWidth()*1.5), 0));
NullPointerException at the line with getGraphics.
Top down...
Seems like Swing should learn from HTML/CSS - why can't a table support column widths in percentages? Seems like a simple enough thing - so I'm off to try banging that into MultiSplitPane.
Thursday, October 9, 2008
Better Swing through dynamic JVM languages...
The holy grail (?) - applying lessons learned in Web App development to Swing/desktop development. We have Python, Ruby, Groovy and now Scala on the JVM. Shouldn't they bring something to the party in terms of making my life easier to make Swing apps - which is still very tedious.
A couple good news items on this front-
Griffon for Groovy - This project shows some great promise! I hadn't been a big Groovy fan mostly because if it looks so much like Java, why not use Java? But then I realize a large impediment to starting up with Python or Ruby or Scala is the learning curve. On closer examination, it seems perhaps Groovy gets the benefits of a dynamic language while still in the overall "framework" of Java. That would be nice. One might say, 'but without the "buzz" it won't get the vast libraries of Python' - true, except for the extent to which it can just use the vast array of Java libraries. Is there an impedance mismatch? Don't know.
Monkeybars for JRuby - I just came across this project yesterday. (See http://groups.google.com/group/monkeybars) It seems to have a lot of the right objectives. The interesting thing is that there is no Ruby API for Swing components - you do the actual Swing components in a Java class and the Ruby code introspects the bytecode to manipulate stuff. Well, plausible I guess.
But interestingly, I've still not come across any Python-Swing or Scala-Swing toolkit/frameworks.
A couple good news items on this front-
Griffon for Groovy - This project shows some great promise! I hadn't been a big Groovy fan mostly because if it looks so much like Java, why not use Java? But then I realize a large impediment to starting up with Python or Ruby or Scala is the learning curve. On closer examination, it seems perhaps Groovy gets the benefits of a dynamic language while still in the overall "framework" of Java. That would be nice. One might say, 'but without the "buzz" it won't get the vast libraries of Python' - true, except for the extent to which it can just use the vast array of Java libraries. Is there an impedance mismatch? Don't know.
Monkeybars for JRuby - I just came across this project yesterday. (See http://groups.google.com/group/monkeybars) It seems to have a lot of the right objectives. The interesting thing is that there is no Ruby API for Swing components - you do the actual Swing components in a Java class and the Ruby code introspects the bytecode to manipulate stuff. Well, plausible I guess.
But interestingly, I've still not come across any Python-Swing or Scala-Swing toolkit/frameworks.
Singletons gone bad - again
I've been successful at using the swing framework, org.jdesktop.application classes in particular. I have a handful of applications sharing a rather large code base. Now however, of course we want to launch application B from application A. It actually works, but the problem is now that the Application singleton became B instead of A and when the objects in the A application go to use their resource map or action map, the get application B which of course isn't an A, so ClassCastException results. Ugh.
Option A: don't use ResourceMap and ActionMap.
I've already headed in this direction because of NetBeans' issues around keeping track of which class is the true application when it is generating code - so that wouldn't be all bad.
Option B: create one master application perhaps deriving from a new class MultipleFrameApplication extended from SingleFrameApplication. It would know how to create a new JFrame, etc. Arguments could be passed in to specify which "real" application to run - which in this case would mean which view to show first.
Option C: pass application A to the new view for application B. But somewhere we need a new JFrame, etc.
I have a related issue in that my model and helper (controller?) classes have common base classes and the models are singletons. So when application B launches, I'm not sure I want a whole new B model which would replicate the base classes of model A.
Hmm...
Option A: don't use ResourceMap and ActionMap.
I've already headed in this direction because of NetBeans' issues around keeping track of which class is the true application when it is generating code - so that wouldn't be all bad.
Option B: create one master application perhaps deriving from a new class MultipleFrameApplication extended from SingleFrameApplication. It would know how to create a new JFrame, etc. Arguments could be passed in to specify which "real" application to run - which in this case would mean which view to show first.
Option C: pass application A to the new view for application B. But somewhere we need a new JFrame, etc.
I have a related issue in that my model and helper (controller?) classes have common base classes and the models are singletons. So when application B launches, I'm not sure I want a whole new B model which would replicate the base classes of model A.
Hmm...
Tuesday, May 6, 2008
NetBeans (6.1) lost my code!
Things were going so well... I had created a Java Desktop application, got a desktop pane going, a dialog and an internal pane. It was now time to take a step back, refactor a little and etc.
I renamed my project, created a project group and BOOM! No more code. After a day or so reading about various frameworks, etc. and figuring out NetBeans 6.1 I got the program running in about an afternoon. Now I have nothing.
And now I have to Join Netbeans.org to post a message about this. Forget about it! My joining wiki.netbeans.org apparently wasn't good enough. My subscription to nbannounce was not good enough. FUGGET ABOUTIT!
The GUI builder was fairly good - but I'm going back to IntelliJ.
I renamed my project, created a project group and BOOM! No more code. After a day or so reading about various frameworks, etc. and figuring out NetBeans 6.1 I got the program running in about an afternoon. Now I have nothing.
And now I have to Join Netbeans.org to post a message about this. Forget about it! My joining wiki.netbeans.org apparently wasn't good enough. My subscription to nbannounce was not good enough. FUGGET ABOUTIT!
The GUI builder was fairly good - but I'm going back to IntelliJ.
Subscribe to:
Posts (Atom)