26
Sep 10

Money Making Project

For the past several years most of my projects were based on Spring and Hibernate. And what I keep seeing is how people struggle to understand how the two are working together.

So going from project to project, I have to repeat the same spiel over and over again to get people up to speed.

Since I believe that the most effective way to LEARN is to DO, I create simple examples for people to play with / to complete / to analyze, etc..

So “Money Making Project” is one of such examples. It comfortably lives at github’s luxury apartments, so anybody can “git clone” / “fork” and play with it.

Besides making money, this project also demos things such as:

A way to structure a project

Maven based structure ( hence can be easily used by gradle ). Configuration and property files organized under “META-INF/conf”, “META-INF/props”, etc..

A way to separate Spring configs

“tx-spring-config.xml”, “persistence-spring-config.xml”, “service-spring-config.xml”, “repository-spring-config.xml” and “application-context.xml” that includes them all

Properties via PropertyPlaceholderConfigurer

<context:property-placeholder location="classpath:META-INF/props/env.properties"/>

Hibernate overall configuration file

That is injected into AnnotationSessionFactoryBean

Hibernate Named Queries

That are linked to the Hibernate overall config

<mapping resource="META-INF/conf/hibernate/mapping/startup-bank-named-queries.xml"/>

Spring’s DAO / Hibernate Exception Translation

Via @Repository and “PersistenceExceptionTranslationPostProcessor”

Simple CRUD Repository

public interface MoneyRepository {
 
    public void make( MoneyRoll moneyRoll );        // C
    public MoneyRoll find( Long id );                       // R
    public void update( MoneyRoll moneyRoll );     // U
    public void takeOut( MoneyRoll moneyRoll );    // D
}

with a Hibernate based implementation

Transaction Management with Spring AOP

Declarative, on a Service Level, using “aop:config”, “tx:advice” namespaces

Spring Testing

With SpringJUnit4ClassRunner, ContextConfiguration, etc..

Using Embeded in-memory H2 Database for Testing

<jdbc:embedded-database id="dataSource" type="H2"/>

Hibernate Logging

Most useful hibernate “log4j.logger” properties

Demoing how important Transaction is for Hibernate Sessions

“HibernateSessionNotBoundToThreadIntegrationTest” for the second (after LazyInitializationException ) most common Hibernate exception: “No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here”


10
Sep 10

Spring Expression Language: Calling a Method with Parameters

Have you ever wanted to win $1,000,000 with a single SpEL ( Spring Expression Language ) call? Well, now you can, and here is how.

Let’s say there is a Lottery that deposits money to a winner’s bank account and congratulates the winner:

private class Lottery {
    // ...
    public String congratulateWinner( String name, BigDecimal amount, Date date ) {
    	String now = new SimpleDateFormat( "MM-dd-yyyy" ).format( date );
    	String cash = new DecimalFormat( "$#,###,###" ).format( amount.doubleValue() );
 
    	return "Congratulations " + name + "! " +
    	       "Today is " + now + ", and it's your lucky day, because " +
    	       "you just won " + cash + "!";
    }
}

Here is how to make Anatoly win money with SpEL:

"congratulateWinner( 'Anatoly', #amount, #date )"

( of course, let’s not forget to set an amount to at least a million dollars ).

And here is a million dollar unit test:

@Test
public void shouldInvokeMethodWithParameters() {
 
    Lottery lottery = new Lottery();
 
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.set( 2010, 8, 10 );
 
    BigDecimal amount = BigDecimal.valueOf( 1000000.00 );
 
    // letting SPEL know about the "lottery", the "amount" won, and the "date"
    EvaluationContext context = new StandardEvaluationContext( lottery );
    context.setVariable( "amount", amount );
    context.setVariable( "date", calendar.getTime() );
 
    ExpressionParser parser = new SpelExpressionParser();
 
    // using '#' to identify a variable ( NOTE: #this, #root are reserved variables )
    Expression exp = parser.parseExpression( "congratulateWinner( 'Anatoly', #amount, #date )" );
 
    String congratulations = ( String ) exp.getValue( context );	
    assertEquals( "Congratulations Anatoly! " + 
                  "Today is 09-10-2010, and it's your lucky day, because you just won $1,000,000!", 
                  congratulations );
}

(!) Do not write code that does not earn you money :)


09
Sep 10

Check If The Aspect Was Applied

Let’s say you have an aspect defined that will be applied to a class:

<bean id="someComponent"
      class="org.dotkam.SomeComponent" />
 
<aop:config>
	<aop:aspect ref="someAspect">
		<aop:around method="someMethod"
                            pointcut="execution(public * org.dotkam.SomeComponent.*(..))" />
	</aop:aspect>
</aop:config>

and you of course have “proxy-target-class” set to “true”:

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

Here is how to check if the aspect was applied:

import static org.junit.Assert.assertTrue;
import net.sf.cglib.proxy.Enhancer;
 
  ... ...
@Resource(name="someComponent")
SomeComponent someComponent
 
  ... ...
assertTrue( Enhancer.isEnhanced( someComponent.getClass() ) );

Behind the scenes it is enhanced with CGLIB’s Enhancer that has a convenient isEnhanced method.

Useful when developing aspects.

NOTE: The above is true given, of course, that this is THE ONLY aspect applied to this component.


08
Sep 10

Convert String to Map in PHP

Let’s say I would like to have a PHP line:

image( "src => images/logo.png", "class => right", "alt => Company Logo" );

to generate a full blown HTML <img> tag:

<img src="http://www.dotkam.com/images/company-logo.png" class="right" alt="Company Logo">

For this I would need to translate these three function parameters:

"src => images/logo.png", "class => right", "alt => Company Logo"

into a MAP ( yes, PHP calls it an array, but it is in fact a MAP ):

imageTag (
    'src' => 'images/logo.png'
    'class' => 'right'
    'alt' => 'Company Logo'
)

Here is how it is done:

function image( ) {
 
    $validAttributes = array( 'src', 'class', 'alt' );
 
    foreach ( func_get_args() as $attr ) {
    	$attrMap = explode( ' => ', $attr ); 
    	if ( in_array( $attrMap[0], $validAttributes ) ) {
    		$imageAttrMap[ $attrMap[0] ] = $attrMap[1];
    	}
    	else {
    	    die( 'Configuration Problem: ['.$attrMap[0].'] is not a valid &lt;img&gt; attribute.' );
    	}
    }
 
    // .... validate 'src' is there, append imgTag string with all the attrs, echo it...
}

26
Aug 10

Cannot Start Microsoft Outlook. Cannot Open the Outlook Window

Sometimes I have to work on Windows boxes… Here is the fix:

C:\Program Files\Microsoft Office\Office12>outlook.exe /resetnavpane

26
Aug 10

Tomcat: Add Memory

sudo vi /usr/share/tomcat6/bin/catalina.sh

At the beginning of the file, after initial comment block add:

# setting JAVA_OPTS to perform
JAVA_OPTS="-Xms512m -Xmx1024m -XX:MaxPermSize=384m -Xss128k"

Restart tomcat:

sudo service tomcat6 restart

26
Aug 10

Clean Hudson Workspace Before Build

In order to clean/delete the workspace before the build, “Add Build Step”, select “Execute Shell”, and use Hudson $WORKSPACE variable to delete the target directory:

rm -rf $WORKSPACE/target/*

Here is what it will look like:

clean hudson workspace before build

built-in support is on the way: HUDSON-3966


22
Aug 10

Gitolite: Does Not Appear to be a Git Repository

Have a user, whose public key was successfully added under “gitolite-admin/keydir” and whose rights were successfully configured under “gitolite-admin/conf/gitolite.conf”.

When this very user is cloning an existing, correctly configured repository, his/her identity ( public key ) is not being passed correclty => hence notice a password prompt:

$ git clone git@yourgitserver.com:your-project
Cloning into your-project...
git@yourgitserver.com's password: 
fatal: 'your=project' does not appear to be a git repository
fatal: The remote end hung up unexpectedly

Here is the way to help out git / gitolite to understand which identity ( key ) to use:

$ vi ~/.ssh/config
host gitolite
     user git
     hostname yourgitserver.com
     identityfile ~/.ssh/mypubkey

Now changing “git@yourgitserver.com” to “gitolite” does the trick:

$ git clone gitolite:your-project
Cloning into your-project...
remote: Counting objects: 83, done.
remote: Compressing objects: 100% (77/77), done.
remote: Total 83 (delta 3), reused 0 (delta 0)
Receiving objects: 100% (83/83), 156.45 KiB | 49 KiB/s, done.
Resolving deltas: 100% (3/3), done.

Notice, public key was successfully accepted => hence there was no password prompt, and the clone was successful.


21
Aug 10

Making Git to Add Empty Directories

Since git is a “content” based SCM, and empty directories by git are not considered to be content [ which is arguable ], the only way to add them is to add “.gitignore” to every empty directory.

That may sound like a weird task after each time you create a Grails / Rails / Spring Roo / … project, since there are going to be many empty directories right from start.

To ease the pain, here is an alias you can add to your “.bashrc” to use before “git add .”:

# add '.gitignore' to all the empty dirs
alias ged='for i in $(find . -type d -regex ``./[^.].*'' -empty); do touch $i"/.gitignore"; done;'

one liner author: justinfrench.com


20
Aug 10

Connect to Wireless Network at Startup

Assuming WPA/WPA2 security is used, first thing to do is to get a hash/hex of the password. Below “myssid” is the wireless network’s SSID, and “mypassword” is the password for this network.

Step 1 Generate a WPA password hash to be used later when setting up network interfaces:

$ wpa_passphrase myssid
# reading passphrase from stdin
mypassword
network={
	ssid="myssid"
	#psk="mypassword"
	psk=2f0568b3492812bd56b946dbaf3fd7dd669b9a4602a09aa6462ff057949b025c
}

Step 2 Configure a wireless network interface using the password hash from Step 1:

$ vi /etc/network/interfaces
   auto wlan0
 
   # configuring a static IP
 
   iface wlan0 inet static
   address 192.168.0.34
   gateway 192.168.0.1
   network  192.168.0.0
   broadcast 192.168.0.255
   netmask 255.255.255.0
 
   #  OR if static IP is not needed ignore above 6 lines and uncomment the one below
   #  iface wlan0 inet dhcp   
 
   # configure WPA/WPA2 security
   wpa-ssid myssid
   wpa-psk 2f0568b3492812bd56b946dbaf3fd7dd669b9a4602a09aa6462ff057949b025c