Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Tuesday, August 29, 2017

TPC-C current benchmarks for stateful and stateless services running Java.

  • Immediately consistency: 1 box: 2000 requests/second with 5 second response time
  • Eventually consistent: 1 box: 300 requests/second with a 100 millisecond response time.

It is all achivable, if you are not there you need tools to figure out why.
Switch to stateless services whenever possible. A great article about pushing the boundaries and how important it is in HFT is available in barbarians at the gateways.

Monday, March 21, 2016

Maven command to run tests in a selected module and ignore failures and redirect output to a file

This is useful when I want to see all the failed tests, and I want to have it in file so I can easily navigate thru entire output - for example to search for errors.
mvn -f system-tests/pom.xml -Dmaven.test.failure.ignore=true clean install > myout.txt

Tuesday, February 23, 2016

NoClassDefFoundError - classloaders in Java


Key concepts

  1. There is a hierarchy of classloaders
  2. Class loader may delegate to its parent
  3. Parent may load class
  4. If none of loaders loaded the class -> NoClassDefFoundError

Monday, January 25, 2016

Maven command to run System tests from CI

I keep system tests in a separate module. Command run by CI to run them is following:
mvn -X -B -f system-tests/reservationsWS/pom.xml --fail-at-end verify install deploy:deploy

Maven install skipping tests

It speeds up install when I just want to recompile everything:
mvn clean install -DskipTests -DskipITs -DskipSystemTests

Monday, January 11, 2016

Enabling debugging for TomEE+

The simplest way is to edit bin\startup.bat file. Add following two lines:
set JPDA_ADDRESS=8000
set JPDA_TRANSPORT=dt_socket
Modify following line:
call "%EXECUTABLE%" start %CMD_LINE_ARGS%
to.
call "%EXECUTABLE%" jpda start %CMD_LINE_ARGS%
Config options explained on Trifork blog.

Monday, October 26, 2015

InteliJ is a joke part1


I already can see that there will be part2 and followups. I totally do not understand how as popular language as Java lacks a good and modern IDE. I started to write a code in Java 8.

I created a new project and I had to manually point IDEA to a location of my Java SDK - guys how silly is that. Why not figuring out at least the default Java location from PATH, or check JAVA_HOME variable. How about making programmers life easier!

But I still was not able to write using Java 8! First I had to deal with lambda expressions not supported at this language level error. But that wasn't it, then I was greeted with javactask source release 8 requires target release 1.8 problem. Somehow IDEA thought that I was going to code using Java in version 1.5. I can't believe it, I don't have any other version then 1.8 installed on my machine and it is 21 century; why would I want to code by default in Java 1.5?

I will just add that I am using the newest IDEA IDE; current version is 14.1.

Documentation for Maven archetypes

I don't start new projects in Java often. Each time I do it I have to go thru terribly written Maven documentation. 10 maybe 13 years ago when I was writing my first projects with Maven documentation was terrible and absolutely nothing has changed. If I didn't know what I am looking for I would be terribly lost. Even when I know what I want it takes me huge amount of time to figure out how it is labeled in Maven project. Have a look at a difference between Simple and Quickstart project archetypes.
  1. Simple: An archetype to generate a simple Maven project.
  2. Quickstart: An archetype to generate a sample Maven project.

Wow, now I learned something definitely. Guys, what is the difference between simple and sample. Which archetype should be used just to create a playground application to write some code and unit test it. I mean library project type. I just want to run tests on my code to check something.
What a wonderful explanation we get when we dig into a given archetype. When you click on Simple project you see this. What is it - empty page. Maybe some explanation of what do I see here. Not to mention that I would expect to see a in depth explanation of when should I use it and why should I use this one.
I am speeches, how can you have something like that. The sad part is that Maven is not the only project in Jave world that is terrible in documentation.
To answer my question about which archetype to use. I recommend using quickstart, that will create a following project structure.
project
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- App.java
    `-- test
        `-- java
            `-- AppTest.java

Sunday, June 26, 2011

Floating vs Double vs Decimal in C#

For a last few days I'm reading Java Puzzlers book (the older version). I am aware about using decimal formats for money, and data that needs to be calculated precisely. I am testing majority of puzzles against C# language, and I was surprised to figure out that in Java:


System.out.println(1.03 - .42);

The output is

0.6100000000000001


In C#

Console.WriteLine((1.03F - .42F));
Console.WriteLine((1.03D - .42D));

The output is

0.61
0.61


The surprising bit is that in both languages float and double are implemented based on IEEE-754 spec. So why the output differs? I was trying to figure out this by looking it up in a CSharp Spec, but no luck. IEEE specification does not give a strict guidelines of how to implement operations (like add, subtract, multiply), just to implementation of data itself - it should be kept as an exponent number. So I believe that operation implementations are different - maybe due to optimization - but it would be weird, because decimal type was 'invented' to tell explicitly, that a programmer is interested in a precise answer, not a relative accuracy.

Monday, June 20, 2011

Java Pitfall

Recently, I've been interested in some differences between C# and Java. Mainly in how some behaviours are implemented. Consider flowing code:


Byte bigByte = 13;
test(bigByte);

byte smallByte = 14;
test(smallByte);


public void test(Byte b){
System.out.println("byte");
System.out.println(b);
}

public void test(int b){
System.out.println("int");
System.out.println(b);
}



The output is:

byte
13
int
14


I did not expect it. In Java there are mechanisms called widening and autoboxing. Starting from Java 5.0 framework first tries to wide the size of a type that is reserved for it in a memory - in this case Byte is equal to 4 bits, but int reserves 8 bits in a memory. And because before Java 5.0 there was no autoboxing, the framework is trying to find a method that somehow matches the call. Maybe it should throw an error, but designers decided differently. And starting from Java 5.0 the framework is trying to find a method that as an argument also takes a type of a primitive value in this case it is trying to find a type Byte for a byte call.

I understand designers that added autboxing feature, and were trying to keep compatibility with older versions - in a behaviour - this is why Java 5.0 first tries to use widening mechanism and then autoboxing. What concerns me is that the code behaves unnaturally for a person without a knowledge about Java history (when what mechanism was added). In other words, because this code compiles, my first impression is that the method that takes as an argument Byte should be called when I send a message with a byte parameter, but the framework behaves differently.

Thursday, March 24, 2011

Plugins for Eclipse that I use




Yet again, here comes a time when I need to configure my Eclipse environment, and yet again I need to search thru the web for all the pages to the tools that I need. And the winners are:
1. SpringIDE
a) Core / Spring IDE
b) Extensions (Incubation) / Spring IDE
c) Extensions / Spring IDE
2. Susbclipse
a) Core SVNKit Library
b) Optional JNA Library (recommended)
c) Subclipse
3. m2eclipse
a) Maven Integration for Eclipse

In order to configure maven plugin I had to add a following code in a eclipse.ini file (add it before -vmargs line)

-vm
C:\worek\java\jdk1.6.0_24\bin\javaw.exe


I love maven plugin - it allowed me to manipulate pom.xml file (dependencies, plugins,...) by just adding them knowing the name of the dependency (like springframework) and plug-in will search for it and suggest the newest version and create entire xml.


I also tend to use Flash Builder for my Flex development.
The biggest problem is that Flash Builder 4 requires a 32 bit JVM, it will rise an error when you try to run it against 64 bit ("An internal error occurred during: "Creating Adobe Flash Player trust file.."). This error is visible if you use a plug-in version of Flash Builder, the Stand Alone Version of Flash Builder has it's own JVM and it's 32 bit one, it means that stand alone version is not using your environmental settings if you didn't know :) Currently the Eclipse version (Helios) is 3.6.2 and Flash Builder is using 3.4.2. On some operating systems (like Solaris) one can use a flag -d32 in eclipse.ini file in order to tell JVM to run in a 32 bit mode, unfortunately under windows I had to install a 32 bit Java. Unfortunately installing Java in 32 bit version means also installing Eclipse in 32 bit version.

In an addition Tortoise can be downloaded from here and it doesn't require SVN server to be downloaded and installed separately (every two years when I rebuild my machine, or configure it at work I ask myself a question - do I need a server)

Sunday, May 20, 2007

Scala




What is scala? Well folks, it is a statically typed programming language. It is based on OOP paradigm, and it's pretty pure on that - everything is an object, it smells like java here. But java is cheating, and as for now, I can't see any cheating from scala's syntax point of view. What's on my mind is that java distinguishes primitive types from reference types, and also functions are not objects. Right, what is so great about scala? Well, you can run scala from your java and .NET code! Can you see that, this is true write once run everywhere, you don't have to choose between .NET and Java anymore. Scala was pretty much at the end of the list of stuff that I was going to write about, but recently it was used on JavaOne, so I thought that it might be good to write about it now. Scala was developed by Martin Odersky's group. Before that time Martin was the author of current java compiler. Some people saids that this language is the java of the 21 century, SUN cannot change java syntax to scala cause it has to keep the backwards compatibility with java.

You can import any java library to scala and you can import any scala library to java. That's a big plus. It reminds me some presentation from JavaOne in 2006 when somebody said that SUN is promoting java not as a language but as a framework. It means that java has a huge number of frameworks that one can use, it also have many tools, and apps already written - just look at those application servers. What it really sucks on is the language itself - it miss so many things. Lets' go back to scala.

Scala has some functional language specific features but it is NOT a functional language. I've read in a few places that it is, but it is not. Scala is an imperative language!!! If you are interested of what it exactly has, be sure to read this short summary.

Personally I do not like the syntax of it sometimes. For example functions:


def foo(callback: () => unit) {
...
}


what's that, just look at this thing. Why not call callback a function, or do something like this:

def foo(function bar){
...
}


I know, it's because we want to show what we are returning. It's all because of strong typing. Otherwise strong typing purists would scream that it might be confusing, just like they did with type inference in java. But why not to do a literal for that? Or some AI for the compiler - actually this kind of AI is already implemented, cause compiler can guess a return type for methods:


class Foo(bar: double) {
def buzz() = bar
}


Here, I don't have to specify a return type. For those of you who didn't cache that one I'm a week type languages supporter, I just hate to write more than I really have to. And this syntax is quite alike anonymous function syntax so I won't say any bad word anymore.

Let's rock and roll
First thing to do is to configure your favorite environment. Scala's distribution ships with modes for many general use apps. As for 2.4.0 version it binds to: a2ps, emacs, gedit, intellij, jedit, kate, scite, vim, xcode. They are installed in the ${SCALLA_INSTALL_DIR}/share/scala/misc/scala-tool-support. Notice that it's not very common that a tool supports intellij in a standard distribution and not eclipse. Fear not, eclipse plugin is located here. Here is my configuration for GNU/Emacs.

(defvar utils-dir "/home/sagasu/worek")
(setenv "SCALA_HOME" (concat utils-dir "/scala"))
(setenv "PATH" (concat (getenv "PATH")
":" (getenv "SCALA_HOME") "/bin"))
(require 'scala-mode-auto)


Scala and Maven
As for now there is no scala plugin for maven that is ready to use. Google is sponsoring creation of a plugin. So, it's not in any maven repository but you can build it yourself. Grab it from subversion repository:

svn checkout http://maven-scala-plugin.googlecode.com/svn/trunk/ maven-scala-plugin

and build

cd maven-scala-plugin
mvn install


now we can add following lines to our maven project (pom.xml file) in order to compile any scala program:


<build>
<plugins>
<plugin>
<groupId>scala</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>scala-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<uncheckedWarnings>true</uncheckedWarnings>
<deprecationWarnings>true</deprecationWarnings>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>scala</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>scala-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

Thursday, May 10, 2007

Date Parsing and Formating in Java




Sounds simple. There is SimpleDateFormat you may say, or GenericTypeValidator. What's the problem then? Well folks, both libraries are not good enough to parse/format dates.

So we want to allowed users to input dates only in a format "yyyy-MM-dd" or "yyy-MM-dd HH:mm".

Let’s write a unit test for that:


import java.util.Date;

import junit.framework.TestCase;

public class DateTimeFormatTest extends TestCase{
public void testParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01", DateTimeFormat.getDateFormat());
assertNotNull(date);

}
}


OK, now let's write a class:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.validator.GenericTypeValidator;

public class DateTimeFormat {
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd";

public static Date parseDate(String dateValue, String format) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
Date aParsedDate = null;
try {
aParsedDate = simpleDateFormat.parse(dateValue);
} catch (ParseException e) {
return null;
}
return aParsedDate;
}

public static String getDateFormat() {
return DATE_FORMAT;
}

public static String getDateTimeFormat() {
return DATE_TIME_FORMAT;
}

}


So now if we run a test it succeeds. Let's add additional tests.

date = DateTimeFormat.parseDate("2005-01-aa", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.parseDate("2005/01/01", DateTimeFormat.getDateFormat());
assertNull(date);



Hey, it's working again. But wait, what about this one:


date = DateTimeFormat.parseDate("2005-01-01 12:12", DateTimeFormat.getDateFormat());
assertNull(date);

Ups, tests don’t pass. Now there is a way that we can tell SimpleDateFormat to be more strict, just add this line

simpleDateFormat.setLenient(false);

unfortunately it won't work. I guess using this kind of parsing is not a good idea :>

But now let's use GenericTypeValidator. We write a test:

public void testValidatorParseDate() throws Exception {
Date date = DateTimeFormat.validatorParseDate("2005-01-01", DateTimeFormat.getDateFormat());
assertNotNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-aa", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005/01/01", DateTimeFormat.getDateFormat());
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-01 12:12", DateTimeFormat.getDateFormat());
assertNull(date);
}



and we add a method to the class:


public static Date validatorParseDate(String dateValue, String format) {
Date aParsedDate = GenericTypeValidator.formatDate(dateValue, format, true);
return aParsedDate;
}



Hey this one works. Now add additional test case:


date = DateTimeFormat.validatorParseDate("2005-1-1-1", DateTimeFormat.getDateFormat());
assertNull(date);


Ups again failure. This same thing happens to the next test:


date = DateTimeFormat.validatorParseDate("2005-11-11 1:1:1", DateTimeFormat.getDateTimeFormat());
assertNull(date);


Again using this parser is not a good idea, but it's better then SimpleDateFormat. What to do then? I use regexps, but by using them I force myself to write additional regexp for every date pattern that I allow. In showed example I've only used two date patterns "yyyy-MM-dd HH:mm" and "yyyy-MM-dd" but I used to deal with systems with more then 8 date patterns and it gets pretty messy their, witch means that I have to use some more complicated techniques in order to create a good looking code. Now after refactoring, both classes looks as follow:

import java.util.Date;

import junit.framework.TestCase;

public class DateTimeFormatTest extends TestCase{

public void testValidatorParse() throws Exception {
String dateFormat = DateTimeFormat.getDateFormat();
String dateFormatRegexp = DateTimeFormat.getDateFormatRegexp();

Date date = DateTimeFormat.validatorParse("2005-01-01", dateFormat, dateFormatRegexp);
assertNotNull(date);

date = DateTimeFormat.validatorParse("2005-01-1", dateFormat, dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01", DateTimeFormat.getDateTimeFormat(), dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01", dateFormat, DateTimeFormat.getDateTimeFormatRegexp());
assertNull(date);

date = DateTimeFormat.validatorParse("2005-01-01 12:12", DateTimeFormat.getDateTimeFormat(), DateTimeFormat.getDateTimeFormatRegexp());
assertNotNull(date);
}

public void testParse() throws Exception {
String dateFormat = DateTimeFormat.getDateFormat();
String dateFormatRegexp = DateTimeFormat.getDateFormatRegexp();

Date date = DateTimeFormat.parse("2005-01-01", dateFormat, dateFormatRegexp);
assertNotNull(date);

date = DateTimeFormat.parse("2005-01-1", dateFormat, dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.parse("2005-01-01", DateTimeFormat.getDateTimeFormat(), dateFormatRegexp);
assertNull(date);

date = DateTimeFormat.parse("2005-01-01", dateFormat, DateTimeFormat.getDateTimeFormatRegexp());
assertNull(date);

date = DateTimeFormat.parse("2005-01-01 12:12", DateTimeFormat.getDateTimeFormat(), DateTimeFormat.getDateTimeFormatRegexp());
assertNotNull(date);
}

public void testParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01");
assertNotNull(date);

date = DateTimeFormat.parseDate("2005-01-aa");
assertNull(date);

date = DateTimeFormat.parseDate("2005/01/01");
assertNull(date);

date = DateTimeFormat.parseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.parseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.parseDate("2005-1-1-1");
assertNull(date);
}

public void testParseDateTime() throws Exception {
Date date = DateTimeFormat.parseDateTime("2005-01-01 11:11");
assertNotNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11 9:11");
assertNull(date);

date = DateTimeFormat.parseDateTime("2005-11-11");
assertNull(date);
}

public void testValidatorParseDate() throws Exception {
Date date = DateTimeFormat.parseDate("2005-01-01");
assertNotNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-aa");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005/01/01");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-01-01 12:12");
assertNull(date);

date = DateTimeFormat.validatorParseDate("2005-1-1-1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 11:11");
assertNotNull(date);
}

public void testValidatorParseDateTime() throws Exception {
Date date = DateTimeFormat.validatorParseDateTime("2005-01-01 11:11");
assertNotNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 1:1:1");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11 9:11");
assertNull(date);

date = DateTimeFormat.validatorParseDateTime("2005-11-11");
assertNull(date);
}
}



And the main class

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.validator.GenericTypeValidator;

public class DateTimeFormat {
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATE_FORMAT_REGEXP = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$";
private static final String DATE_TIME_FORMAT_REGEXP = "^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$";

/**
* @param dateValue
* @param format
* @param regexp
* @return parsed date if dateValue matches format and regexp, else null
*/
public static Date validatorParse(String dateValue, String format, String regexp) {
Date parsedDate = GenericTypeValidator.formatDate(dateValue, format, true);
return matchRegexp(dateValue, regexp, parsedDate);
}

/**
* @param dateValue
* @param regexp
* @param parsedDate
* @return parsedDate if dateValue matches regexp, else null
*/
private static Date matchRegexp(String dateValue, String regexp, Date parsedDate) {
if(!dateValue.matches(regexp)){
return null;
}
return parsedDate;
}

/**
* @param dateValue
* @return date parsed by SimpleDateFormat
*/
public static Date parseDate(String dateValue) {
return parse(dateValue, getDateFormat(), getDateFormatRegexp());
}

/**
* @param dateTimeValue
* @return date parsed by SimpleDateFormat
*/
public static Date parseDateTime(String dateTimeValue) {
return parse(dateTimeValue, getDateTimeFormat(), getDateTimeFormatRegexp());
}

/**
* @param dateTimeValue
* @return date parsed by GenericTypeValidator
*/
public static Date validatorParseDateTime(String dateTimeValue) {
return validatorParse(dateTimeValue, getDateTimeFormat(), getDateTimeFormatRegexp());
}

/**
* @param dateValue
* @return date parsed by GenericTypeValidator
*/
public static Date validatorParseDate(String dateValue) {
return validatorParse(dateValue, getDateFormat(), getDateFormatRegexp());
}

/**
* @param dateValue
* @param format
* @param regexp
* @return parsed date if dateValue matches format and regexp, else null
*/
public static Date parse(String dateValue, String format, String regexp) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
simpleDateFormat.setLenient(false);
Date parsedDate = null;
try {
parsedDate = simpleDateFormat.parse(dateValue);
} catch (ParseException e) {
return null;
}
return matchRegexp(dateValue, regexp, parsedDate);
}

public static String getDateFormat() {
return DATE_FORMAT;
}

public static String getDateTimeFormat() {
return DATE_TIME_FORMAT;
}

public static String getDateFormatRegexp() {
return DATE_FORMAT_REGEXP;
}

public static String getDateTimeFormatRegexp() {
return DATE_TIME_FORMAT_REGEXP;
}

}


Because both SimpleDateFormat and GenericTypeValidator need to be enhanced in order to work properly I'll stick with SimpleDateFormat, mainly because I don't have to use huge apache library in order to parse anything. Two things bother me. Why do I have to write my own validator, and why there is no way in java to remove this redundancy that I see in tests. I'll live it for the future investigation.

Thursday, May 3, 2007

Unit Testing with Groovy




So we know what the Groovy is and how to eat it. Now it is time to do something useful in terms of methodology. I'm agilist and the thing that I do after knowing constructors and reductors is how to test it. Again Groovy is really helpful, and easy to use. So, you don't need to add additional libraries or do some hacking to use tests in Groovy - they are provided in a default installation. By the default installation i mean get a Groovy from local ftp untar it and there it is ready to be used. So here is a simple example:

Create a class Square.groovy

class Square{
def square(x) {x*x}
}


Create a class SquareTest.groovy

import Square

class SquareTest extends GroovyTestCase{

void testSquare(){
Square square = new Square()
assertEquals( square.square(3),9)
}
}


be sure that both classes are in one catalog. In a command line just type:

groovy SquareTest.groovy


and see the result - everything is fine. It is the easiest xUnit framework that I've seen.
One thing about classes in Groovy - they are public by default, same as methods.

Now let's say that we want to create a framework in maven or we already have one and we want to add some Groovy classes or Groovy test classes. This task is more complicated - because of maven, it is a good tool but sometimes when you search in a xml files for a bug it it terrible, I hate it, but again it is like 200 times better then ant.

so to create a maven project (I'm using maven 2.*) just type:

mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app


Now goto my-app and edit pom.xml add:

<dependency>
<groupid>groovy</groupid>
<artifactid>groovy-all</artifactid>
<version>1.0</version>
<scope>test</scope>
</dependency>


create a folder groovy in my-app/src/main directory and in the my-app/src/test. In other words just in this same place as java folder. And put a *.groovy class there. Go back to the my-app directory, and run:

mvn groovy:compile


to compile main classes.

mvn groovy:testCompile


to compile test classes.

You might ask "Cool, but is there a way to compile classes just by calling normal mvn install or mvn compile?". Yes there is, just add this code to your pom.xml file:


<build>
<plugins>
<plugin>
<groupid>org.codehaus.mojo</groupid>
<artifactid>groovy-maven-plugin</artifactid>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>


Now every time you compile or run tests also groovy classes are going to be included.

Wednesday, April 25, 2007

Old world of Java





I've been coding in Java language for some time now. To be honest I many times complained about features that it just doesn't have. It's really easy to pick some things that are missing there. Hey, but it is going to be better. Recently I've been reading Neal's blog and as I can clearly see it is going to happen. The world of Java is going to receive plenty of goodies in a new Dolphin release, but why wait. Groovy, Nice, SISC-scheme of course are already there. They are not fully featured but they do have "the meat". I don't have to say that sic-scheme is my favorite one, but it is also the most scary one for the typical Java developer so lets begin with something easier - Groovy.

Groovy workspace

This framework is really easy to use and it has a pretty good documentation. So it has plugins for Eclipse, Idea, Emacs, JDeveloper and plenty other editors. Be aware that it is really hard (and I do mean it) to create a good plugin for a highly dynamic language (take a look at those for Ruby, thats what I call fun) so be prepared that sometimes they have hard time telling you what attributes or methods some object has. Right, First cool thing is literals for lists and maps (no need to construct a class). Finally I can create a list just by typing:

By the string "->" I mean "returns".


foo = [1, 3, 4, "sigma", "lambda"]
foo[1] -> 3
foo[3] -> "sigma"


And yes lists are polymorphic just as dictionaries called maps here.


bar = [123:4, "gamma":"omega", "pi":3.14]

bar["gamma"] -> "omega"
bar[123] -> 4


or in a shorter way

bar.gamma -> "omega"

unfortunately when you try to execute

bar.123 an error will accure


This syntaxt is much more modern and in my opinion much better then typical construction with "new" prefix. Im also glad that dynamic and static typing is supported - hey, maybe one day I will be able to do all the tricks that I can do with VB.NET language (now don't laugh it's sad but it is true), but as for now Groovy is not quite yet there.

Next thing that I really missed from python was the string agility, basicly I could use " or ' character as a string and If I wanted to create some complicated string I could just put it into """ block. And here it is ready to use in groovy.


name = "Basho Matsuo"

someXML = """
Fallen sick on a journey,
In dreams I run wildly
Over a withered moor.
${name}
"""



Next sexy thing to investigate is a support for closers - Ladies and Gentlemens finally, Java stops to look like Logo language and introduce some meat that makes your job easier.