Spring 2.5.x+3.0.x: Create prototype instances from code

Here follow some snippets to show you the programmatically creation of prototype instances using Spring 2.5.6.SEC01.

a) Create a spring bean with scope “prototype”.

package springsample;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "prototype")
public class Knife {
}

b) Create a spring bean and autowire a ProviderUtil instance (l. 12). The prototype instances are created at line 29 using ProviderUtils.

package springsample;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class KnifeJuggler {

    @Autowired
    ProviderUtil util;

    public void juggle() {
        List<Knife> list = new ArrayList<Knife>();

        for (int i = 0; i < 5; i++) {
            //create 5 prototype scoped instances
            list.add(createKnifeInstance());
        }

        //print each instance
        for (Knife knife : list) {
            System.out.println(knife);
        }
    }

    private Knife createKnifeInstance() {
        return util.getBeanByType(Knife.class);
    }
}

c) The “magic” is coded here. A utility bean named ProviderUtil is defined and the ApplicationContext is autowired (l. 14). The prototype bean now can be resolved using this context: Every time you call ctx.getBean(xxx) to get the bean a new instance will be returned (l. 24). (Because the scope of the target bean is “prototype”)

package springsample;

import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class ProviderUtil {

    @Autowired
    private ApplicationContext ctx;

    public <T> T getBeanByType(final Class<T> claz) throws UnsupportedOperationException, BeansException {
        Map beansOfType = ctx.getBeansOfType(claz);
        final int size = beansOfType.size();
        switch (size) {
            case 0:
                throw new UnsupportedOperationException("No bean found of type" + claz);
            case 1:
                String name = (String) beansOfType.keySet().iterator().next();
                return claz.cast(ctx.getBean(name, claz));
            default:
                throw new UnsupportedOperationException("Ambigious beans found of type" + claz);
        }
    }
}

d) Enable annotation driven spring bean processing. This registers all Spring beans via annotations like @Component.


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
 
    <context:component-scan base-package="springsample"/>
</beans>

e) Sample code to test these snippets

package springsample;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("newSpringXMLConfig.xml");
        //resolve by type
        KnifeJuggler juggler = ProviderUtil.getBeanByType(ctx, KnifeJuggler.class);
        juggler.juggle();
    }
}

e) When running this code 5 different prototype instance will be printed to stdout.


springsample.Knife@f9da4fc
springsample.Knife@36baa466
springsample.Knife@177f409c
springsample.Knife@236acdd1
springsample.Knife@38ee6681
BUILD SUCCESSFUL (total time: 0 seconds)


Alternative a) An alternative would be the usage of javax.inject.Provider from JSR 330, but this is not supported for Spring 2.5.x. Using javax.inject.Provider in Spring 3.0.6 works. Do not forget to include a JSR330-dependency (like JEE6-API in NetBeans).

The code is simpler again: Autowire a provider for the prototype bean (l. 13) and use the provider to get the prototype instance (l. 31).

package springsample;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component(value = "jugglername")
public class KnifeJuggler {

    @Autowired
    Provider<Knife> knifeProvider;

    public void juggle() {
        List<Knife> list = new ArrayList<Knife>();


        for (int i = 0; i < 5; i++) {
            //create 5 prototype scoped instances
            list.add(createKnifeInstance());
        }

        //print each instance
        for (Knife knife : list) {
            System.out.println(knife);
        }
    }

    private Knife createKnifeInstance() {
        return knifeProvider.get();
    }
}

Alternative b) Use ObjectFactory – see the sample at http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/

Automating hudson/jenkins via REST and curl – a very small cookbook

As you know, Hudson supports a RESTful-API. So here a small cookbook using curl (running in cygwin). It is very easy, when you are accustomed to it.

#Get the current configuration and save it locally
curl -X GET http://user:password@hudson.server.org/job/myjobname/config.xml -o mylocalconfig.xml

#Update the configuration via posting a local configuration file
curl -X POST http://user:password@hudson.server.org/job/myjobname/config.xml --data-binary "@mymodifiedlocalconfig.xml"

#Creating a new job via posting a local configuration file
curl -X POST "http://user:password@hudson.server.org/createItem?name=newjobname" --data-binary "@newconfig.xml" -H "Content-Type: text/xml"

Update: Use --data-binary to post the data, else the line-endings won’t be transfered correctly.

Update 2017-08-13: A good post about securing the calls can be found at https://blog.dahanne.net/2016/05/17/how-to-update-a-jenkins-job-posting-config-xml/

[Update] Monitoring tomcat instances

Here are some OSS projects to monitor your tomcat instances (f.e. memory-/cpu-usage, sessions, mbeans)

Off course you can also monitor your tomcat via VisualVM (http://visualvm.java.net/ or included in JDK6)

Update: Or use JRDS http://jrds.fr/

[Quicktip] Importing a “dependencyManagement”-section from an external artefact

Situation: You have a parent pom with defined dependencies in the “dependency management”-section. This way you do not have to provide versions for your dependencies. Standard-Maven-Stuff.

New situation: BUT for some reason you have to switch to another totally different parent pom with totally different “dependency management”-section. Your previously declared dependencies have no version, so there will be errors when invoking maven on this pom.

One solution: A cool thing you can do since Maven 2.0.9 is the import of the “dependency management”. So still no versions required for your previously declared dependencies…

This is accomplished by declaring a pom artifact as a dependency with a scope of “import”.

The offical documentation can be found here

More shortcuts/quickfixes for eclipse

After a short detour to Idea Intellj, i am back to eclipse now and there is still potential to learn new features/shortcuts for improved productivity.

Here a few i was not aware of:

  • Ctrl-3: quick access – all commands, filterable
  • Ctrl-E: to list open files, there you can close the currently selected file by pressing del
  • Alt-Shift-W: Show current file in view xyz
  • F12: go to editor pane
  • Shift-Enter: Create a new line below – no longer Shift-End, Enter
  • Ctrl-Q: go to the last edit location
  • Ctrl-T: Quick type hierarchy
  • Sharing plugins in external folder – how to manage it properly.
  • Pick out part of a string via Quickfix

Mainly influenced by http://eclipseone.wordpress.com/

Any cool missed features or quickfixes out there?

[Quicktip] JMeter – Own graphs/diagrams using csv-export

You want to create good looking graphs, but JMeter doesn’t provide them? You want to compare several testruns and present the results in one graph? But you do not want to code a plugin for JMeter or don’t want to parse the *.jtl file via XSLT?

Then use the easy but often overlooked  csv-export feature of JMeter:

  • Add a listener like “Aggregate Report” (includes 90% line) or “Summary Report” (includes standard deviation) to your project.
  • Record or load your testdata
  • Navigate to the listener and click on the button “Save Table Data” at the bottom and save the result as a file.

That did the trick. You got a CSV file, which you can import into your favourite spreadsheet application and create diagrams from the data.

With a little bit of tweaking the diagram options you can create diagrams like the following example, which compares two testruns. Such type of diagram is easy to understand and shows possible performance improvements in the same scale…