Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, January 20, 2013

Unit Testing with HSQLDB

The latest release (2.0.0) of Yank - the Ultra-Light JDBC Persistance Layer for Java, finally contains unit-tested code. This blog is about how HSQLDB was used for performing in-memory unit tests using JUnit. Just like most things, once you know the few tricks, it's really easy.

Once nice feature of HSQLDB is that you can set up 100% in-memory tables, which makes unit testing a snap because you don't need to worry about having a database setup on the machine running the database. The following code snippets show how easy it was to setup a unit test for testing the core JDBC persistance layer code in Yank. While this is specific to Yank, this example should help you unit test any of your JDBC code using HSQLDB. After all, the main trick is to have your database properties setup correctly, as shown in HSQL_DB.properties below.

TestBooksTable.java

package com.xeiam.yank.unit;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.xeiam.yank.DBConnectionManager;
import com.xeiam.yank.PropertiesUtils;
import com.xeiam.yank.demo.Book;
import com.xeiam.yank.demo.BooksDAO;

/**
 * @author timmolter
 */
public class TestBooksTable {

  @BeforeClass
  public static void setUpDB() {

    Properties dbProps = PropertiesUtils.getPropertiesFromClasspath("HSQL_DB.properties");
    Properties sqlProps = PropertiesUtils.getPropertiesFromClasspath("HSQL_SQL.properties");

    DBConnectionManager.INSTANCE.init(dbProps, sqlProps);
  }

  @AfterClass
  public static void tearDownDB() {

    DBConnectionManager.INSTANCE.release();
  }

  @Test
  public void testBooksTable() {

    BooksDAO.createBooksTable();

    Book book = new Book();
    book.setTitle("Cryptonomicon");
    book.setAuthor("Neal Stephenson");
    book.setPrice(23.99);
    int i = BooksDAO.insertBook(book);
    assertThat(i, equalTo(1));

    List<Book> books = new ArrayList<Book>();

    book = new Book();
    book.setTitle("Cryptonomicon");
    book.setAuthor("Neal Stephenson");
    book.setPrice(23.99);
    books.add(book);

    book = new Book();
    book.setTitle("Harry Potter");
    book.setAuthor("Joanne K. Rowling");
    book.setPrice(11.99);
    books.add(book);

    book = new Book();
    book.setTitle("Don Quijote");
    book.setAuthor("Cervantes");
    book.setPrice(21.99);
    books.add(book);

    int[] returnValue = BooksDAO.insertBatch(books);
    assertThat(returnValue.length, equalTo(3));

    List<Book> allBooks = BooksDAO.selectAllBooks();
    assertThat(allBooks.size(), equalTo(4));

    book = BooksDAO.selectBook("Cryptonomicon");
    assertThat(book.getPrice(), equalTo(23.99));

  }
}

HSQL_DB.properties

driverclassname=org.hsqldb.jdbcDriver

# 100% in memory DB
myconnectionpoolname.url=jdbc:hsqldb:mem:aname;shutdown=true
myconnectionpoolname.user=sa
myconnectionpoolname.password=
myconnectionpoolname.maxconn=10

HSQL_SQL.properties

BOOKS_CREATE_TABLE=CREATE TABLE Books (TITLE VARCHAR(42) NULL, AUTHOR VARCHAR(42) NULL, PRICE DECIMAL(10,2) NOT NULL)
BOOKS_SELECT_BY_TITLE=SELECT * FROM BOOKS WHERE TITLE = ?

Ultra-Light JDBC Persistance Layer

Yank is a very easy-to-use yet flexible Java persistence layer for JDBC-compatible databases build on top of org.apache.DBUtils. Yank wraps DBUtils, hiding the nitty-gritty Connection and ResultSet details behind a straight-forward proxy class: DBProxy. "Query" methods execute SELECT statements and return a List of POJOs. "Execute" methods execute INSERT, UPDATE, and DELETE (and more) statements.

Usage is very simple: define DB connectivity properties, create a DAO and POJO class, and execute queries.

Features

  • Depends on light-weight and robust DBUtils library
  • ~13KB Jar
  • Apache 2.0 license
  • Batch execute
  • Automatic POJO and POJO List querying
  • Works with any JDBC-compliant database
  • Write your own SQL statements
  • Optionally store SQL statements in a Properties file
  • Built-in Connection pool

What's Next?

Now go ahead and study some examples, download the thing and provide feedback.



Piece of Cake!!!

Thursday, January 17, 2013

XChange Release 1.3.0

Our Financial Exchange Library for Java, XChange, has seen a lot of active development since the previous release in October 2012. We went from 2 to 7 exchange implementations thanks mostly to the growing community starting to support the project more.

Here's a list of the supported exchanges. More detailed info can be found here, which includes planned future exchange implementations.
  • MtGox - polling and streaming market data, authenticated trading
  • Bitstamp - polling market data, authenticated trading
  • BTC-E - polling market data, authenticated trading
  • VirtEx - polling market data
  • CampBX - polling market data
  • BitcoinCharts - polling market data (Bitcoin Exchange Rates)
  • OpenExchangeRates - polling market data (Fiat Currency Exchange Rates)

Internally, we introduced a new and improved REST interface that sits between our xchange classes and the HttpTemplate class responsible for fetching JSON. It also gives XChange clients access to the raw unmarshalled JSON data if they want it, which was something XChange needed for a long time.

All exchange implementations have full-coverage unit tests.

We've been able to reduce the number of dependencies a lot. One of the main focuses of XChange is to be very lightweight. Most notably is the outdated org.json jar. We dug into the Socket.io code, and painstakingly swapped out the old code with our already-used Jackson JSON code. This is good news for apps like Bitcoinium and Multibit, which both use XChange, for keeping their executable footprint small.

Another major accomplishment with this release, is that the artifacts are now hosted on Maven Central: XChange artifacts on Maven Central

We're thinking about adding an arbitrage API within XChange next as the MtGox, BTC-E, and Bitstamp implementations all contain trading functionality.

Relevant Links

Detailed Exchange Support
Bug Reports and Feature Requests
XChange Home on xeiam.com
XChange artifacts on Maven Central
XChange project on Github

Monday, October 29, 2012

Unit Testing Runtime Exceptions with JUnit4 and Hamcrest

Junit and Hamcrest make unit testing with Java almost enjoyable. In this post, I show how to unit test Exceptions with JUnit4 and Hamcrest. In this over-simplified example, I'm testing a method that always throws an IllegalArgumentException. In real-life the IllegalArgumentException would only be thrown under special circumstances given certain arguments, and those are the ones you want to test with the unit test.

The basic idea is to surround the method you want to test with a try catch block and pass it an argument that will trigger the IllegalArgumentException to be thrown. The fail method call should never be reached, and if it does the unit test should fail. What should happen is that the IllegalArgumentException is caught, followed by a check for the correct message.

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * The following example code demonstrates how to unit test Exceptions with JUnit and Hamcrest
 */
public class ExceptionUnitTesting {

  @Test
  public void test() {

    try {
      blah("asdf");
      fail("Expected exception");
    } catch (IllegalArgumentException e) {
      assertThat(e.getMessage(), is(equalTo("Argument foo is not valid!")));
    }
  }

  /**
   * @param foo
   * @throws IllegalArgumentException - in this test case always
   */
  private void blah(String foo) {

    throw new IllegalArgumentException("Argument foo is not valid!");
  }
}


Piece of Cake!!!

Tuesday, September 11, 2012

Avoiding Name Collisions When Organizing Imports in Eclipse

Is there any way to get Eclipse to automatically give preference to a preferred import when organizing imports? Thankfully, the answer is yes.

For example, I'd like to be able to write:

List myList = new ArrayList();

hit Ctrl + Shift + O and have Eclipse add:

import java.util.List;

And not always ask me which List I want to import:


To tell Eclipse not to ever consider java.awt.List, for example, go to Preferences --> Java --> Appearance --> Type Filters menu. Click add and enter Types you do not want Eclipse to consider for automatic insertion of import statements.


Piece of Cake!!!

Tuesday, August 28, 2012

XChange - Open Source Java API for MtGox Bitcoin Exchange


UPDATE March 9, 2013: Version 1.5.0 released. Support for 10 exchanges.

UPDATE Jan 31, 2013: Version 1.4.0 released. Support for Canadian Virtual Exchange. Mostly bug fixes.

UPDATE Jan 16, 2013: Version 1.3.0 released. Support for many more exchanges. See release notes and also XChange Release 1.3.0 Announcement

UPDATE Oct 11, 2012: Version 1.2.0 released. Support for Canadian Virtual Exchange.

Supported Exchanges

Together with other members from the Bitcoin community, I've recently created a new open source Java library called XChange. XChange is a Java library providing a simple and consistent API for interacting with a diverse set of financial security exchanges including Bitcoin. The first exchange implemented is the world's largest Bitcoin exchange - Mt Gox. The plan is to add more Bitcoin exchanges and other traditional financial exchanges offerring trading APIs such as Interactive Brokers.

As of the most recent release 1.1.0, Xchange offers the following functionality:
  • Support for MtGox Bitcoin Exchange (public) polling market data (ticker, depth, trades, etc.)
  • Support for MtGox Bitcoin Exchange (private) polling trade data (account info, market order, limit order, cancel order open orders, etc.)
  • Support for MtGox Bitcoin Exchange (public) streaming market (ticker)
Next up on the todo list is:
  • Support for MtGox Bitcoin Exchange (public) streaming market (depth, trades, etc.)
  • Support for MtGox Bitcoin Exchange (private) streaming trade data (account info, market order, limit order, cancel order open orders, etc.)

Relevant Links

Project Home - http://xeiam.com/xchange.jsp
Code on Github - https://github.com/timmolter/XChange
Example Code - http://xeiam.com/xchange_examplecode.jsp

Examples

The following examples demonstrate getting Ticker data from MtGox, first using the polling API, and second using the streaming API.

Ticker via Polling API

package com.xeiam.xchange.examples.mtgox.v1.polling;

import com.xeiam.xchange.Currencies;
import com.xeiam.xchange.Exchange;
import com.xeiam.xchange.ExchangeFactory;
import com.xeiam.xchange.dto.marketdata.Ticker;
import com.xeiam.xchange.service.marketdata.polling.PollingMarketDataService;

/**
 * Test requesting polling Ticker at MtGox
 */
public class TickerDemo {

  private static PollingMarketDataService marketDataService;

  public static void main(String[] args) {

    // Use the factory to get the version 1 MtGox exchange API using default settings
    Exchange mtGox = ExchangeFactory.INSTANCE.createExchange("com.xeiam.xchange.mtgox.v1.MtGoxExchange");

    // Interested in the public polling market data feed (no authentication)
    marketDataService = mtGox.getPollingMarketDataService();

    // Get the latest ticker data showing BTC to USD
    Ticker ticker = marketDataService.getTicker(Currencies.BTC, Currencies.USD);
    double value = ticker.getLast().getAmount().doubleValue();
    String currency = ticker.getLast().getCurrencyUnit().toString();
    System.out.println("Last: " + currency + "-" + value);

    System.out.println("Last: " + ticker.getLast().toString());
    System.out.println("Bid: " + ticker.getBid().toString());
    System.out.println("Ask: " + ticker.getAsk().toString());

    // Get the latest ticker data showing BTC to EUR
    ticker = marketDataService.getTicker(Currencies.BTC, Currencies.EUR);
    System.out.println("Last: " + ticker.getLast().toString());
    System.out.println("Bid: " + ticker.getBid().toString());
    System.out.println("Ask: " + ticker.getAsk().toString());

    // Get the latest ticker data showing BTC to GBP
    ticker = marketDataService.getTicker(Currencies.BTC, Currencies.GBP);
    System.out.println("Last: " + ticker.getLast().toString());
    System.out.println("Bid: " + ticker.getBid().toString());
    System.out.println("Ask: " + ticker.getAsk().toString());

  }

}
Result:
Last: USD-5.14739
Last: USD 5.14739
Bid: USD 5.12011
Ask: USD 5.1299

Last: EUR 4.07
Bid: EUR 4.0527
Ask: EUR 4.07

Last: GBP 3.3452
Bid: GBP 3.3
Ask: GBP 3.34091

Ticker via Streaming API

package com.xeiam.xchange.examples.mtgox.v1.streaming;

import java.util.concurrent.BlockingQueue;

import com.xeiam.xchange.Currencies;
import com.xeiam.xchange.Exchange;
import com.xeiam.xchange.dto.marketdata.Ticker;
import com.xeiam.xchange.mtgox.v1.MtGoxExchange;
import com.xeiam.xchange.service.marketdata.streaming.StreamingMarketDataService;

/**
 * Test requesting streaming Ticker at MtGox
 */
public class TickerDemo {

  public static void main(String[] args) {

    TickerDemo tickerDemo = new TickerDemo();
    tickerDemo.start();
  }

  private void start() {

    // Use the default MtGox settings
    Exchange mtGox = MtGoxExchange.newInstance();

    // Interested in the public streaming market data feed (no authentication)
    StreamingMarketDataService streamingMarketDataService = mtGox.getStreamingMarketDataService();

    // Get blocking queue that receives streaming ticker data
    BlockingQueue tickerQueue = streamingMarketDataService.requestTicker(Currencies.BTC, Currencies.USD);

    // take streaming ticker data from the queue and do something with it
    while (true) {
      try {
        // Put your ticker event handling code here
        doSomething(tickerQueue.take());
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * Do something fun with the streaming data!
   * 
   * @param ticker
   */
  private void doSomething(Ticker ticker) {

    System.out.println(ticker.toString());
  }

}
Result:
Ticker [timestamp=2012-08-26T20:09:13.202Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3078691906206]
Ticker [timestamp=2012-08-26T20:09:18.651Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:19.568Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:23.152Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:23.975Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:24.790Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:25.205Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:26.018Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Ticker [timestamp=2012-08-26T20:09:26.543Z, last=USD 10.6, bid=USD 10.55248, ask=USD 10.6, tradableIdentifier=BTC, volume=3068691906206]
Piece of Cake!!!

Monday, August 27, 2012

Running Average and Running Standard Deviation in Java

Today I needed to generate statistics for a simulation in real-time, which forced me to code a class that calculates the running average and running standard deviation of incoming data. I remember doing this a long time ago for another project based on MATLAB, but today I needed a Java implementation. The following code example shows how to calculate the running average and running standard deviation for streaming data. Thanks to Subluminal Messages for the simple math implementation!

The Code

public class RunningStatDemo {

  public static void main(String[] args) {

    RunningStatDemo rsd = new RunningStatDemo();
    rsd.go();
  }

  private void go() {

    RunningStat rs = new RunningStat();
    rs.put(1);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());

    rs.put(1);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());

    rs.put(10);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());

    rs.put(20);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());

    rs.put(50);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());

    rs.put(50);
    System.out.println("ave: " + rs.getAverage());
    System.out.println("std: " + rs.getStandardDeviation());
  }

  public class RunningStat {

    private int count = 0;
    private double average = 0.0;
    private double pwrSumAvg = 0.0;
    private double stdDev = 0.0;

    /**
     * Incoming new values used to calculate the running statistics
     * 
     * @param value
     */
    public void put(double value) {

      count++;
      average += (value - average) / count;
      pwrSumAvg += (value * value - pwrSumAvg) / count;
      stdDev = Math.sqrt((pwrSumAvg * count - count * average * average) / (count - 1));

    }

    public double getAverage() {

      return average;
    }

    public double getStandardDeviation() {

      return Double.isNaN(stdDev) ? 0.0 : stdDev;
    }

  }

}

Results

ave: 1.0
std: 0.0
ave: 1.0
std: 0.0
ave: 4.0
std: 5.196152422706632
ave: 8.0
std: 9.055385138137417
ave: 16.4
std: 20.354360712142253
ave: 22.0
std: 22.794736234490628

Piece of Cake!!!

Sunday, August 26, 2012

Create Javadocs for a Multi-Module Maven Project

In this tutorial, I show how to create Javadocs for a multi-module Maven project. Creation of Javadocs requires the use of the Maven maven-javadoc-plugin plugin and running "mvn javadoc:aggregate" on the parent pom.xml. For the sake of this tutorial, I'm taking some excerpts from one of my current Open Source Projects - XChange.

Relevant Links

XChange on Github - To see an actual working example
Javadocs for XChange on xeiam.com - To see what the generated Javadocs look like.

How To

Step 1: Add the following to the parent pom.xml file:

<build>
  <pluginmanagement>
    <plugin>
      <groupid>org.apache.maven.plugins</groupId>
      <artifactid>maven-javadoc-plugin</artifactId>
      <version>2.8.1</version>
    </plugin>
  </pluginManagement>
  <plugins>
    <plugin>
      <groupid>org.apache.maven.plugins</groupId>
      <artifactid>maven-javadoc-plugin</artifactId>
    </plugin>
  </plugins>
</build>
Step 2: Run the following mvn command:

mvn javadoc:aggregate

Piece of Cake!!!

See also: Maven Project Compiles in Eclipse but Maven Build Fails
See also: Using Maven Offline
See also: Hello World - Maven, M2Eclipse and Eclipse

Saturday, August 25, 2012

Java XChart Library Now Supports Error Bars

XChart provides a super light-weight and dependency-free charting API for Java. It is open source, hosted on Github, and is licensed with an Apache 2.0 license. I created it over a year ago because I was looking for and couldn't find an easy-to-use plotting library for Java that was similar to the MATLAB's charting tool. I tried JFreeChart of course, but I found that the learning curve was very steep. Like MATLAB's charting functions, I just wanted to simply pass my data to an API, and after a few lines of code, have a plot.

I just recently added support in XChart for making plots with error bars, which is what this post is about. The following demo, shows how to add error bars to an XChart chart. BTW, if you have any feature requests for XChart, please feel free to open a new issue on Github here. For more XChart exmaples go here.

XChart - Open Source Charting API

To use XChart, you first need to get the XChart jar, which is available here. If you use Maven, just add the following to your dependencies in pom.xml:
<dependency>
  <groupId>com.xeiam</groupId>
  <artifactId>xchart</artifactId>
  <version>1.1.0</version>
</dependency>

The XChart artifacts are currently hosted on the Xeiam Nexus repository here:
<repositories>
  <repository>
    <id>xchange-release</id>
    <releases/>
    <url>http://nexus.xeiam.com/content/repositories/releases</url>
  </repository>
  <repository>
    <id>xchange-snapshot</id>
    <snapshots/>
    <url>http://nexus.xeiam.com/content/repositories/snapshots/</url>
  </repository>
</repositories>

Error Bars Example Code

package com.xeiam.xchart.example;

import java.util.ArrayList;
import java.util.Collection;

import com.xeiam.xchart.Chart;
import com.xeiam.xchart.series.Series;
import com.xeiam.xchart.series.SeriesColor;
import com.xeiam.xchart.series.SeriesLineStyle;
import com.xeiam.xchart.series.SeriesMarker;
import com.xeiam.xchart.swing.SwingWrapper;

/**
 * Create a Chart with error bars
 * 
 * @author timmolter
 */
public class Example8 {

  public static void main(String[] args) {

    // generates data
    int size = 10;
    Collection xData1 = new ArrayList();
    Collection yData1 = new ArrayList();
    Collection errorBars = new ArrayList();
    for (int i = 0; i <= size; i++) {
      xData1.add(i);
      yData1.add(10 * Math.exp(-i));
      errorBars.add(Math.random() + .3);
    }

    // Create Chart
    Chart chart = new Chart(600, 400);

    // Customize Chart
    chart.setChartTitleVisible(false);
    chart.setChartLegendVisible(false);
    chart.setAxisTitlesVisible(false);

    // Series 1
    Series series1 = chart.addSeries("10^(-x)", xData1, yData1, errorBars);
    series1.setLineColor(SeriesColor.PURPLE);
    series1.setLineStyle(SeriesLineStyle.DASH_DASH);
    series1.setMarkerColor(SeriesColor.GREEN);
    series1.setMarker(SeriesMarker.SQUARE);

    new SwingWrapper(chart).displayChart();
  }

}

Resulting Plot

Piece of Cake!!! See also: Java Web Apps - Integrating Charts into a Servlet

Wednesday, May 2, 2012

Install Sonar on Windows as a Windows Service

This short tutorial shows how to setup Sonar as a Windows Service on Windows.

Step 1: Download Sonar from the Sonar download website.


Step 2: Unzip the .zip file and move the entire 'sonar-3.0' directory to 'C:\Program Files'.

Step 3: Double-click C:\Program Files\sonar-3.0\bin\windows-x86-64\StartSonar.bat to start Sonar. If your machine is 32-bit, run C:\Program Files\sonar-3.0\bin\windows-x86-32\StartSonar.bat instead.

Step 4: Verify it's running. Open up a browser and go to: http://localhost:9000/. You should see the following...


Step 5: Setup Sonar to start as a Windows Service. Double-click C:\Program Files\sonar-3.0\bin\windows-x86-64\InstallNTService.bat. If your machine is 32-bit, run C:\Program Files\sonar-3.0\bin\windows-x86-32\InstallNTService.bat instead.

Step 6: Restart the computer.

Step 7: Verify again that it's running. The Sonar Windows service should start Sonar when the machine boots up. Open up a browser and go to: http://localhost:9000/. For administration features, the Sonar default login/password is admin/admin.

One Small Issue

After restarting the computer and checking if Sonar was running, Sonar was not running. After some digging, I found that you can look in C:\Program Files\sonar-3.0\logs\sonar.log to debug Sonar. The following log messages hinted at the problem:

INFO | jvm 1 | 2012/05/02 12:55:26 | WrapperSimpleApp: Encountered an error running main: java.lang.IllegalStateException: Unable to create file in temporary directory, please check existence of it and permissions: C:\Windows\system32\config\systemprofile\AppData\Local\Temp\
INFO | jvm 1 | 2012/05/02 12:55:26 | java.lang.IllegalStateException: Unable to create file in temporary directory, please check existence of it and permissions: C:\Windows\system32\config\systemprofile\AppData\Local\Temp\
INFO | jvm 1 | 2012/05/02 12:55:26 | at org.sonar.application.StartServer.canCreateTemporaryFiles(StartServer.java:60)

Apparently, Sonar is trying to write to a temp file and Windows is not letting it. After all failed attemps to create the Temp folder manually and remove the write protection, I ended up solving the issue by manually configuring the Windows Service. The Sonar Windows Service's "user" was LocalSystem by default. I had to switch the service over to run under a regular user, and that fixed the issue.

Piece of Cake!!!

Relevant Links

Sonar on Wikipedia
sonarsource.org

Sunday, April 29, 2012

Continuous Integration Using Jenkins, Git, and Maven

This tutorial demonstrates how to set up Jenkins, Git, and Maven to work together and provide a smooth continuous integration system. While the examples shown here are on a Windows machine, the concepts are the same for other operating systems such as Linux or Mac OS X, and with slight adjustments, can be adapted accordingly. This article assumes the following is installed and running on the system:

Why CI?

Continuous integration attempts to automate building and testing of source code at regular intervals in order to alert a team as early as possible about problems and merging issues.

From Wikipedia: Continuous Integration, "In software engineering, continuous integration (CI) implements continuous processes of applying quality control — small pieces of effort, applied frequently. Continuous integration aims to improve the quality of software, and to reduce the time taken to deliver it, by replacing the traditional practice of applying quality control after completing all development."

From Martin Fowler: "Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly."

Configure Jenkins

Step 1: Enable security. From the Jenkins dashboard, navigate to 'Manage Jenkins' and then 'Configure System'. Note: Newer versions have this under "Configure Global Security" instead.

1.a. Check 'Enable security'

1.b. Choose 'Jenkins's own user database'

1.c. Uncheck 'Allow users to sign up'

1.d. Choose 'Matrix-based security'

1.e. Enter an admin username next to 'User/group to add:'

1.f. Check all rights for the user.


1.g. Click 'Save'

1.h. Enter log in information for the admin user in the form that appears.


Step 2: Add a JDK. From the Jenkins dashboard, navigate to 'Manage Jenkins' and then 'Configure System'.

2.a. Click 'Add JDK' and enter Name and JAVA_HOME.


2.b. Click 'Apply'

Step 3: Add Maven information.

3.a. Click 'Add Maven' and enter Name and MAVEN_HOME.


3.c. Click 'Save'

Step 4: Add Git information.

4.a. From the Jenkins dashboard, navigate to 'Manage Jenkins' and then 'Manage Plugins'.

4.b Click on the 'Available' tab and search using the browser (CTRL+F) for 'git plugin'.

4.c. Check 'Git Plugin' and click 'Download now and install after restart'. The install can take a while.

4.d. From the Jenkins dashboard, navigate to 'Manage Jenkins' and then 'Configure System'.

4.e. Add Git information.


4.f. Add Git user and email info under section "Git Plugin".



4.g. Click 'Save'.

Step 5: Configure a Jenkins Job.

5.a. From the Jenkins dashboard, navigate to 'New Job'.

5.b. Enter a 'Job Name' and select 'Build a maven2/3 project'. Click 'OK'.


5.c. Enter a 'Description'.

5.d. Select 'Discard Old Builds'.

5.e. Enter an amount by 'Max # of builds to keep'.


5.f. Select 'Git' and enter a 'Repository URL'. If you wanted to track a git repo on Github, this is where you would enter the git URL.


5.g. Check 'Poll SCM' and add '* * * * *' to 'Schedule'. '* * * * *' is a cron expression which means 'every minute'.

5.h. Under 'Build' add a Maven goal in 'Goals and options'.


5.i. Click 'Save'.

Step 6: Run the Job.

6.a. From the Jenkins dashboard, run the new job by clicking the clock with arrow icon on the far right. If everything is set up correctly, the job should run and a blue ball should appear. You may have to refresh the page after the job runs to refresh the ball.


If you need to debug a Jenkins job either while it is running or after it is finished, you can view console output. From the dashboard, click on the job name. Once on the job's page, hover over a link in the 'Build History' section and select 'Console Output'.


Also, when you push new commits to the git repo, Jenkins should recognize that and start the job automatically.

Piece of Cake!!!

Helpful Links

Install Jenkins on Windows as a Windows Service
Hello World - Maven, M2Eclipse and Eclipse
Setup Git on Windows

Saturday, April 28, 2012

Install Jenkins on Windows as a Windows Service

Installing Jenkins on Windows and setting up a Jenkins Windows Service, which starts Jenkins automatically whenever Windows is restarted is now easier than ever since there is a Jenkins Windows install wizard for it. This short tutorial shows how to setup Jenkins on Windows.

Step 1: Download the Windows native package from the Jenkins main website.


Step 2: Unpack the .zip file.

Step 3: Click through the install wizard.





Step 4: Verify that Jenkins is running. Open up a browser and go to: http://localhost:8080/. You should see the following:


Piece of Cake!

Friday, April 27, 2012

Hello World - Maven, M2Eclipse and Eclipse

This tutorial takes you through all steps needed to create a Hello World Java Application using Maven, M2Eclipse and Eclipse from scratch. The instructions are geared toward a Windows machine, but you should probably be able to easily adapt the steps to apply to Linux or Mac OS X.

Eclipse

Step 1: Download Eclipse. Download the lastest version of Eclipse at the Main Eclipse download page. You can download which ever flavor of Eclipse you like the best. I chose Eclipse IDE for J2EE Developers.


Step 2: Install Eclipse. Unpack the Eclipse .zip file and move the entire folder 'eclipse' to the 'Programs' folder on the hard drive.

M2Eclipse

Step 3. In Eclipse, go to Help --> 'Eclipse Marketplace...' and search for 'Maven'. Click on 'Install' for the m2eclipse plugin title 'Maven Integration for Eclipse'.


Step 4: Click through the wizard, installing m2eclipse.

Maven (Optional)

Installing Maven is optional because M2Eclipse does have its own embedded version of Maven. I chose to install Maven separately for two reasons. First, I wanted the latest and greatest version of Maven. Secondly, I plan to run a CI server (Jenkins) that needs access to Maven, and I wanted M2Eclipse and Jenkins to both use the same Maven install. If you don't plan on installing Maven separetely, skip to step 10.

Step 5: Download Maven. Download the lastest version of Maven at the Main Apache Maven download page choosing the binary .zip file for Windows.


Step 6: Install Maven. Unpack the Maven .zip file and move the entire folder 'apache-maven.x.x.x' to the 'Programs' folder on the hard drive.

Step 7: Set environment variables (adjust according to your setup):

JAVA_HOME C:\Program Files\Java\jdk1.6.0_25
M2_HOME C:\Program Files\apache-maven-3.0.4
M2 %M2_HOME%\bin

Path ;%M2%;%JAVA_HOME%\bin

Step 8: Verify Maven install with 'mvn -- version' at the command line. Note, if you had the command line open before changing the environment variables, close it and reopen it.

>mvn --version
Apache Maven 3.0.4 (r1232337; 2012-01-17 09:44:56+0100)
Maven home: C:\Program Files\apache-maven-3.0.4
Java version: 1.6.0_25, vendor: Sun Microsystems Inc.
Java home: C:\Program Files\Java\jdk1.6.0_25\jre
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "x86", family: "windows"

Step 9: Configure m2eclipse. In Eclipse, go to Window --> Preferences

9.a. Under Maven --> Installations, specify an external Maven install by clicking 'Add...' next to 'Select the installation used to launch Maven'. By default m2eclipse selects it's own embedded Maven version.


9.b. Under Maven --> User Settings, specify a settings.xml by clicking 'Browse...'. I chose to put the settings.xml file inside Mave's conf folder.


9.c. Edit the settings.xml file and specify the location of the local Maven repository. I chose 'C:\Program Files\apache-maven-3.0.4\repository'. After editing settings.xml click the 'Update Settings' in 'User Settings' from the previous step.


A repository in Maven is used to hold build artifacts and dependencies of varying types. The local repository refers to a copy on your own installation that is a cache of the remote downloads, and also contains the temporary build artifacts that you have not yet released.

Hello World

Step 10: Create Maven Project in Eclipse.

10.a. In Eclipse open the New Project Wizard by clicking File --> New --> Project. Under 'Maven' select 'Maven Project' and click 'Next'.


10.b. On the next page of the wizard, check 'Create a simple project' and click 'Next'.


10.c. Give a 'Group Id' and an 'Artifact Id' and click 'Finish'.



Step 11: Create a class with a main method in src/main/java. In this case I created MelloMavenMain.java.


Step 12: In the main method, log a message using slf4j. I chose to use a 3rd party library to do this to demonstrated how to depend on 3rd party libraries in the next step.


Logger logger = LoggerFactory.getLogger(HelloMavenMain.class);
logger.info("Hello Maven!");

Step 13: Add the slf4j dependency in the project's pom.xml file.



  
    org.slf4j
    slf4j-simple
    1.6.4
  

Step 14: Package your program. Right-click on the project and choose Run As... --> 'Maven Install'. This will create a jar file for your project in the 'target' directory.

Piece of Cake!!!

Helpful Links

Maven Documentation
m2eclipse
Maven Eclipse Plugin

Tuesday, April 24, 2012

Fixing Unsatisfiedlinkerror - Can't Find Dependent Libraries

After I finally got my Java JNI code working on my Windows development machine that sets the local time of the computer from Java, I discovered it was not working on the production machine. I got the dreaded Unsatisfiedlinkerror - Can't Find Dependent Libraries runtime error. Following is an explanation of why it was happening and what I did to fix it...

The Cause - Visual Studio C++ 2010 Express

In order to find what dependent library was missing on the production machine that was present on my development machine, I downloaded and installed Dependency Walker. After analyzing my generated DLL I saw something unexpected.


What the heck is MSVCR100.DLL?? It turns out it's added by Visual Studio C++ during the build of the DLL, and it is NOT necessary.

The Solution

There seem to be several solutions to this problem, but the most elegant in my opinion to to configure Visual Studio to not make the built DLL dependent on it in the first place. Here's how to do that: Right click on the DLL project and open up the properties dialog. Under Configuration Properties -> C/C++ -> Code Generation -> Runtime Library select "Multi-threaded (/MT)". source


Rebuild your DLL and verify with Dependency Walker that the rogue dependency is gone.


Piece of Cake!!!

Monday, April 23, 2012

Uninstall Stubborn Java JRE or JDK from Windows

Having trouble uninstalling or fixing Java from a Windows 7 machine like I did? I somehow managed to mess up my Java installation and was receiving an error 1723 along the way while trying to uninstall the 64-bit version of Java 6 (in my case version 6.0.31). It was complaining about not being able to find a certain file which it apparently needed for the uninstall. What I did was the following:

Step 1: Locate the following folder:

C:\Users\<User>\AppData\LocalLow\Sun\Java\jdk1.7.0_x64

and make a copy of it in

C:\Users\<User>\AppData\LocalLow\Sun\Java

If it isn't there, you need to downlaod and install Java jdk1.7.0_x64.

Step 2: Rename the copied folder to

C:\Users\<User>\AppData\LocalLow\Sun\Java\jdk1.6.0_31_64

Step 3: Rename

C:\Users\<User>\AppData\LocalLow\Sun\Java\jdk1.6.0_31_64\jdk1.7.0.msi

to

C:\Users\<User>\AppData\LocalLow\Sun\Java\jdk1.6.0_31_64\jdk1.6.0_31.msi

Following those steps combined with some restarting of Windows allowed me to Uninstall my corrupt Java 6 version. Make sure you replace <User> above with your Windows user name.  I hope that helps someone!

Monday, January 30, 2012

Java Web App in Tomcat Dropping Sessions

Want to integrate charts into your webapp? Check out XChart.

Here's another nano-blog that will hopefully help someone solve an problem that I was dealing with today:

Problem

I upgraded Tomcat from 7.0.22 to 7.0.25 and my web application starting closing or dropping the session that was being created during a user login operation. I also noticed in my log files, which tracks sessions being created and closed that tons of sessions were being created at once.

Solution

I'm not sure why this helps or why the problem suddenly appeared in a new release of Tomcat, but what I ended up doing to solve the problem was to add <%@ page session="false" %> to all my JSP files. Apparently for each JSP file, a session is otherwise created. In my web app I have several JSPs nested inside of other JSPs, which was probably causing all the sessions to be created. Why that was never an issue before, I'm not quite sure.

I hope that helps someone!

Sunday, December 25, 2011

Serialize an Object to a JSON String in Java Using Gson

To serialize a specified object or bean into its equivalent Json representation in Java we can use Google's GSON library. First create a serializable object and set its fields to some values. Next new up a com.google.gson.Gson object. Finally call the Gson objects's toJson() method passing it your serializable object.


import com.google.gson.Gson;

// The following example code demonstrates how to serialize a Bean
// object to a JSON String using the GSON library from Google.

public class Bean2JsonUsingGson {

    public static void main(String[] args) {

        SampleBean sampleBean = new SampleBean(3.14, "xyz", 42);
        Gson gson = new Gson();
        String json = gson.toJson(sampleBean);

        System.out.println(json);
    }

    static class SampleBean {

        private double value1;
        private String value2;
        private int value3;

        // Constructor
        SampleBean(double value1, String value2, int value3) {
            this.value1 = value1;
            this.value2 = value2;
            this.value3 = value3;
        }
    }
}

Here is the output of the example program:
{"value1":3.14,"value2":"xyz","value3":42}

Piece of cake!!!

Tuesday, December 6, 2011

Set Font Style in an Excel File Using Java and POI

To create an Excel file and style a cell's font in Java we can use Apache's POI library. First a HSSFWorkbook object is created and a HSSFSheet object is added. A HSSFRow is added to the sheet, and a HSSFCell is added to the row. To sent the font style of a cell's content, a HSSFFont object is created, customized, and applied to a HSSFCellStyle object which in turn is applied to a cell in the spreadsheet. The following sample code was successfully tested with POI versions 3.6 and 3.7.



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

// The following example code demonstrates how to create an Excel  
// file using the org.apache.poi library and style the font in a cell.

public class StyleExcelFileFont {

    public static void main(String[] args) {

        HSSFWorkbook workbook = new HSSFWorkbook();

        HSSFSheet firstSheet = workbook.createSheet("Sheet 1");

        // Write a String in Cell 2B
        HSSFRow row1 = firstSheet.createRow(1);
        HSSFCell cell2B = row1.createCell(1);
        cell2B.setCellValue(new HSSFRichTextString("Sample String"));

        // Style Font in Cell 2B
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle = workbook.createCellStyle();
        HSSFFont hSSFFont = workbook.createFont();
        hSSFFont.setFontName(HSSFFont.FONT_ARIAL);
        hSSFFont.setFontHeightInPoints((short) 16);
        hSSFFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        hSSFFont.setColor(HSSFColor.GREEN.index);
        cellStyle.setFont(hSSFFont);
        cell2B.setCellStyle(cellStyle);

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(new File("/Temp/Test5.xls"));
            workbook.write(fileOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}


Here is a screenshot of the generated Excel File:


Piece of cake!!!

Monday, December 5, 2011

Set Background Color and Add Border to a Cell in an Excel File Using Java and POI

To create an Excel file and style a cell with a background color and a border in Java we can use Apache's POI library. First a HSSFWorkbook object is created and a HSSFSheet object is added. A HSSFRow is added to the sheet, and a HSSFCell is added to the row. To add a String to the cell, a HSSFRichTextString is used. To add a background color to the cell and add a border, a HSSFCellStyle object is applied to the cell. The following sample code was successfully tested with POI versions 3.6 and 3.7.



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

// The following example code demonstrates how to create an Excel  
// file using the org.apache.poi library and style the cell by setting
// its background color and adding a border.

public class StyleExcelFileCells {

    public static void main(String[] args) {

        HSSFWorkbook workbook = new HSSFWorkbook();

        HSSFSheet firstSheet = workbook.createSheet("Sheet 1");

        // Write a String in Cell 2B
        HSSFRow row1 = firstSheet.createRow(1);
        HSSFCell cell2B = row1.createCell(1);
        cell2B.setCellValue(new HSSFRichTextString("Sample String"));

        // Style Cell 2B
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle = workbook.createCellStyle();
        cellStyle.setFillForegroundColor(HSSFColor.YELLOW.index);
        cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        cellStyle.setBorderTop((short) 1); // single line border
        cellStyle.setBorderBottom((short) 1); // single line border
        cell2B.setCellStyle(cellStyle);

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(new File("/Temp/Test4.xls"));
            workbook.write(fileOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Here is a screenshot of the generated Excel File:


Piece of cake!!!

Sunday, December 4, 2011

Read Contents of an Excel File using Java and POI

To get the content from an Excel file in Java we can use Apache's POI library. First a file is imported from disk passing a FileInputStream object to a org.apache.poi.hssf.usermodel.HSSFWorkbook object. In this example only the first sheet was parsed. To access the cell content of the entire sheet, each row is iterated followed by iterating over each cell in the row. For each cell, the content is simply read using the getStringCellValue() method from the HSSFCell object. The following sample code was successfully tested with POI versions 3.6 and 3.7.

Here is a screenshot of the test file I used for this example:





import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

// The following example code demonstrates how to parse the contents
// of all cells in the first sheet of an Excel spreadsheet file

public class ReadExcelFile {

    public static void main(String[] args) {

        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("/Temp/Test1.xls");

            HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);

            HSSFSheet sheet = workbook.getSheetAt(0);

            Iterator rows = sheet.rowIterator();
            while (rows.hasNext()) {
                HSSFRow row = (HSSFRow) rows.next();

                Iterator cells = row.cellIterator();
                while (cells.hasNext()) {
                    HSSFCell cell = (HSSFCell) cells.next();

                    System.out.println(cell.getStringCellValue());
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Here is the output of the program:
Hello
There
Piece of cake!!!

Monday, November 28, 2011

Create an Excel File using Java and POI

To create an Excel file in Java we can use Apache's POI library. The example file created by the following example code demostrates how to add a String, a Date, a Boolean, and a Number to specified cells in the spreadsheet. First a HSSFWorkbook object is created and a HSSFSheet object is added. A HSSFRow is added to the sheet, and a HSSFCell is added to the row. To add a String to the cell, a HSSFRichTextString is used. To add a Date to the cell, a HSSFCellStyle is used in conjunction with a HSSFDataFormat object appied to a Date object. A Boolean value and a Number value are added directly to the cell. The following sample code was successfully tested with POI versions 3.6 and 3.7.


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

// The following example code demonstrates how to create an Excel  
// file using the org.apache.poi library. In the sample file,
// a String, Date, Boolean, and Number are added to individual cells
// in the spreadsheet.

public class CreateExcelFile {

    public static void main(String[] args) {

        HSSFWorkbook workbook = new HSSFWorkbook();

        HSSFSheet firstSheet = workbook.createSheet("Sheet 1");

        // Write a String in Cell 1A
        HSSFRow row1 = firstSheet.createRow(0);
        HSSFCell cell1A = row1.createCell(0);
        cell1A.setCellValue(new HSSFRichTextString("Sample String"));

        // Write a Date in Cell 2B
        HSSFRow row2 = firstSheet.createRow(1);
        HSSFCell cell2B = row2.createCell(1);
        cell2B.setCellValue(new Date());
        // Format the Date so it looks like a date
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle = workbook.createCellStyle();
        cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
        cell2B.setCellStyle(cellStyle);

        // Write a Boolean in Cell 3C
        HSSFRow row3 = firstSheet.createRow(2);
        HSSFCell cell3C = row3.createCell(2);
        cell3C.setCellValue(true);

        // Write a Number in Cell 4D
        HSSFRow row4 = firstSheet.createRow(3);
        HSSFCell cell4D = row4.createCell(3);
        cell4D.setCellValue(3.14);

        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(new File("/Temp/Test3.xls"));
            workbook.write(fileOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


Here is a screenshot of the generated Excel File:


Piece of cake!!!