Blog

Continuous Integration

  • Continuous Delivery (or putting agility back into SOA) by Matt Wright
    in OSB, SOA, BPEL, Continuous Integration
    11 Aug 2011  | 1 Comment

    One of the key principles of SOA is that systems are no longer built to last, but rather built to change. 

    The promise being, that if you follow SOA principals, it will not only enable you to more rapidly implement new solutions through re-using existing functionality, but also reduce the time it takes to modify and adapt existing SOA based solutions in response to ever changing business requirements. 

    Being able to adapt to changing business requirements is not only important once a system has gone live but is equally important during development. Too often projects experience significant delays due to changes during implementation; a SOA-based approach provides a way to manage this change and help mitigate the risk of project delayed due to change.

    Yet, the reality is often different. Often we come across projects that are struggling to get from development into System and Integration Testing (SIT), or beyond SIT into production.

    As Jez Humble puts it in his book Continuous Delivery

    the most important problem that we face a software professionals is this: if somebody thinks of a good idea, how do we deliver it to users as quickly as possible?

    Now if we follow SOA principles, then the design and implementation (i.e. writing code) should be optimized, however what SOA doesn't address is how we build, deploy, test and finally released that code into production. 

    And this seems to be an area that has been largely ignored by the vast majority of SOA projects, which are still following a manual, resource intensive and highly error prone process that requires someone to piece together all the relevant components, compile and package them before deploying the end result into a test environment; and then run a series of tests to validate the build. Once over this hurdle the next step is to deploy, configure and test the build in each environment that it must progress through before it reaches production.

    We’re not making this statement likely; at Rubicon Red we have had the privilege of working with over 100 Oracle SOA success stories, including helping to rescue many failing projects. This gives us a pretty big sample in which to gauge the overall level of maturity in the industry when implementing SOA projects. 

    In addition, we have recently run a series of workshops entitled “Breaking through the SOA Glass Ceiling” (we are planning another series so let us know if you are interested in attending). One of the biggest issues that customers were facing was the complexity of deploying a new release into production (another being to successfully manage and monitor a solution once in production).

    At the core of the issue, was the resource intensive nature of building and testing software, meaning this tended to be carried out infrequently, so often developers would work in isolation for days, weeks (or even months) before integrating different components. 

    The result? 

    Code shared between multiple people and frequent changes often introduce a lot of integration complications, dependency bugs etc. The longer these bugs remain undiscovered, the more effort it takes to troubleshoot and fix, resulting in significant project delays.

    Yet, continuous integration and testing (the first part of continuous delivery) has shown to reduce  the risk of project delays, providing better visibility into the overall progress and state of the software development, as well as less issues once deployed into production.

    It has also been shown to provide a significant return on investment, due to the impact of finding and fixing integration bugs early in the development process; which saves both time and money over the lifespan of a project.

    It is precisely for these reasons that continuous integration and testing as a practice is being widely adopted within the software industry; so you would expect that with SOA which is all about integration to be at the front of the queue!

    Now Rubicon Red was founded with the vision of providing Oracle Fusion Middleware customers, a robust SOA adoption methodology incorporating agile development and KPI based governance. So the establishment of best practice around Continuous Delivery has always been a central pillar in our strategy.

    We have been using Continuous Integration and Testing internally for some time now, and have extended our platform to provide support for Continuous Delivery. We have recently introduced this to a number of our customers, and the feedback has been incredibly positive.

    So much so, that one of our customer suggested that we write a series of blogs about what we have done, to hopefully inspire others as well as share some of the lessons learnt. So expect to see a few more blogs on this topic over the coming months.

    In addition, I would love to receive feedback from anyone else on this topic. Particularly if you are implementing (or at least trying to) CIT or Continuous Delivery, what are some of the obstacles you have faced (both technical and organizational) as well as any tips you have to succeed. Many thanks. Matt

  • Deploying Hudson on Weblogic by Homan.Ma
    in Continuous Integration
    8 Jul 2011  | 0 Comments

    During the past few months, we have been setting up hudson on our servers to automate our GWT and SOA builds, testing and deployments to Weblogic.

    Using the helpful wiki page provided on the hudson wiki and thank you to Maxence Button's blog post, this is a step by step installation guide to get Hudson 2.0.1 deployed on to Weblogic 10.3.4.0. 

    Due to Weblogic's class loading structure, if the hudson.war is directly deployed, the application will fail to startup. This is to because there are jar conflicts between Hudson and Weblogic. To get around the issue, we use the FilteringClassLoader mechanism so that specific hudson jars get priority in the classpath over Weblogic's jars. 

     

    1. Download hudson.war

    Download hudson.war from hudson downloads.

     

    2. Create a directory structure for the new hudson.ear

    hudson/
     |_____ META-INF/
             |_____ application.xml
             |_____ weblogic-application.xml
     |_____ hudson.war

     

    Note: This step will not work correctly on MacOSX as it will generate .DS_STORE files within the folders.


    3. Edit application.xml

    Enter the following into application.xml

    <?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?>
     
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
    version="5">
     
    <module id="hudson">
    <web>
    <web-uri>hudson.war</web-uri>
    <context-root>/hudson</context-root>
    </web>
    </module>
     
    <application xmlns="http://java.sun.com/xml/ns/javaee"</module>

    4. Edit weblogic-application.xml

    Enter the following into weblogic-application.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <wls:weblogic-application
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd
    http://www.bea.com/ns/weblogic/weblogic-application >
     
    <!-- server-version: 10.3 -->
    <wls:application-param>
    <wls:param-name>webapp.encoding.default</wls:param-name>
    <wls:param-value>UTF-8</wls:param-value>
    </wls:application-param>
     
     
    <wls:prefer-application-packages>
    <wls:package-name>org.apache.*</wls:package-name>
    <wls:package-name>javax.xml.stream.*</wls:package-name>
    <wls:package-name>org.dom4j.*</wls:package-name>
    </wls:prefer-application-packages>
    </wls:weblogic-application>

     

    Weblogic needs this because (unlike JBoss, Tomcat, Jetty et. al) Weblogic will not load the JARs in the WAR before the Weblogic installed JARs, and usually the resulting error is that there is an old version of Ant 1.7 in scope, instead of Ant 1.8.x as Hudson wants. There is also a conflict with stax-api-1.0.1.jar for the javax.xml package listed.

     

    5. Package into an enterprise application archive

    Inside the hudson directory, at the same level as META-INF and hudson.war, run the following unix commands or zip the contents of the directory and then rename to hudson.ear

    [server]$ zip -r hudson *
    [server]$ mv hudson.zip hudson.ear

     

    Note: Do not zip the hudson folder directly, this will not work. Zip the contents of the hudson folder. 


    6. Deploy the hudson.ear to the Weblogic server:

    Note: remember to delete any old Hudson WAR or EAR deployments first. 


    7. Use Hudson

    The application will deploy to http://serverName:port/hudson.

     

    Troubleshooting

    If you run into certain java exceptions after deployment (see below for an example). Try removing the hudson working directory (In linux, this is in <user_home>/.hudson) and redeploying the hudson.ear file

    org.jvnet.hudson.reactor.ReactorException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.) (Caused by org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.)) at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:246) at hudson.model.Hudson.executeReactor(Hudson.java:727) at hudson.model.Hudson.(Hudson.java:630) at hudson.model.Hudson.(Hudson.java:569) at hudson.WebAppMain$2.run(WebAppMain.java:248) Caused by: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.) (Caused by org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.)) at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:543) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351) at org.springframework.context.support.MessageSourceSupport.(MessageSourceSupport.java:42) at org.springframework.context.support.AbstractMessageSource.(AbstractMessageSource.java:63) at org.springframework.context.support.ResourceBundleMessageSource.(ResourceBundleMessageSource.java:57) at org.acegisecurity.AcegiMessageSource.(AcegiMessageSource.java:34) at org.acegisecurity.AcegiMessageSource.getAccessor(AcegiMessageSource.java:41) at org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider.(AbstractUserDetailsAuthenticationProvider.java:72) at hudson.security.AbstractPasswordBasedSecurityRealm$Authenticator.(AbstractPasswordBasedSecurityRealm.java:175) at hudson.security.AbstractPasswordBasedSecurityRealm.createSecurityComponents(AbstractPasswordBasedSecurityRealm.java:68) at hudson.security.SecurityRealm.getSecurityComponents(SecurityRealm.java:387) at hudson.security.HudsonFilter.reset(HudsonFilter.java:134) at hudson.model.Hudson.setSecurityRealm(Hudson.java:1999) at hudson.model.Hudson$14.run(Hudson.java:2420) at org.jvnet.hudson.reactor.TaskGraphBuilder$TaskImpl.run(TaskGraphBuilder.java:147) at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:260) at hudson.model.Hudson$4.runTask(Hudson.java:708) at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:187) at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:94) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:909) at java.lang.Thread.run(Thread.java:619) Caused by: org.apache.commons.logging.LogConfigurationException: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. (Caused by org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.) at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:397) at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235) at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351) at org.springframework.context.support.MessageSourceSupport.(MessageSourceSupport.java:42) at org.springframework.context.support.AbstractMessageSource.(AbstractMessageSource.java:67) at org.springframework.context.support.ResourceBundleMessageSource.(ResourceBundleMessageSource.java:59) ... 17 more Caused by: org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed. at org.apache.commons.logging.impl.LogFactoryImpl.getLogConstructor(LogFactoryImpl.java:385) ... 24 more