Nov 08 2009

Eclipse – Ubuntu 9.1 Button Issue…

Category: Eclipse,TestingPhil @ 5:18 pm
This was making me crazy the other night… I did not spend too much time on it, thinking is was just me. But, after upgrading my laptop and encountering the exact same problem, I knew there was more too it. It seemed like only the cancel buttons actually worked; all of the next and finish buttons did absolutely nothing, other then beep!  I soon realized that I could use the tab key and press enter to move to the next screen; but that did not make me very happy.

A quick Google search turned up several people with the same exact problem. It was kind of interesting. The Ubuntu developers did not want to take responsibility for the problem and said it was an Eclipse issue. The Eclipse community said they never had to do anything special for Eclipse to run on Ubuntu; it was looking like a stand off! I did find the official bug report filed with Launchpad.net, it says the problem is resolved. However, without overriding the following variable, Eclipse is not very usable.

export GDK_NATIVE_WINDOWS=1

It also appears that this problem is affecting many other tools on the new 9.1 release as well. This simple fix will get you back into action, without having to wait for the real fix.

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Oct 19 2009

Spring Framework Anti-Patterns

Category: Java,Software Development,TestingPhil @ 4:40 pm

Not that I’m a big fan of the whole “Anti-Pattern” concept, but there is some subtle irony in the title of this post; some of my coworkers will actually understand. Sorry about the mystery for the rest of you, but I think this post is really relevant for those trying to use Spring for the first time. After building my first Spring-based application, I was on the fence concerning Spring’s actual value. Obviously, I made lots of mistakes in my first implementation; I think many of the following anti-patterns can typically happen on your first Spring project; my goal is to make you aware of these pitfalls, such that you can skip past the mistakes made by myself and others.

Interesting Thought Tangent?
While looking for the title to my post, I have found a little snippet that calling “Spring a direct attack on J2EE“. I thought this was a unique way of describing the Spring Framework. For sometime now, I have been on the bandwagon to simplify the development practice through Spring (Spring Core, Security and Remoting). I never really thought about Spring as another religious battle front; such as the classic emacs/vi or mac/pc wars. In essence, I was picking a side: No more J2EE! I guess it was not obvious to me before today, as I really can’t escape the J2EE container; I’m are required to deploy in a J2EE container, even though I make no use of its capabilities; a Servlet container is all most of us really need! Just an interesting thought! Agree or Not?

So where to begin, I guess the first question is: Why do you want to use Spring? What service(s) will it provide for you? I think many developers simply wanted to slam it on their resume! Let’s start with the the most obvious use of Spring, Dependency Injection (WIKI, Fowler). I think this is the hardest thing for most developers to actually understand! If you think you are just writing XML code to create your instances rather than writing Java code, you have already missed the boat. I really believe that most developers have not actually taken advantage of DI in their applications.  They just use Spring to create an alternative static (hard-wired) bean creation strategies. Just for fun, I thought I would highlight some anti-patterns I have seen used before and hopefully never again!

Create a Factory.
Factories are so 1990. This is one hurdle that some developers have a tough time understanding. They continue to think about creating objects via factories. There is NO need to ever create a factory when using Spring. Spring is essentially the a super factory, plus it is actually responsible for the life-cycle of those vended objects. There are scenarios where you need to specifically create objects that Spring manages, in a loop for example; but these are very uncommon. The proper way to solve this problem, is to create a bean that is ApplicationContextAware.  When this bean is created (by Spring itself), Spring will set the application context on this bean. Now, you have the ability to ask for any bean that Spring is managing.
Ask Spring for objects.
This is probably the toughest habit to break and is easiest pattern to get stuck in. This is especially true if you are trying to integrate Spring into an existing project and is your first attempt at Inversion of Control. You will have a much better chance understanding these constructs, if you can start from a clean slate (or at least create a bunch of samples). Spring done right, is truly is a different way of thinking. For example, when working with a context-aware Servlet, you fundamentally NEVER need to ask Spring for a single instance; this is almost a perfect example of IOC and DI.  The whole point of DI is the INJECTION. It is not about ASKING for an instance, it is about being GIVEN an instance;  throw in the IOC principle and your bean will be invoked at the RIGHT time to provide the appropriate behavior.
Domain Object DI.
This was an unusual one for me. I recently observed a project that used Spring to created multiple static Singleton factories to vend out a variety of instances, each factory with it’s own Spring context file. Needless to say, this application was far from easy to understand. To my surprise, there was even a factory specifically implemented for creating the business domain objects. Why this was done is still a mystery to me and seems to violate the true spirit of Spring. Why would I ever want to call DomainFactory.getNewWidget() or DomainFactory.getNewGadget()? The configuration had the domain beans defined in a separate Spring context file and oddly, used static methods to initialize specific properties of these new bean instances. There was no way which enabled the XML configuration to be overridden, allowing for different implementations. Worse yet, you were tied to the initialization behavior of the factory methods! Depending on your definition of a domain object, I see very little reason domain object dependency injection.
Use Ant to create Spring Configurations.
This is an interesting use of Ant in a Spring-based application. The idea here is to generate the Spring configuration and properties file from an Ant task, to specifically configure the context files to each deployment environment. They values are essentially baked into the application and unchangeable.  It is bad enough to substitute property file values, but some developers actually substitute bean name references. This might be a little hard to follow, but the Spring XML configuration would define two different implementations of the same basic function, each with its own name. When the application is built, the Ant tasks would substitute ref=”bean1” for some environments and ref=”bean2” for others; everywhere that implementation was referenced in the configuration files. Call me crazy, but I don’t think this what the Spring creators ever intended!

As I have developed a better understanding of Spring and how to take advantage of it features, we have evolved our Spring applications to a state of “environmental awareness”. Using this solution, all of the context and property files are packaged into the application, for all known environments at build time. This enables us to build the deployment image (jar/war file) one time, using simple Ant tasks, no more templates, no more substitutions, no complexity. At execution time, Spring is now intelligent and can determine it’s execution environment; we can use specific property files for specific environments, as well as use alternate implementations (via DI) for each environment. This is where DI really pays off, allowing us to use the appropriate objects, not just properties, but objects for each environment! No code changes, no crazy Ant tasks, you build once and deploy anywhere. I think this is actually pretty slick and what Spring (core functionality) is all about.

I do have to put in a plug in for testability. Taking advantage of jUnit 4.x annotations and Spring integration, makes unit testing a snap. Using the @Resouce annotation to inject everything (instances) you need into your unit test is amazingly elegant; unit testing could not be made any easier. This approach allows us to have highly controlled, customizable execution environments; we can seamlessly manage unique configurations for local development, continuous integration, as well as any actual deployment environment almost magically.

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Oct 18 2009

Ubuntu 9.10 Upgrade…

Category: UbuntuPhil @ 7:33 am

Apparently, I like to live dangerously; last week I upgraded my Ubuntu box to the 9.10 beta. Unlike my last upgrade, this one went off without a hitch. Not surprisingly, I seem to have 100MB updates every other day, but even so, the box is rock solid. The only annoying thing is that many of the updates make me reboot, I almost feel like I’m running Windows! The list of new features is quite extensive. The most obvious change appears on the initial reboot; the login manager and upgrade to GNOME desktop environment. With every release, the user experience becomes more and more polished.
Throw in Avant Window Manager and Screenlets, and you have a really nice looking, easy to use desktop. Other than doing my checkbook (which some might call old school), I have no need for a commercial OS. Everything I need to do is available, Open Office, GIMP, Empathy, Firefox, etc.  This release included some work around boot performance and changes to the login manager. I didn’t really notice any boot time differences (this might not be obvious on a Quad-core, SATA machine), but the login manager is much nicer. I can see this being a big win for people that share a computer at home and user multiple accounts.

Presumably, in a attempt to create another income stream, Ubuntu created https://one.ubuntu.com, personal storage in the cloud. I have been recommending DropBox to my friends, as it has worked very well for heterogeneous environments, supporting all of the major platforms.

There are numerous technical advancements, but my primary motivation is to have a usable development box, one that delivers me a user experience similar to the expensive options and provides all of tools I need (database, Servlet container, web server, etc).  I have been using the 64-bit version of Ubuntu for over a year, it has never been as “issue free” as the 32-bit version I run on my old laptop. However, it is getting much better. I finally have Flash integrated perfectly, this has been a persistent issue for me… I recently tried to get the new Hulu desktop working, but I think it wanted the real Adobe Flash Player. I had been using one of the alternative, non-Adobe implementations and it was quite flaky and unreliable. I finally did a clean install of the Adobe plug-in and am seeing much better rendering; I have not had success with the Hulu Desktop yet, but Google Analytics, YouTube, Hulu, Pandora, WordPress, all web sites that rely on Flash, work perfectly for me now.

So far so good with my upgrade, I’m much happier with this release. Hopefully, your upgrade is as smooth! WorksWithU was an interesting site I found this morning, it seemed to have a lot of information on the upgrade and Ubuntu in general, give it a look!

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Oct 18 2009

Droid Does…

Category: MiscPhil @ 5:55 am

I like anything that gives Apple a little jab… and am looking forward to Verizon releasing some interesting new phones. Verizon just created a new sub-site, http://www.verizonwireless.com/droid. I think it is actually a pretty good campaign, “iDon’t”. I have been using Windows Mobile for many years, and I will be the first to say that it has be be considered a complete failure; but similar to the old Palm OS, there have always been a multitude of free applications with no Steve restrictions. My primary need for a Windows-based phone was the integration with Outlook, which allowed me to sync my calendar, contacts, email, etc; which did work flawlessly. I have never been into the whole Android thing, as I am no fan of “single” source solutions, such as that iThing. But, now that Verizon and several other carriers are planning to release phones, and even Acer has released a new Android-based netbook, I’m starting to get a little more interested!

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 12 2009

Capturing Values with Java Regular Expression Groups

Category: JavaPhil @ 6:48 pm

For whatever reason, I have been using a lot of Java Regular expressions at work lately; I started taking advantage of the grouping abilities provided by the standard Java Regular Expression implementation. I am certainly no RegEx expert, especial after reading this overview of backreferences and forward references! I use them every so often, probably not as much as I should; I know just enough to be dangerous! With my new exposure to grouping, I will probably use regular expressions much more frequently. Historically, if I needed to split a String into pieces, my goto class was the StringTokenizer. More often than not, I now use the String.split() method; you use create a simple regular expression and the method returns an array of the split values;  It is actually easier to use and handles the case where no matches are discovered fairly well.

If you are going to create and use regular expressions, you are probably going to need to test them. I have been using web-based expression testers for several years; here is one that I use often; Tonight, I found a FireFox plug-in I like ever better!

The point of this post was to show how easy it is to capture data using regular expressions. I created a little class to decode an id and status from a String. As illustrated in this simple example, you can use the Matcher class to do more than simply determine if the regular expression matched. With the addition of round brackets (parentheses) to the regular expression, we can actually capture the matched values in one simple step. This approach can also be used to capture optional values, the id and status, as in the included example. Unlike using a tokenizer or the split method, the Matcher class maintains the expected positions of non-specified, optional values; simply including an empty String for the optional attributes, when they are not provided.  As you can see the following Eclipse debugger screen shot, the groups are easily accessible, even allowing you to build nested groups, as my example demonstrates. You can play with the example or give the Matcher JavaDoc a quick read to learn more about how this class works.

public class StringDecoder {

    private static final Logger LOGGER = LoggerFactory.getLogger(StringDecoder.class);

    private Collection<String>  transactionIdentiferPatterns;

    public class Result {

        private long   transactionId;
        private String status;
        private String filename;

        public long getTransactionId() {
            return transactionId;
        }

        public void setTransactionId(long transactionId) {
            this.transactionId = transactionId;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getFilename() {
            return filename;
        }

        public void setFilename(String filename) {
            this.filename = filename;
        }
    }

    private class Match {

        private String[] group;
        private int      start;
        private int      end;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("Match [end=" + end + ", start=" + start + ", value=");
            String comma = "";
            for (String s : group) {
                sb.append(comma).append(s);
                comma = ",";
            }
            sb.append("]");
            return sb.toString();
        }
    }

    public void setTransactionIdentiferPatterns(final Collection<String> patterns) {
        this.transactionIdentiferPatterns = patterns;
    }

    public Result decode(final String filename) {
        Result rc = null;
        for (final String pattern : transactionIdentiferPatterns) {
            final Match match = find(StringUtils.trim(pattern), filename);
            if (match == null) {
                LOGGER.warn("No match found using pattern [{}]", pattern);
            }
            else {
                LOGGER.info("Mache found {}", match);
                rc = new Result();
                rc.setTransactionId(Long.valueOf(match.group[2]));
                rc.setStatus(match.group[3]);
                rc.setFilename(filename.substring(0, match.start) + filename.substring(match.end));
                return rc;
            }
        }

        return null;

    }

    private Match find(final String patternStr, final String valueStr) {

        final Pattern pattern = Pattern.compile(patternStr);
        final Matcher matcher = pattern.matcher(valueStr);

        if (matcher.find()) {
            final int groupCount = matcher.groupCount();
            final Match match = new Match();

            match.group = new String[groupCount + 1];
            for (int i = 0; i <= groupCount; i++) {
                match.group[i] = matcher.group(i);
                if (i == 0) {
                    match.start = matcher.start();
                    match.end = matcher.end();
                }
            }

            LOGGER.debug("Good {}", match);

            return match;
        }

        return null;

    }

    @Test
    public void simple() {
        Collection<String> patterns = new ArrayList<String>();
        patterns.add("(###OID([0-9]+)([F|S]?)###)");
        this.setTransactionIdentiferPatterns(patterns);

        String name = "SomeStuff###OID122325F###.csv";
        Result result = this.decode(name);

        assertEquals(122325, result.getTransactionId());
        assertEquals("SomeStuff.csv", result.getFilename());
        assertEquals("F", result.getStatus());

    }
}
https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 09 2009

Hudson Task Scanner Plug-in

Category: Continuous Integration,Software DevelopmentPhil @ 8:21 pm

Ok, that is just about enough Hudson for this month, unless I get fired up about Selenium and try out the Hudson integration! I did find one more useful plug-in this week, the Task Scanner.  Because I tend to check in code early and often, my code is typically in an incomplete state; you will tend see a lot of TODO or FIXME comments in the code. Managing these task inside of Eclipse is easy enough, but I thought it might be interesting to also monitor them on Hudson’s dashboard.

The plug-in is very easy to configure and allows you to specify thresholds on the number of open tasks. Like most other plug-ins, it generates configurable trend graphs and provides a convenient task browsing screen.

Here was an interesting blog post that shows how you could use the plug-in to determine how messy your SVN merges will be… kind of cool..

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 08 2009

Continuous Deployment with Hudson…

Since I was looking through the Hudson plug-in list this week, I decided to try a few more of them. We currently have Hudson continuously deploying a simple web application to a Tomcat instance. Since both Hudson and Tomcat are running on the same server, it was pretty simple to have Tomcat point to the WAR file generated during the build process. Tomcat notices the new WAR file and automatically redeploys the application. Pretty simple and pretty handy; this is about a 100 times easier and faster than dealing with our standard Weblogic deployment process!

So, how do you deploy your application if Hudson is running on a different machine than your Tomcat instance? Fortunately, Hudson provides a plug-in to solve this problem, simply named the Deploy Plug-in. It supports a variety of containers, taking advantage of the Cargo Framework. Can’t get much easier than this, just point to your WAR file and fill in the container information. That’s it! I tried it out today and it worked perfectly. This was a much cleaner approach than adding the logic to the build process.

Having the current code set continuously deployed is a great benefit all by itself. This helps ensure that your application is built correctly and is deployable; How many times have you forgot to add that new JAR file to the WAR, only to discover the failure several days later? Continual deployment also makes the application constantly available to the analysis and test teams. This allows everyone to see the current state of development and bounce through the application to see how it will ultimately work. This early exposure also gives developers a change to resolve issues much earlier in the development cycle. We can achieve more value by adding the integration or system testing to the process as well… Just think how much we could reduce our development and testing cycles with this level of testing?

I have been starting to read about Selenium on the Hudson mailing list and found this interesting blog by Ben Rometsch on “Easy Automated Testing with Hudson and Selenium“. I really liked this picture from the article (hopefully it will spark your interest too!) and truly believe this is what we should be working towards… Maybe this can be one of my next educational adventures!!!

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 07 2009

Cleaning out my inbox!!!

Category: Blogging,JavaPhil @ 8:16 pm

I have been so busy with work and life, that my blogging had basically stopped for the summer.  I keep sending myself topics and notes about things that I would like to write about. Unfortunately, I have not had a chance to do anything with them and the topics keep piling up! I was talking with one of my coworkers last month, and he mentioned that he also had a blog. I mailed myself the link to his site, http://blogs.averconsulting.com/, and forgot all about it!

I thought It would be a good idea to share it, since many of my readers are coworkers as well! He has written some good stuff on the Spring Batch Framework,  REST, and Flex.  Please check it out…

Here is a  link to another one of my coworkers blogs… He  like to write about blogging and web security, you might find that interesting too… http://tdot-blog.com/.

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 07 2009

Why would anyone still be using IE6?

Category: Software DevelopmentPhil @ 7:54 pm

I have been working on a web application and was required to make the  work with IE6.  We were doing nothing fancy, but the application had numerous issues rendering in IE6. First, we implemented the presentation using  JSF and Facelets. All of our content was in XHTML documents, which IE6 apparently has no idea how to deal with! After doing some research,  we found a simple solution to the problem;  simply by removing the XML prologue, IE6 could now display the pages. We also had problems with some of the CommandLinks and CommandButtons not posting back to the server, by playing with different tag combinations, we finally got it working all of the browsers. What a pain in the behind!

I just cannot image how anyone could actually still be using IE6… Unfortunately, It is still the corporate standard where I work too. Somehow, I have no idea how, my Internet Explorer magically upgraded itself to IE7 a couple of years ago, and then again to IE8. It is amazing how that happened, and even more amazingly, everything still works fine! How do people surf without tabs? That is the question I really want answered! I really don’t use IE anyway, as the rich supply of plug-ins makes Firefox the best option out there, in my humble opinion.

Anyway, one of my friends forwarded me a couple of posts that I just had to share, the best one being “IE6 must die“! You just really have to love what gets people fired up… People are even spending their time building Javascript libraries and  WordPress plug-ins, to encourage people to upgrade. I found some of these URLs rather funny…

  • http://isie6dead.com/
  • http://idroppedie6.com/
  • http://www.ie6nomore.com/
  • http://ie6update.com/

The most interesting post was about “IE6 Offenders“. I checked out the site, ieoffenders.com, which highlighted organizations that were still using IE6. It reported the number of users and the reason why they had not upgraded. In searching for the site tonight, the guy actually took his site down! I guess the guy must have caught some flack? I actually thought it was quite interesting!

I also like some of the banners, example below, that people are adding to their sites… I found this post tonight, The browser that will not die. It says that Microsoft will support IE6 until at least, 2014! That is amazingly sad!

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


Sep 07 2009

Hudson Plug-in for Custom Documentation, integrating an Ivy Report

Category: Continuous Integration,Software DevelopmentPhil @ 7:14 am

One of the best things about the Hudson Continuous Integration platform, is the amount of activity. People are constantly fixing problems and adding new functionality. I’m sure that some would say this is a bad thing, but even with the frequent releases, it is amazingly stable.

I have been moving projects to the Ivy Dependency Manager for the last couple of years. We have established a multi-repository solution, that allows us to control access to the repositories without impeding the progress of the development teams.  Introducing multiple repositories and transitive dependencies takes a little getting used to, so I have been adding an ivy.report task to each of the project’s build scripts.  Here is an example of Ivy dependency report. I think it is quite handy on multiple levels, but the primary benefit is displaying the dependencies of each component. Side benefits include showing the different types licenses used by each component, kind of nice for corporate environments. The report also shows where the components are resolved from, such as the legacy or sandbox repositories (indicating that you might need to do some promotion or upgrade work before releasing the project).

My problem was, how to tie the Ivy dependency report into my continuous integration process. Building the report was easy, but how could I make it available on the main Hudson project page? Unfortunately, there was no plug-in to make this happen; I was actually thinking about writing my own plug-in this summer, but never quite got around to it (or blogging for that matter!) Fortunately, this appears to have been a common need and someone was nice enough to release a really nice plug-in this past July, called DocLinks. It allows you to add multiple links to items generated by the build process. The process could not be simpler.  The links will automatically show up on your main project page, but will not be active until the next build completes.

This also solved a problem that I have with the Testability Explorer plug-in. I have about a 50% success rate with this plug-in. I am able to generate both the XML and HTML files for all projects without issue, however, the Hudson Plug-in reports nothing for half of the projects; I have yet to figure out the pattern. Anyway, the DocLinks plug-in now lets me add a link to the Testability Explorer HTML report, so that everyone can always see the results, independent of the Hudson integration.

Suggestion!There is one area that the Hudson community could be a little more helpful. The Hudson tool is very good about showing you when updates are available for itself or installed plug-ins. However, there appears to be now good process for discovering new plug-ins. I even follow the Hudson mailing lists, and there are no notices about new or updated components; the only way I know about upgrades is to click the “configure” link every so often, when I actually remember! To find out about new plug-ins is even worse, I have to look at the Plug-in page, and notice if there is something new. There are so many plug-ins now, it is almost impossible to know if something has been added. Hopefully, they will add some kind of search for recently added or updated feature to their page; I’m sure that I’m not the only one that would appreciated it!

https://www.beilers.com/wp-content/plugins/sociofluid/images/digg_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/reddit_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/dzone_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/stumbleupon_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/delicious_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blinklist_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/blogmarks_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/google_48.png https://www.beilers.com/wp-content/plugins/sociofluid/images/facebook_48.png


« Previous PageNext Page »