Category: Maven, Spring Integration Gene De Lisa @ 1:19 pm — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

How many poor suckers have wasted time configuring Maven to run the examples for the Spring Integration project? The sources are in a jar included in the download. I’d post a complete maven project but I don’t want to hear from any lawyers.

Here is the POM that I slapped together.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration</groupId>
<artifactId>samples</artifactId>
<packaging>jar</packaging>
<version>1.0.0.RC2</version>
<name>spring integration samples</name>
<url>http://www.springsource.org/spring-integration</url>
<description>spring integration samples</description>

<repositories>
<repository>
<id>springsource-external</id>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>

<repository>
<id>springsource-snapshot</id>
<url>http://repository.springsource.com/maven/bundles/snapshot</url>
</repository>

<repository>
<id>springsource-milestone</id>
<url>http://repository.springsource.com/maven/bundles/milestone</url>
</repository>

<repository>
<id>springsource-release</id>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>

<repository>
<id>apache-maven-snapshots</id>
<name>Apache snapshot repository</name>
<url>http://svn.apache.org/maven-snapshot-repository/</url>
<layout>default</layout>
</repository>
</repositories>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<type>jar</type>
<!--
these are compile time dependencies for log4j and not us. Since
we're not compiling log4j just say no thanks.
-->
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration.adapter</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration.ws</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>org.springframework.integration.stream</artifactId>
<version>${spring.integration.version}</version>
</dependency>
</dependencies>

<properties>
<spring.integration.version>1.0.0.RC2</spring.integration.version>
<!-- the tdeps specify this version. So, here it is if you want more -->
<spring.version>2.5.6</spring.version>
<log4j.version>1.2.15</log4j.version>
</properties>

</project>
Category: RIA Gene De Lisa @ 8:15 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Take a look at the Silverlight showcase. There is a gallery of sites that purport to display the capabilities of Microsoft’s entry into the RIA horserace. Check out this site listed on their gallery: http://www.solardospresuntos.com/VISITAVIRTUAL/tabid/60/Default.aspx.

The technology being used there for the cool panorama is a Java applet. Oops.

Category: Maven Gene De Lisa @ 6:31 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

For some reason log4j 1.2.15 has a compile time dependency on JMX even if you’re not going to compile log4j. Go figure. I’m not the first one to point this out since there is a bug report issued.

What’s worse is that the jars are not in any maven repository due to Sun licensing restrictions. So what do you do? There are two things you can do.

  • Install them to your local repository.
  • Say no thanks

To install the jars to your local repository:

Get the jars from Sun. Download the “JMX 1.2.1 Reference Implementation”.

Then rename them to include the version.

copy jmxtools.jar jmxtools-1.2.1.jar
copy jmxri.jar jmxri-1.2.1.jar

Then install them to your local repo:

mvn install:install-file -DgroupId=com.sun.jdmk -DartifactId=jmxtools -Dversion=1.2.1 -Dpackaging=jar -Dfile=jmxtools-1.2.1.jar
mvn install:install-file -DgroupId=com.sun.jmx  -DartifactId=jmxri    -Dversion=1.2.1 -Dpackaging=jar -Dfile=jmxri-1.2.1.jar

If you also need JMS download them from Sun too.

To say “No thanks”:

You can see the log4j build dependencies at their site. Here they are.

GroupId ArtifactId Version
com.sun.jmx jmxri 1.2.1
com.sun.jdmk jmxtools 1.2.1
javax.jms jms 1.1
javax.mail mail 1.4

So, you can just say “I don’t want them” by excluding them.

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>

<exclusions>

<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>

<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>

<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>

</exclusions>
</dependency>
Category: Eclipse, IDE, Maven Gene De Lisa @ 7:27 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

RAD 7.5 was just released and I just installed it. Lots of improvements. It’s based on Eclipse 3.4 now.

One glitch. I use the Maven plugin on many projects. I cannot install the POM editor. That’s mostly OK with me since I just use the XML editor but sometimes I like to have a second “check” on my pom.

Turns out I’m not alone. Here is the bug. It is mostly the new Update manager P2.

Category: Maven Gene De Lisa @ 12:19 pm — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Ever get this?

[INFO] [keytool:genkey]
[WARNING] Enter keystore password:  Keystore password is too short - must be at least 6 characters

You probably have something like this:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>keytool-maven-plugin</artifactId>
<configuration>
<keystore>${basedir}/target/keystore</keystore>
<dname>cn=Gene De Lisa, ou=Devel, L=Philadelphia, ST=PA, o=Rockhopper, c=US</dname>
<alias>mykey</alias>
<keypass>validpassword</keypass>
<storepass>validpassword</storepass>
<storetype>pkcs12</storetype>
<verbose>true</verbose>
</configuration>
</plugin>

See that dname element? If you reformatted your code in Eclipse perhaps it was split over two lines. It has to be on a single line. So, you problem has nothing to do with the password!

Category: Eclipse, IDE, Maven Gene De Lisa @ 9:46 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

The m2Eclipse plugin has been accepted into the Eclipse Foundation.  Perhaps this will push development along. Already there is a ton of new features in the current release - along with decent documentation!

Thanks!

The update site at codehaus is still alive but it looks like the new versions will be at

http://m2eclipse.sonatype.org/update/

and for those who wish to be bleeding edge the snapshots are at

http://m2eclipse.sonatype.org/update-dev/

Category: Spring Framework Gene De Lisa @ 10:42 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5 out of 5)
Loading ... Loading ...

Let’s say you wrap stored procedures with Spring’s StoredProcedure class like this:

@Repository

public class SPGetWhatever extends StoredProcedure {

   @Autowired

   public SPGetWhatever (DataSource dataSource)etc.

That @Repository annotation like @Component and @Service allows you to tell Spring to scan the
classpath and instantiate them without you having to write a bean element in your Spring XML file.
You can even inject dependencies like the DataSource with the @Autowired annotation as you see here.

You enable it with this in your XML config file:

schema stuff...

<context:annotation-config />

<context:component-scan base-package="com.rockhoppertech.someproject" />
setup the datasource etc.

It will recursively scan the package you specify for these annotations. You will get a bean in your context
with the simple classname. (You can override that if you want).

N.B. this used to be aop:component-scan but it was moved.

Then in some DAO you can do this:

@Repository

public class MyDaoImpl implements MyDao {

@Autowired(required=true)

SPGetWhatever sp;

Pretty cool. Unless you use AOP - and hey, you’re just not hip and happenin’ if you’re not right?

<aop:aspectj-autoproxy/>

Turn the logging level up and you will indeed see Spring create the SP. But then it will fail when creating your
DaoImpl saying that there is no bean that satisfied the dependency on the SP class. But two lines above that
it just said it has the bean in the context. WTF?

Here’s a clue. Do this:

<aop:aspectj-autoproxy proxy-target-class="true"/>

You’ll see that Spring’s StoredProcedure class does not have a default constructor so there is a problem creating the proxy.

What RJ says in his Intro to Spring 2.5 article about StoredProcedures is that you can have them implement an interface blah blah fishcake…
Something like this.

@Repository

public class SPGetWhatever extends StoredProcedure implements SomeBloodyInterface {

etc.

Sure enough that solves the problem. OK, interfaces are good.
A glass of wine is good too. Drinking a vat of wine will kill you.

Category: DB, Spring Framework, Testing Gene De Lisa @ 7:08 am — Comments (0)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

I’ve been taking a legacy codebase, putting testing in place and refactoring. For DB access I retrofitted the persistence classes to be injected via Spring with a DataSource instead of looking them up via JNDI. IN my Spring context I defined a PlatformTransactionManager.

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
scope="singleton" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />

<!-- has a property named dataSource which we autowire -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
autowire="byName" />

Then I refer to it in the the test case class.

@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class MyTestCases extends
   AbstractTransactionalJUnit4SpringContextTests {

etc.

Sure enough the console blathered on about starting and rolling back the transaction. The problem is, it wasn’t. It was just saying it did.

How do I know? I checked.

int nrowsInMyTable;

@BeforeTransaction
public void onSetUpInTransaction() throws Exception   {
   nrowsInMyTable = countRowsInTable("SomeTable");
}

@AfterTransaction
public void verifyFinalDatabaseState()   {
   int rows = countRowsInTable("SomeTable");
   assertEquals(nrowsInMyTable, rows);
}

So what was the problem?

I was doing this like every other J(2)EE programmer.

connection = this.dataSource.getConnection();

But with Spring you need to do this instead to associate the transaction thread with the datasource.

connection = DataSourceUtils.getConnection(this.dataSource);

and

DataSourceUtils.releaseConnection(conn, this.dataSource);

Then it worked.

Category: Selenium, Spring Framework, Testing Gene De Lisa @ 6:43 am — Comments (1)
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

In a previous post I wrote about using JUnit4 with Selenium.

So how about injecting your JUnit run listener via Spring?

My first attempt modified my runner to be a subclass of SpringJUnit4ClassRunner

Then I created the usual XML spring config file but named it after my test class name. So for

FooTests I created FooTests-context.xml. If you want another name you can pass that into
@ContextConfiguration.

Here is a bit of it:

<bean id="Selenium"
	class="com.thoughtworks.selenium.DefaultSelenium">
	<constructor-arg>
		<value>localhost</value>
	</constructor-arg>
	<constructor-arg>
		<value>4444</value>
	</constructor-arg>
	<constructor-arg>
		<value>*firefox</value>
	</constructor-arg>
	<constructor-arg>
		<value>http://localhost:9080/myapp/</value>
	</constructor-arg>
</bean>

Here is is what I have for the test cases

@RunWith(SpringRunner.class)
@ContextConfiguration

public class FooTests() {

   @Autowired
   private Selenium selenium;

  @Test
   public void whatever() {}
}

and the JUnit 4 listener:

public class SpringRunListener extends RunListener {
   @Autowired // wishful thinking
   private Selenium selenium;

etc.

So there is the problem. Spring will autowire testcases but not the runners nor the listeners.

What is the Spring way? Forget the JUnit RunListener. You write a Spring TestExecutionListener.
But that’s not autowired either so you have to grab your beans yourself. Luckily you have access to
the Spring context.

public class MyTestExecutionListener extends AbstractTestExecutionListener {
   private static final Log logger = LogFactory.getLog(MyTestExecutionListener.class);
   Selenium selenium;

   @Override
   public void beforeTestMethod(TestContext testContext) throws Exception {
      // not autowired so go grab it
      selenium = (Selenium) testContext.getApplicationContext().getBean("Selenium");
   }

   @Override
   public void afterTestMethod(TestContext testContext) throws Exception {
      Throwable t = testContext.getTestException();
      if (t != null) {
         report(t); // go ahead and do the screendump using selenium
      }
   }

and to make your listener get used you add it to the list of test execution listeners in your test classes.
I put it in the superclass of my test classes.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@TestExecutionListeners(
{
MyTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class
})

public class FooTests ...

But you say, what about that new @Configurable annotation?
Can’t you use DI on an object that Spring does not instantiate?
Stay tuned.

Category: Selenium, Testing Gene De Lisa @ 10:34 am — Comments (2)
1 Star2 Stars3 Stars4 Stars