Home Resources News - rss PHP Magazine

PHP Magazine

JAXenter Magazine - All-Inclusive Feed

JAXenter Magazine feeds Java Developers and Software Architects with the latest news, videos and events on Java, Enterprise Architectures and SOA.
  • Tutorial - Gradle SOAP - Features Revealed

    We face the following problem: While the SOAP-based approach to web services is currently out of favor, SOAP-based web services are certainly not out of existence, and the tools for building simple clients to SOAP services are built into Java. Creating a simple client is an almost trivial exercise. All you need is the wsimport tool (part of the JDK installation) and access to a Web Services Description Language (WSDL) file. The wsimport script reads the WSDL file and generates all the required stubs necessary to build the client.Since Groovy and Java can be freely intermixed, it’s easy enough to build a client in Groovy that uses the generated Java stubs.

    Here a Spock test case will be used to check the behavior of a web service. A freely available Microsoft web service used to compute currency exchange rates will be accessed. Hopefully the use of a Microsoft web service won’t turn away the readers of this article that didn’t leave once the term SOAP was used. The service doesn’t matter – it’s the Gradle stuff that’s good. The goal is to automate the entire process, from stub generation to test, using Gradle.

    A Web Service Client

    Microsoft supports a number of simple web services. One of these services is a currency converter (Which they even misspelled as “convertor”. Don’t get me started.), whose WSDL file is located here. By convention, the service is at the same URL with the WSDL parameter removed. Since this is certainly not the place to discuss the vagaries of WSDL, observe only that from the source of the WSDL file the service name is CurrencyConvertor and the portType (i.e., the interface) is CurrencyConvertorSoap. That means that once the stubs have been generated, accessing the web service is as simple as writing:

    CurrencyConvertorSoap stub = new CurrencyConvertor().getCurrencyConvertorSoap()
    

    Then just use the stub to invoke any operations defined in the WSDL file. The only operation needed is called getConversionRate, which takes two Currency instances defined in an XML Schema inside the WSDL file. For example, a typical request would look like:

    double rate = stub.getConversionRate(Currency.USD, Currency.INR)
    

    to get the exchange rate between US dollars and Indian rupees. The key benefit (if any) to SOAP web services is in the stub generation. Java comes with the wsimport tool, whose usage takes the form:

    c:\> wsimport -d buildDir -s srcDir -keep http://...path.to.WSDL.file...
    

    where the -d flag specifies the directory to use for the compiled stubs, the -s flag says where to put the generated source code, the -keep flag means to save the generated source code, and the last argument is the location of the WSDL file.

    This is easy enough to run from the command line, but how do you make it part of an automated build? Fortunately, there is an Ant task defined for it. The job now is (1) add the proper repository so Gradle can find the required jars for the Ant task, (2) define a custom Gradle task for wsimport, and (3) make the execution of the task part of the regular build process. The rest of this article shows how to do each of those tasks.

          

    Creating the Build File

    Since this is ultimately going to be part of a combined Groovy/Java project, start with a build.gradle file containing:

     

    apply plugin: 'groovy'
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        groovy 'org.codehaus.groovy:groovy-all:1.8.4'
    }
    

    This file will grow as additional tasks and dependencies are added. The jar file that defines the web service Ant tasks (like wsimport and wsgen) is part of the JAX-WS tools project. The good news is, JAX-WS modules are located in Maven Central, which Gradle integrates with seamlessly. Modules in Maven Central are minimally defined by a “vector” of three components: a group ID, an artifact ID, and a version. The group id for the JAX-WS tools module is com.sun.xml.ws, the artifact id is jaxws-tools, and the version number is 2.1.4. We want to tell Gradle to download this jar file and other other jars it depends on, and we want to keep those jars in a named container called a configuration. To make this happen, add to the build.gradle file:

    configurations {
        jaxws
    }
    
    dependencies {
        ... from before ... 
        jaxws 'com.sun.xml.ws:jaxws-tools:2.1.4'
    }
    

    However, this library is not stored at the Maven Central repository, so additional repositories must be added. As of Gradle 1.0 milestone 6, the syntax for doing this is:

    repositories {
        mavenCentral()
        maven { url 'http://download.java.net/maven/1' }
        maven { url 'http://download.java.net/maven/2' }
    }
    

    Now comes the fun part! Listing 1 shows an initial attempt at adding a wsimport task to the build.

    Listing 1

    task wsimport {
        doLast {
            destDir = file("${buildDir}/generated")
            ant {
                sourceSets.main.output.classesDir.mkdirs()  
                destDir.mkdirs()
                taskdef(name:'wsimport',
                        classname:'com.sun.tools.ws.ant.WsImport',
                        classpath:configurations.jaxws.asPath)
                wsimport(keep:true,
                         destdir: sourceSets.main.output.classesDir,
                         sourcedestdir: destDir,
                        wsdl:'http://www.webservicex.net/CurrencyConvertor.asmx?
    wsdl')
            }
        }
    }
    compileJava.dependsOn(wsimport)
    

    This block defines a custom task in Gradle. The call to the doLast method defines the steps to be taken when the wsimport method runs. This is an example of an imperative task definition in Gradle. When the task runs, it generates the Java stubs, which then need to be compiled. To ensure that this task runs before the built-in compileJava task, compileJava is declared to depend on wsimport after wsimport is defined.

    That provides a bit of a complication, too, because the output directories for the compiled code aren’t created until the compile task runs. That’s why before the stubs are generated, it is necessary to run mkdirs() on the destination directory. The syntax for this changed in milestone 6 as well. It now requires the “output” property between “main” and “classesDir”.

    The next line defines a “generated” directory under the build directory for the generated Java source files, and the line after that creates this directory.

    Now that all the required properties of the wsimport task have been defined, it’s time to call the actual WSDL generation code. Inside the doLast closure, “ant” refers to the instance of AntBuilder inside every Gradle build file. Inside the ant closure, the taskdef and wsimport tasks come from their Ant counterparts. The only subtlety is the classpath configuration for the task, which refers to the jaxws configuration defined earlier. Using Gradle's transitive dependency management in connection with Ant task definitions is a significant improvement on what can be an inconvenient process of wrangling the right dependencies into your project to define a custom Ant task.

    So far, the process works fine, but is inefficient. As configured, the wsimport tasks runs on every build, which certainly isn’t necessary if the web service doesn’t change. (That actual web service hasn’t changed for years!) There are a couple of ways to prevent re-running the task every time. One is to take advantage of the onlyIf property of Gradle tasks, as follows:

    wsimport.onlyIf { !(new File(buildDir, 'generated').exists()) }
    

     Now the task will run only if the generated source directory doesn’t exist. By placing the generated directory under the build directory, a clean task will eliminate it and the wsimport task will run during the next build.

    This is all well and good, and is a reminder that the build file is still a Groovy file so arbitrary Groovy expressions can be added to it, but there is an even better alternative. Each Gradle task has properties called “inputs” and “outputs”, which engage the incremental compilation engine. The purpose of these two fields is to determine whether a task is up to date or not with respect to the files a task reads as input and writes as output. The only problem here is that the arguments to inputs and outputs have to be file based, and the WSDL file is at a URL.

    There is no perfect way to solve this problem. The build can always look to the web for the WSDL, which means it always get updated versions of the WSDL when they are released. However, Gradle's incremental compilation engine can only work with local files, not network resources; moreover, this approach would force users of the build to have a network connection all the time. A better approach is to cache the WSDL file locally by saving it as a file in the project. It would be straightforward to add another task to the build to download the WSDL file from its canonical URI and cache it in the project directory. This step is omitted here for the sake of brevity. The resulting changes are shown in bold in Listing 2.

    Listing 2

     

    task wsimport  {
        destDir = file("${buildDir}/generated")
        wsdlSrc = file('currency_convertor.wsdl')
        inputs.file wsdlSrc
        outputs.dir destDir
        doLast{
            ant {
                sourceSets.main.output.classesDir.mkdirs()
                destDir.mkdirs()
                taskdef(name:'wsimport',
                    classname:'com.sun.tools.ws.ant.WsImport',
                    classpath:configurations.jaxws.asPath)
                wsimport(keep:true,
                    destdir: sourceSets.main.output.classesDir,
                    sourcedestdir: destDir,
                    wsdl: wsdlSrc)
            }
        }
    }
    

     

    The WSDL file is stored in the root of the project. The inputs property uses the file method to connect to the WSDL file, and the outputs property uses the dir method to connect to the destination directory. If the input file or any of the files in the output directory change, the task will execute again. If neither the input nor the output change between invocations of the build, the task will not execute.

    The build as it stands is fine, but there’s one other under-publicized feature of Gradle that’s worth illustrating. Gradle assumes that the project layout conforms to a standard layout, with subdirectories like src/main/groovy, src/main/java, src/test/groovy, and so on. If you prefer not to use that structure, with it's remarkably easy to change.

    Consider an alternate project layout with two source folders, one called src and one called tests. It’s easy enough to map this structure to the Gradle domain model: 

    sourceSets {
        main {
            java { srcDir "$buildDir/generated" }
            groovy { srcDir 'src' }
        }
        test {
            java { srcDirs = [] }
            groovy { srcDir 'tests' }
        }
    }
    

        

    The sourceSets closure maps standard source directory structure to whatever the project requires. The layout here says that there is only one source directory for Java files, which is the generated directory populated by the wsimport task. Everything else in “src”, whether written in Java or in Groovy, is compiled by groovyc. The test closure is even more explicit – there are no directories for javac to use. Everything under the ‘tests’ directory is compiled by groovyc. That’s actually a good integration principle. The groovyc compiler knows all about Java source code, so let it compile both the Java and the Groovy sources. That way it can resolve any potential cross compilation issues for you. So far, all of the code in this article has been from the Gradle build file. For completeness, Listing 3 shows a class defining a conversion rate service.

    Listing 3

    import net.webservicex.Currency;
    import net.webservicex.CurrencyConvertor 
    import net.webservicex.CurrencyConvertorSoap 
    
    class ConversionRate {
        CurrencyConvertorSoap stub = 
            new CurrencyConvertor().getCurrencyConvertorSoap()
    
        double getConversionRate(Currency from, Currency to) {
            return from == to ? 1.0 : stub.conversionRate(from, to)
        }
    }
    

    Listing 4 below shows a simple Spock test to check the implementation

    Listing 4

    import net.webservicex.Currency;
    import spock.lang.Specification;
    
    class ConversionRateSpec extends Specification {
        ConversionRate cr = new ConversionRate()
    
        def "same currency should be rate of 1"() {
            when:
            double rate = cr.getConversionRate(Currency.USD, Currency.USD)
    
            then:
            rate == 1.0
        }
    
        def "rate from USD to INR is > 1"() {
            expect:
            cr.getConversionRate(Currency.USD, Currency.INR) >= 1 
        }
    }
    

    Even if you’ve never seen a Spock test before, this should be pretty intuitive. The class extends the Specification class from Spock, which makes it a Spock test class. Each test has a def return type, followed by a string explaining its goal, and empty parentheses. The first test uses a when/then pair as a stimulus/response. The “then” block contains boolean conditions that are evaluated automatically, so no assert-based keyword is required.

    Since the actual exchange rates change all the time, the second test picks two currencies that are guaranteed to satisfy the condition. At the time this article was written, there were about 51 INR for 1 USD. The boolean test is in an expect block, which works the same way the then block did in the previous test. To make the test work, one last change to the build file is required. Add the following line to the dependencies block.

     

    testCompile 'org.spockframework:spock-core:0.5-groovy-1.8'
    

    That will download the proper version of Spock, along with its dependencies (like JUnit), and now the build will execute the tests as well. Version 0.5 is current as of this writing. Feel free to try updating the version number to whatever is current at the time you run the example.

    Summary

    While the project that motivated this article involved a simple Groovy/Java client on a Microsoft web service, the real goal was to illustrate several aspects of Gradle development. Among them were creating a custom task, using a configuration based on an external Ant jar, working with multiple repositories, defining and configuring an Ant task, inserting it into the normal build process, ensuring that the task only ran when necessary, and showing how to map an alternative project layout to what Gradle expects. Hopefully some or all of these tasks will be helpful to you in the future. All of the source code for this article is available at a GitHub repository located here.

     

    This article first appeared in Java Tech Journal: Gradle. You can find other articles from that issues and other issues here



  • IBM gets Symphony OpenOffice contribution underway

    Little than a week on from Apache OpenOffice getting a reboot, following a period in which they irked many and lost many to LibreOffice, IBM have put their weight behind the Apache vehicle through the submission of office automation suite IBM Lotus Symphony.

    It's a welcome boost for the ailing giant looking to regain ground with the Apache Foundation's first version OpenOffice 3.4, with the addition of Lotus Symphony, which was originally based on a combination of the Eclipse Rich Client Platform and OpenOffice.org code. Due to the Java wrapper being based on Eclipse, this doesn't form part of the submission, due to clashing with a rival open source foundation.

    Donald Harbison detailed in an email that he had submitted the IBM Software Grant Agreement and Corporate Contributor License Agreement for the IBM Lotus Symphony contribution, having originally suggested doing this in January 2011. He also noted that 'the successful delivery of Apache OpenOffice 3.4 has now made it possible to move forward' with this submission and went on in further email to elaborate:

    This is about envisioning a future for Apache OpenOffice that builds on the best code we can offer together with the best developers who have mastered it. This is going to be a lot of fun and a lot of hard work. It's something we've looked forward to doing for a very long time. 

    We invite you to think about this code as providing a rich set of features with the potential to significantly improve user productivity, performance and stability of Apache OpenOffice. Additionally, there is excellent work in Microsoft Office file format support, globalization, and last but not least, accessibility support.

    We hope everyone is as excited about this contribution as we are. IBM will continue to maintain and support Symphony for our customers until we are able to offer Apache OpenOffice with what we hope will be most of the value we are contributing today. How we get to this goal will depend on all of usworking together here. We have our ideas, but recognize that we are all equal in the project and are dedicated to working in the Apache Way.

    A Wiki page, detailing all the possible features that can come out of Symphony has been created for contributions. Some features mooted include UI design upgrades, new sidebars, templates and Visual Basic APIs. IBM intend to continue their Symphony product until these proposed features are fully implemented within a future Apache OpenOffice. What happens after this is as of yet unknown.



  • JAX Innovation Awards - Nominations Revealed!

    Over the last month we have had many interesting and diverse nominations sent our way in the form of Top Java Ambassadors, Most Innovative Java Technologies and Most Innovative Java Companies.

    We thank every one of you who has taken the time to fill out the nomination forms.

    You may have noticed that one of our jury members, Martijn Verburg, was nominated in the Top Java Ambassador category. After much discussion we decided that it would only to be fair for Martijn to either decline the nomination or to remove himself from judging duties in that category. Martijn opted to decline the nomination.

    Martijn has also not cast any votes for any nomination related to ZeroTurnaround, as he sits on their product advisory board.

    Another conflict that you may have noticed is that ZeroTurnaround has been nominated in the Most Innovative Java Company category.  Jevgeni Kabanov, the CEO of ZeroTurnaround, who is also a Jury member will not be casting any votes in regards to that nomination.

    The Jury members are currently judging the nominations, once all of the votes have been tallied up, we will reveal who/what has made it into the shortlist next week. How exciting! Then it’s back to you guys again, we need the community’s involvement to help decide the winners. We need YOU to vote on who you think deserves to wear the crown of Top Java Ambassador and who/what deserves the title of Most Innovative Java Company and Technology.

    Community voting opens on May 28th and the winners will be announced at the award ceremony on July 10th as part of our JAX Conference in San Francisco.

    To see who has been nominated altogether check out the website.

    Good luck to everyone who has been nominated and congratulations! 



  • Oracle vs Google - trial roadmap laid out by Alsup, copyright damages postponed for future trial

    As reported yesterday, Oracle's lawsuit against Google over Android was entering the farcical yet they still have the faintest glimmer of hope of obtaining the astronomical damages for the minimal lines of code that were found to be infringing.

    Wednesday's play began with an emergency summit between Judge Alsup and the two parties to outline where the trial was heading. As ZDNet's Rachael King aptly put it, the potential outcomes read like a 'Choose Your Own Adventure' storybook.

    The most salient piece to take from the session was that the copyright damages phase will now be postponed after both Oracle and Google came to a truce. In summary, the jury will play no further part in the copyright part (currently out debating the patent phase), nor will we hear anything further until the appeals have passed and if a future trial is granted by the court. Google are still pushing to tie the infringement and fair use matters into a new trial, but Oracle vehemently opposes this.

    As previously stated, Oracle are free to go for infringer's profits but with some caveats - neither they or Google can call upon previous witnesses or reports already seen by the jury. If the SSO claim is put forward to a new jury in a future trial, then both parties waive their right to a jury trial over damages from the nine lines of code in 'rangeCheck'. Phew.

    This is of course all irrelevant if the coding Judge Alsup returns from his background reading on the 37 Java APIs and rules that they aren't copyrightable, meaning he might give Oracle statuory damages alone - barely amounting to spare change for them. If he finds they are copyrightable, Oracle gets a second chance via a re-trial.

    So this leaves us with four possible outcomes, with a mass of grey area inbetween with appeals aplenty expected:

    • Oracle wins API copyright debate and patent portion - has an outside chance of winning big, and gets the jury to debate damages. It won't be in the big figure ballpark they want though, with Oracle's own damages expert suggesting that the two patents are worth $4m together maximum, and Google will clearly contest this.
    • Oracle wins API copyright debate but loses patents - gets re-trial but damages decided at a later date.
    • Oracle loses API copyright debate but wins patents - gets small damages, can ask for injunction on offending Android patents
    • Oracle loses both - wipeout, two year battle with Android comes up with nothing.

    Clearer? We hope so. Now we await that crucial decision from Judge Alsup on API copyrights as well as hearing the jury's decision on Phase 2 on patents. It could transpire that Alsup awards damages here, given that in comparison to the copyright phase, it's a small amount. The murky quagmire that is this trial has been made as crystal clear as we're going to get.



  • Spring Data JPA and AMQP reach 1.1.0 releases

    Things never seem quiet in the SpringSource labs with the team announcing three important releases on their blogs.

    First up, Spring Data JPA 1.1.0 has gone GA, bringing with it over 72 fixed bugs, improvements and new features. Evolving out of the Hades open source project and an offshoot of the larger Spring Data project, Spring Data JPA's goal is to make the old cumbersome methods of implementing a data layer far simpler through streamlining the process needed to implement JPA-based repositories.

    Flagged as the important new features by Project Lead Oliver Gierke include support for declarative locking and native queries in @Query, plus new query generation keywords such as LessThanEqualGreaterThanEqualBeforeAfterStartsWithEndsWithContains.

    PersistenceUnitPostProcessor is added to scan for JPA entities (but only to be used with Spring versions before 3.1) and there's a big plus for the inclusion of CDI integration for repositories

    The relevant release reference documentation is available in HTML and PDF format, as is the changelog delving deeper into every difference for Spring Data JPA 1.1.0. Binaries are available through SpringSource's own Artifactory or you can get your hands on the Javadocs.

    Combined with this announcement, Gierke detailed the advances made to Spring Data REST 1.0.0 with the second milestone released almost in unison. The major update for Spring Data REST exporter includes fundamental functionalities such as query method and validation support, in addition to the already included JSR-303 validation. Improved ApplicationEvent handling means 'ApplicationEvents are emitted before and after each save or delete, allowing your code to tie into these lifecycle events and trigger other actions.'

    The final announcement is the release of Spring AMQP 1.1.0, which is Spring's home for AMQP-based messaging development. The main changes here come in the form of support for RabbitMQ 2.8x client, with features such as Mirrored Queues, Broker Failover, Publisher Confirms, Returns and Federated Exchanges.

    All in all, a busy day for SpringSource as some smaller projects get the time in the limelight.



10 Minute Joomla! Tips Blog

Conticreative joomla book reviews

Independent joomla hosting reviews

Books

Books we suggest...

 

Spreadfirefox Affiliate Button
switch the positions on