Sunday, January 25, 2015

Spring by Example Update (1.5)


The Spring by Example site update is just a basic library update. All of the Spring by Example modules have also been published to the Maven repo. The site has been updated to use Spring Framework 4.1.x. Most other libraries have also been upgraded. Some major ones are Spring Integration 4.1.2, Spring Security 3.2.5, Spring Data JPA 1.7.1, and Hibernate 4.3.8.

Saturday, September 28, 2013

Dynamic REST Client & Controller Generation


Here is the example from SBE REST Modules on GitHub.

It let's you create an interface and put your Spring MVC REST annotations on it if you follow certain patterns. The REST client and controller can be generated using Spring beans. It's expected that your controllers would just delegate to a service layer, so the interface to that service can be registered using @RestResource on the class. The base URI and default response class are also defined here. By default, a method with @RequestMapping will expect the same method and method signature to be available to delegate to in the service class.

Another feature is to turn off creating a relative URI using the class' path, is to specify @RestRequestResource on a method and setting 'relative' to false. If the interface overloads a method to perform further conversion on the results, the method name can be specified. The framework still expects the method signatures to match. A converter can be specified to change the result before it's sent to the client. A good example of this is creating smaller models to match different needs without doing further customizations on the backend services or queries.

This all needs more work, but all of the basics are working now. I'll write this up soon on Spring by Example.



public interface PersistenceFindMarshallingService<R extends EntityResponseResult, FR extends EntityFindResponseResult> {

     public final static String PATH_DELIM = "/";
     public final static String PARAM_DELIM = "?";
     public final static String PARAM_VALUE_DELIM = "&";

     public final static String ID_VAR = "id";
     public final static String PAGE_VAR = "page";
     public final static String PAGE_SIZE_VAR = "page-size";

     public final static String PAGE_PATH = PATH_DELIM + PAGE_VAR;
     public final static String PAGE_SIZE_PATH = PATH_DELIM + PAGE_SIZE_VAR;
     public final static String PAGINATED = PAGE_PATH + PATH_DELIM + "{" + PAGE_VAR + "}" + PAGE_SIZE_PATH + PATH_DELIM + "{" + PAGE_SIZE_VAR + "}";

     public final static String ROOT_URI = PATH_DELIM;
     public final static String FIND_BY_ID_URI = PATH_DELIM + "{" + ID_VAR + "}";

     /**
      * Find by primary key.
      */
     @RequestMapping(value = FIND_BY_ID_URI, method = RequestMethod.GET)
     public R findById(@PathVariable(ID_VAR) Integer id);

     /**
      * Find a paginated record set.
      */
     @RequestMapping(value = PAGINATED, method = RequestMethod.GET)
     public FR find(@PathVariable(PAGE_VAR) int page, @PathVariable(PAGE_SIZE_VAR) int pageSize);

     /**
      * Find all records.
      */
     @RequestMapping(value = ROOT_URI, method = RequestMethod.GET)
     public FR find();

}


public interface PersistenceMarshallingService<R extends EntityResponseResult, FR extends EntityFindResponseResult, S extends PkEntityBase>
         extends PersistenceFindMarshallingService<R, FR> {

     public final static String DELETE_URI = ROOT_URI + "remove";

     /**
      * Save record.
      */
     @RequestMapping(value = ROOT_URI, method = RequestMethod.POST)
     public R create(@RequestBody S request);

     /**
      * Update record.
      */
     @RequestMapping(value = ROOT_URI, method = RequestMethod.PUT)
     public R update(@RequestBody S request);

     /**
      * Delete record.
      */
     // FIXME: server has marshalling error if DELETE
     @RequestMapping(value = DELETE_URI, method = RequestMethod.PUT)
     public R delete(@RequestBody S request);

}



@RestResource(service=ContactService.class, path=PATH, responseClass=PersonResponse.class)
public interface ContactMarshallingService extends PersistenceMarshallingService<PersonResponse, PersonFindResponse, Person> {

     final static String PATH = "/person-test";
     final static String SMALL_URI = "/small";
     final static String SMALL_PATH = "/small-person";

     public final static String SMALL_FIND_BY_ID_REQUEST = SMALL_PATH + PATH_DELIM + "{" + ID_VAR + "}";

     public final static String SMALL_FIND_PAGINATED_REQUEST = SMALL_PATH + PAGINATED;

     public final static String LAST_NAME_VAR = "lastName";
     public final static String LAST_NAME_PARAMS = PARAM_DELIM + LAST_NAME_VAR + "={" + LAST_NAME_VAR + "}";
     public final static String FIND_BY_LAST_NAME_CLIENT_REQUEST = PATH + LAST_NAME_PARAMS;
     public final static String SMALL_FIND_BY_LAST_NAME_CLIENT_REQUEST = PATH + SMALL_URI + LAST_NAME_PARAMS;

     @RequestMapping(value = SMALL_FIND_BY_ID_REQUEST, method = RequestMethod.GET)
     @RestRequestResource(relative=false, methodName="findById", converter=SmallContactConverter.class)
     public PersonResponse smallFindById(@PathVariable(ID_VAR) Integer id);

     @RequestMapping(value=SMALL_FIND_PAGINATED_REQUEST, method = RequestMethod.GET)
     @RestRequestResource(relative=false, methodName="find", converter=SmallContactConverter.class)
     public PersonFindResponse smallFind(@PathVariable(PAGE_VAR) int page, @PathVariable(PAGE_SIZE_VAR) int pageSize);

     @RequestMapping(value = PATH_DELIM, method = RequestMethod.GET, params= { LAST_NAME_VAR })
     public PersonFindResponse findByLastName(@RequestParam(LAST_NAME_VAR) String lastName);

     @RequestMapping(value = SMALL_URI, method = RequestMethod.GET, params= { LAST_NAME_VAR })
     @RestRequestResource(methodName="findByLastName", converter=SmallContactConverter.class)
     public PersonFindResponse smallFindByLastName(@RequestParam(LAST_NAME_VAR) String lastName);

}


Spring by Example Update (1.3)


I've been working on this off and on for a long time, but I finally have a Spring by Example site update ready. It's using Spring Framework 3.2.x and most major libraries are all upgraded. The biggest changes are to the Contact Application, which now references SBE REST Modules (available on Spring by Example's GitHub), which I will document on the site shortly. The Contact Application also has a better production ready DB connection pool configuration and upgrades the Jackson JSON mapper & view.

I did also try to create a shared base for messages/response for the JAXB beans, but I ran into some issues generating them in the Contact Application. The Fluent API doesn't look at parent classes when generating the '.withXXX' methods. It does look like it would be simple to customize the JAXB plugin to fix this, but I didn't want to take the time right now.

Below are the Contact Application modules.
  • DAO - DB Schema, JPA Entities, Spring Data JPA repositories.
  • Web Service Beans - JAXB beans generated from XSDs.
  • Services - APIs use JAXB beans and Dozer is used to convert between this beans and the JPA entities. Security and transactions are configured in this layer.
  • REST Services - The module has clients & controllers, as well as their Spring configurations. JSON and XML views are supported for requests.
  • Webapp - The webapp as a standard JSP UI, Sencha ExtJS, and also a Sencha Touch UI.
  • Test - The DAO, Services, and REST Services all have an abstract test class for each module that each test extends. This way within each module, all tests have a shared context so Spring only has to load once. All of these tests use an in memory database and the REST Services have an embedded jetty server. REST Services tests can be run with clients using JSON or XML for marshalling.


Sunday, November 11, 2012

Contact Application on Spring by Example

I've just updated Spring by Example to have a multi-module Contact Application. It's meant to be an example of an architecture pattern to follow for larger applications.

The DAO module has the DB schema, JPA entities, and uses Spring Data JPA repositories. It also has a Spring Profile for HSQL DB and PostgreSQL. The tests and webapp default to using the in memory database and PostgreSQL is meant to be used in the production deployment of the webapp.

The WS Beans module are JAXB beans generated from XSDs. They are generated to have a fluent API (ex: new Person.withId(1).withFirstName("John")) and are meant to provide an easy way to create different models for external APIs that can be easily serialized to JSON & XML.

The Services module uses the WS Beans (JAXB Beans) for it's main model and for any APIs. It is meant to be the layer where all business logic is located. It converts to and from the JPA entities & WS Beans using Dozer. It configures Spring's transactional support and Spring Security.

REST Services exposes the Services layer and provides clients & controllers for all REST APIs. All APIs can be exposed over JSON & XML. It has the standard JSON media type and a custom one that also includes class information for more complex data models.

The contact webapp has a standard JSP UI, Sencha ExtJS, and also a Sencha Touch UI.

There is a shared test module to keep inter-module dependencies less complex. The DAO, Services, and REST Services layer each have an abstract test base that creates a shared test context. The DAO and Services both create an in memory DB, and use Spring's transactional test framework to rollback transactions after each test runs. The REST Services module creates an in memory DB and an embedded Jetty instance. The embedded Jetty has it's own Spring context, separate from the test one. The embedded Jetty context loads as much as possible of the production Spring configuration, and the test context just loads the REST clients. You may also want to look at Spring Test MVC for testing controller, but the Contact Application approach runs very quickly and is really a full integration test.

Friday, August 24, 2012

Spring Data JPA Examples on Spring by Example

I've just updated Spring by Example to have two Spring Data JPA examples. One has basic repository use and shows how to make some custom queries, and the other one shows how to use Spring Data JPA auditing. All of the main webapps using JPA were updated to use Spring Data JPA and all JPA examples were updated to use Hibernate 4.1. I ran into issues updating the Hibernate template examples, so they will stay on Hibernate 3.6.

There were other miscellaneous updates. The AJAX tiles work in the web flow examples wasn't working so I removed it for now.

I'll be continuing to work on REST and UI examples, using ExtJS and Sencha Touch.

Saturday, August 18, 2012

SpringOne & Spring By Example Update

I've just updated Spring by Example to Spring 3.1 and Java 6. The new Spring by Example Repository is on GitHub.

Here are some general comments about the latest release. The Maven group and artifact IDs have been changed back to standard Maven naming and also all project dependencies (no OSGi ones in standard examples). The project is now one large multi-module project structure to make it easier to maintain and upgrade releases. Originally the goal was to have standalone projects so it was easier for someone to get started, but I don't have time to maintain the project this way anymore.

The GWT examples have been removed from the documentation and are not in git. If I have time in the future I may add them back, but I'll be focusing on some standard JS UI examples. The Spring dm Server (OSGi) examples have not been updated, but are still available in the documentation. They still located in Subversion since I won't actively try to maintain them anymore. Spring by Example JDBC has been removed and all projects (except for OSGi ones) have been changed to use the Spring JDBC Custom Namespace. Between the this namespace and Spring Data JPA, nothing is really necessary in this module. I'll be starting on a Spring Data JPA example next week.

Friday, January 20, 2012

Spring JAXB with CDATA Elements


I wanted to configure the Jaxb2Marshaller to support CDATA elements. This example works with Spring 3.1 and Java 6, using the Java 6 restricted XML parser classes to configure the CDATA elements.



<bean id="marshaller" class="org.springbyexample.marshaller.CdataJaxb2Marshaller">
     <property name="cdataElements">
         <list>
             <value>^value</value>
         </list>
     </property>
...


import java.io.IOException;
import java.io.OutputStream;

import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.ArrayUtils;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.oxm.mime.MimeContainer;


public class CdataJaxb2Marshaller extends Jaxb2Marshaller {
    
    private String[] cdataElements;
    
    public String[] getCdataElements() {
        return cdataElements;
    }

    public void setCdataElements(String[] cdataElements) {
        this.cdataElements = cdataElements;
    }
    
    @Override
    public void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException {
        if (ArrayUtils.isNotEmpty(cdataElements)) {
            try {
                Marshaller marshaller = createMarshaller();
    
                com.sun.org.apache.xml.internal.serialize.XMLSerializer serializer =
                        createXMLSerializer(cdataElements, ((StreamResult)result).getOutputStream());
                marshaller.marshal(graph, serializer.asContentHandler());
            } catch (IOException e) {
                throw new MarshallingFailureException(e.getMessage(), e);
            } catch (JAXBException ex) {
                throw convertJaxbException(ex);
            }
        } else {
            super.marshal(graph, result);
        }
    }

    @SuppressWarnings("restriction")
    private com.sun.org.apache.xml.internal.serialize.XMLSerializer createXMLSerializer(String[] cDataElements, OutputStream cOut) {
        // This code is from a sample online: http://jaxb.java.net/faq/JaxbCDATASample.java
        // configure an OutputFormat to handle CDATA
        com.sun.org.apache.xml.internal.serialize.OutputFormat of = new com.sun.org.apache.xml.internal.serialize.OutputFormat();

        // specify which of your elements you want to be handled as CDATA.
        // The use of the '^' between the namespaceURI and the localname
        // seems to be an implementation detail of the xerces code.
        // When processing xml that doesn't use namespaces, simply omit the
        // namespace prefix as shown in the third CDataElement below.
        of.setCDataElements(cDataElements); //

        // set any other options you'd like
        of.setPreserveSpace(true);
        of.setIndenting(true);
        of.setPreserveSpace(false);

        // create the serializer
        com.sun.org.apache.xml.internal.serialize.XMLSerializer serializer = new com.sun.org.apache.xml.internal.serialize.XMLSerializer(of);
        serializer.setOutputByteStream(cOut);

        return serializer;
    }

}

Friday, December 25, 2009

Spring 3.0 & Maven

I wanted to go over the process of upgrading the build from Spring 2.5 to Spring 3.0 (3.0 release announcement) using Maven for the build process. For almost all applications from basic dependency injection to webapps, and even enterprise applications with Spring Web Services and Spring Integration all upgraded without any issues.

I did change all the builds to use the SpringSource Enterprise Bundle Repository. It has all the Spring projects and also repackaged versions of many other open source ones. SpringSource did this to make all the artifacts OSGi enabled and also corrected any errors in dependencies where possible. It isn't necessary to use this repository and all Spring projects are also deployed to the main Maven repository tool.

I primarily switched so the projects could be more easily imported into an OSGi environment if someone needed to the SpringSource Enterprise Bundle Repository (EBR) and to avoid any dependency resolution issues since some artifacts will need to be resolved from the EBR.

Keith Donald, from SpringSource, did a blog discussing using Maven with Spring 3.0. It's called Obtaining Spring 3 Artifacts with Maven and is definitely worth reading to understand things in more detail.

Thursday, December 24, 2009

Spring & Spring by Example


I've been working a lot on getting Spring by Example updated for Spring 3.0. A Simple Grails Webapp was also added to this release.

Almost everything is upgraded except for the AspectJ LTW example, GWT ones, and OSGi. The AspectJ one, I've had an odd problem that I've updated everything to use the Spring Repository, but when I change it to from Spring 2.5.6 to 3.0, the weaving stops working. No errors and no success resolving the issues, but I will keep working on it. I had trouble with the GWT webapps too, but I think it's mainly build related. I'll probably start over with a new project using GWT 2.0 and build the examples back up. For the Spring dm Server (OSGi) ones, I just haven't had time. I don't think there will be a problem upgrading them.

Everything is versioned on the site, so all past site releases and examples are available (Spring by Example 2.5.x, which is version 1.0.3). Just follow the subversion instructions at the end of the examples to checkout the correct version of the project the example describes. If you're ever not sure what version of something the example uses, check the 'Project Information' section at the end of the example and/or the Maven POM.

I have a Spring Roo example in progress that is the basis for a simple person and address example. Ideally I'd like to even use Roo to replace many of the webapp examples and/or have as much of them generated as possible. I'd also like to spend time redoing the web services add-ons for Roo and get them into a releasable state, but I just haven't had the time. I'm hoping it will fit in with a future project soon, so maybe it will get done.

I also plan on getting SpEL, REST, and some other examples together for the website. I've also done a lot of Flex work over the last year, so I'd really like to do some more advanced Flex examples and especially a basic messaging example and security example.

Monday, December 14, 2009

Spring Roo, SpringOne 2009, Spring by Example

I haven't been active on my blog or Spring by Example for a long time. I was just really busy. In that time I've been working with Flex, Spring BlazeDS Integration, Spring MVC, Spring Web Flow, Spring Roo, and other things.

Spring Roo was very useful. I made my own add-ons that generated web services based on a JPA bean and even the matching ActionScript class. I'm going to try working on a better version based on the new Spring Roo add-on format when I have time. What I did so far is checked into subversion. It was developed against Spring Roo 1.0.0.RC1 before there was standardized add-on format. I was very rushed when I did this, so it's functional but very basic and needs to be redone.

SpringOne 2009 in New Orleans was good. A lot of interesting presentations and nice getting to see different people again. The cloud presentation in the keynote was very interesting. Some of the improvements in Spring MVC that are in Spring 3.0 are quite nice. There is JSR-303 (Bean Validation) support, Type Conversion and Validation (blog by Keith Donald), REST support, and an MVC namespace for reduced configuration. Some of the SpEL (Spring EL) integration with other projects like Spring Integration and Spring Security look really useful. SpringOne is a really good conference and I'm glad I went.

I've been working for over a week on upgrading Spring by Example's projects to Spring 3.0.0.RC3. Most have upgraded without any issues, although I'm having trouble upgrading the GWT ones. I'm going to probably leave them and the dm Server (OSGi) examples as they are for now and finalize the other examples, double check everything is working, and update the documentation so I'll be ready for a release for the Spring 3.0 final release. The webapps (other than GWT & dm Server ones) have not only been upgraded to Spring 3.0, but have also been upgraded to JPA and following Spring MVC best practices as much as possible if they weren't already. All of them were changed to use the Spring MVC namespace which reduced their configuration slighlty. Also the applications with security had their login/logout pages changed to be served through Tiles and support i18n. When I have time I'd like to change the webapps to use jspx and use RESTful URLs.

I'm hoping to get a release of Spring by Example out in the next few days. Then continue working on everything else and possibly have another release before the end of the year. I'd also like to get a SpEL and Spring MVC REST examples added to the site.

Sunday, May 31, 2009

Spring, Flex, and other things


I finally just did another release for Spring by Example. One example is Simple Flex Webapp and the other is Simple Spring Integration.

I just did the Flex example recently and the Spring Integration one was done a little while ago, but I never wrote about it for the site. There's also a more advanced example using queues and splitting, but I'm not sure if the flow really makes sense although it needs to be the way it is to split and aggregate things.

I've been working with Flex for a few months now and I still think it's really nice. It's the best thought out UI framework I've ever worked with. Besides it looking very nice with minimal effort, it's very easy to do many things, ActionScript is a very comfortable environment for someone that knows Java, JavaScript, and is used to doing web development. Also, I'm impressed with how many things Adobe has open sourced. The Adobe BlazeDS provides a really good bridge between Java and Flex for remoting and messaging. Also the Spring BlazeDS Integration project from SpringSource really simplifies configuration and ease of use as you would expect. I think they've done a really great job again. Spring Integration also has integration with Spring BlazeDS Integration so from a message flow you could send a message to a Flex UI and the flow could wait for a response to come back.

The Adobe Cairngorm project for providing client side MVC in Flex is nice too. It helps provide separation of business logic from UI components and encourages using Flex's data binding to transfer information from the controller to the view using a bound model. Adobe suggests having the model a singleton, but it would be nice if a dependency injection framework was used instead. Spring ActionScript gives basic functionality, but just the bare minimum compared to Spring's Java implementation. Although I think it could become a lot nicer without too much effort.

I'm going to try to post more Flex examples including more advanced Flex usage as well as ones using messaging. A bridge can be created between JMS queue and a Flex queue or messages can be sent directly to the Flex queue. Also, I'd like to start spending more time using the SpringSource dm Server. The new web features that are being added to version 2.0 really interest me.


Sunday, April 19, 2009

Maven JAXB Generation Part II

I've already done a posting on using Maven to generate JAXB with the Fluent API and this adds making the JAXB beans serializable and setters for lists. Add the file jaxb-bindings.xjb to the 'src/main/resources' with the config below and JAXB beans will implement serializable.

Also by default, collections only have getters. The JAXB 2.1 Collection setter Injector Plugin will also generate a setter for any collection. I found this useful while serializing JAXB beans between Java and ActionScript with BlazeDS (while using Spring BlazeDS Integration. BlazeDS only serializes something if it has a getter and a setter. Unfortunately I couldn't find this in a Maven repo, but you can install it locally or into your Nexus server.




<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<args>
<arg>-Xfluent-api</arg>
<arg>-Xcollection-setter-injector</arg>
</args>
<schemaDirectory>src/main/resources</schemaDirectory>
<plugins>
<plugin>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>2.1.8</version>
</plugin>
</plugins>
</configuration>
<dependencies>
<!-- Had to manually install in repo, not in main java.net repo. -->
<dependency>
<groupId>org.jvnet.jaxb2-commons</groupId>
<artifactId>collection-setter-injector</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>

src/main/resources/jaxb-bindings.xjb
<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">

<jxb:bindings>
<jxb:globalBindings>
<jxb:serializable/>
</jxb:globalBindings>
</jxb:bindings>

</jxb:bindings>

Monday, February 16, 2009

Spring Modules Valang

I've been working on adding enhancements to Spring Modules Valang. I've added a number of new features so far and I have two versions uploaded to the Spring by Example Maven Repository (org.springbyexample.validation:sbe-validation). I have it under a different group id and artifact name so there aren't' any collisions in the future with Spring Modules releases.

I'm also working on documentation, but that's going to take a little longer to finish.

Version 0.91

  • Bytecode generation added to DefaultVisitor as a replacement for reflection accessing simple properties (BeanPropertyFunction) for a significant performance improvement.
  • Basic enum comparison support. In the expression below the personType is an enum and the value STUDENT will be convereted to an enum for comparison. The value must match an enum value on the type being compared or an exception will be thrown.

    personType EQUALS ['STUDENT']
    For better performance the full class name can be specified so the enum can be retrieved during parsing. The first example is for standard enum and the second one is for an inner enum class .

    personType EQUALS ['org.springmodules.validation.example.PersonType.STUDENT']

    personType EQUALS ['org.springmodules.validation.example.Person$PersonType.STUDENT']
  • Where clause support. In the expression below, the part of the expression price will only be evaluated if the personType is 'STUDENT'. Otherwise the validation will be skipped.

    price < 100 WHERE personType EQUALS ['STUDENT']
  • Improved performance of 'IN'/'NOT IN' if comparing a value to a java.util.Set it will use Set.contains(value). Static lists of Strings (ex: 'A', 'B', 'C') are now stored in a Set instead of an ArrayList.
  • Functions can be configured in Spring, but need to have their scope set as prototype and use a FunctionWrapper that is also a prototype bean with set on it.
  • Removed servlet dependency from Valang project except for the custom JSP tag ValangValidateTag needing it, but running Valang no longer requires it. This involved removing ServletContextAware from it's custom dependency injection. If someone was using this in a custom function, the function can now be configured directly in Spring and Spring can inject any "aware" values.

Version 0.92

  • Removed custom dependency injection since functions can be configured in Spring.
  • Added auto-discovery of FunctionWrapper beans from the Spring context to go with existing auto-discovery of FunctionDefinition beans.

Generating Bytecode


I've been looking at the Javassist project. It's really nice. It's a higher level API for manipulating and generating bytecode. Below is an example generating a new class that implements and interface, and then implements the interface. By generating this, it avoids reflection and is significantly faster in tests I've run.



ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.makeClass(classFunctionName);

cc.addInterface(pool.get("org.springmodules.validation.valang.functions.Function"));

StringBuilder generatedMethod = new StringBuilder();
generatedMethod.append("public Object getResult(Object target) {");
generatedMethod.append(" return ");
generatedMethod.append(" ((" + className + ")target).");
generatedMethod.append(property);
generatedMethod.append("();");

CtMethod m = CtNewMethod.make(generatedMethod.toString(), cc);
cc.addMethod(m);

result = (Function)cc.toClass().newInstance();

Sunday, February 1, 2009

Spring by Example Update

I've been working for a while on an update to Spring by Example. It just happens to be the 1.00 release so I wanted it to be a little bit bigger. It's over a years worth of work at this point and I think it shows how much work I've put into it. I'm happy that it's helping people and will continue to work on it as I have time. I wish I had more. Especially to keep doing more work with the Spring dm Server. Below is a list of the lastest examples posted and I'm working on other ones that I'll hopefully be able to finalize over the next month.

Tuesday, December 9, 2008

Maven generating JAXB with the Fluent API

I thought this was interesting and there wasn't a lot of information on this online. It's using the Maven JAXB plugin to generate JAXB classes with the Fluent API. All the regular methods for getting and setting values are available, but there is also an API to chain together setting and creating classes. Thanks to Steve Berman for the Maven config.

Standard API

PersonResponse personList = new PersonResponse();

Person person = new Person();
person.setId(ID);
person.setFirstName(FIRST_NAME);
person.setLastName(LAST_NAME);

Person person2 = new Person();
person2.setId(SECOND_ID);
person2.setFirstName(SECOND_FIRST_NAME);
person2.setLastName(SECOND_LAST_NAME);

personList.getPerson().add(person);
personList.getPerson().add(person2);


Fluent API

PersonResponse personList = new PersonResponse().withPerson(
    new Person().withId(ID).withFirstName(FIRST_NAME).withLastName(LAST_NAME),
    new Person().withId(SECOND_ID).withFirstName(SECOND_FIRST_NAME).withLastName(SECOND_LAST_NAME));


Inside the build element's plugins section, this can be added to generate JAXB beans with the Fluent API.

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <configuration>
        <extension>true</extension>
        <args>
            <arg>-Xfluent-api</arg>
        </args>
        <schemaDirectory>src/main/resources</schemaDirectory>
        <plugins>
            <plugin>
                <groupId>net.java.dev.jaxb2-commons</groupId>
                <artifactId>jaxb-fluent-api</artifactId>
                <version>2.1.8</version>
            </plugin>
        </plugins>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

<repositories>
    <repository>
        <id>maven2-repository.dev.java.net</id>
        <name>Java.net Maven 2 Repository</name>
        <url>http://download.java.net/maven/2</url>
    </repository>
</repositories>

Friday, December 5, 2008

Spring by Example Wins

I was going to really try to get back into working on the book, but I think I realistically don't have the time. I did make a small update to Spring In-depth, In Context before SpringOne started, but I was thinking about how Spring 3.0 is coming out soon so I would need to go through everything again. Posting examples on Spring by Example is less effort since each example is more or less standalone and I'm primarily writing up something specifically on the example. Instead of trying to explain the subject completely, which involves a lot more research and effort. Maybe one day I'll try to get back into working on it, but I actually think hands on examples are probably more valuable. At least that what I always like to see. I typically just want to get going on a project and I'll learn all the nuances of the technology as I go. Possibly the preface and intro from the book can become part of the Spring by Example documentation at some point.

Based on this decision I moved the work I had done for the book to Spring by Example.

Tuesday, December 2, 2008

SpringOne Americas 2008 Presentation

SpringOne has been really interesting so far. Rossen Stoyanchev gave a really excellent presentation on all the nuances and best practices for using Spring MVC Annotations. I'll need to update all my web examples, because there's at least one thing if not more that could be done more elegantly. Like using the @ModelAttribute on a method to populate the model for a form instead of using a dummy method just for a create (so the form has an instance to bind to).

My presentation on GWT & Dojo Cometd with Spring Bayeux is tomorrow morning. I've put a lot of work into the presentation, writing up what I could for Spring In Depth, In Context, and getting the examples cleaned up as much as possible and checked into Subversion. Hopefully the presentation will go well and everyone will find it interesting.

Spring by Example & 'Spring In-depth, In Context'

I've made updates to both sites. Spring by Example doesn't have anything too major, but the last site release updated the Spring by Example Web Module to version 1.1.1. For Spring In-depth, In Context, I finally had time to get the Chat and Trade Monitor examples I made for my SpringOne presentation posted and written up for Jetty. The examples are checked in except for the Trade Monitor example running an embedded Jetty in Tomcat. This is the same as the Trade Monitor that runs under Jetty, was just to show that you could still use Jetty's Bayeux implementation even if you were on Tomcat.

Also I finally had time to post a simple Spring dm Server example showing side-by-side versioning. It has a version 1.0 and 1.1 of a message service. The version 1.0 uses Commons Lang 2.1.0 and version 1.1 uses Commons Lang 2.4.0. There is a web module that just displays the data and you can switch back and forth between the two different message services at runtime. I'll work on this section more to add screen shots and a more detailed explanation of things, but I wanted to get what was ready posted.


Wednesday, November 26, 2008

Maven & No Commons Logging

Maven includes Commons Logging by default, which isn't what you really want if you'd like to use SLF4J for your logging facade. A nice solution to fake out Maven was written at this blog. Basically you have a fake version 99.0 as an empty jar named the same as Commons Logging so it's downloaded instead.

I noticed builds were running really slow and it seems that he Maven repository (http://no-commons-logging.zapto.org/mvn2) has been down for days. As a temporary solution I've put the no Commons Logging jars into the Spring by Example repo and put a mirror entry into my settings.xml.

It would be nice if Maven just had a way to do global excludes if you don't want a jar no matter what transitive dependencies are resolved.


~/.m2/settings.xml
<settings>
  <mirrors>
    <mirror>
      <id>no-commons-logging</id>
      <name>No Commons Logging</name>
      <url>http://www.springbyexample.org/maven/repo</url>
      <mirrorof>no-commons-logging</mirrorof>
    </mirror>
  </mirrors>
</settings>