Monday, April 12, 2010

Java Development Environment for Windows

Since I'm setting up Java software development Environment, thought I would document parts of the process for any potential new Java programmers out there trying to get set up on Windows. Not going to go into every detail...but this would get someone started with commonly used software tools for Java software development and some tips for Windows users.

A few things before we get started:

Some of the instructions below indicate that you should open a command prompt window or type a command. You can get to a command prompt window by going to the start menu, choose run, type cmd and hit enter.

Additionally there are instructions for setting environment variables. To get to those go to Control Panel, click on System, Advanced and Choose Environment Variables. These instructions differ slightly on different versions of Windows but should be pretty close.

When you run Java code it can run using a JRE (Java Runtime Environment) or JDK (Java Development Kit). The JRE is what runs in your browser. It is for people who need to run but not write Java code. The JDK has additional functions for writing and compiling Java code. When configuring development tools, make sure you reference the folder where you download and install the JDK, not folders containing a JRE.

Java

Download java - on the Sun web site choose downloads, SE and the JDK (not
E)

java.sun.com

Run the executable (exe file) you just downloaded to install Java.

Set the JAVA_HOME environment variable:

Go to Control Panel, click on System then Advanced, then Environment Variables. Click new. Type JAVA_HOME for the name of the variable and the path to the directory you stalled java into for the value. For example:

C:\Program_Files\java\jdk1.x.x_xx

Note: the directory you enter sould be the one that contains the \bin folder. In other words for the example above if I look in the directory above I will see a subfolder named "bin".

Eclipse

Eclipse is an "IDE" or program used to write and compile Java code (among other things). Eclipse integrates with a lot of tools and applications. I have found Eclipse used at almost every company I've worked at recently for Java software projects (and some other types of software as well):

Eclipse

Click on downloads and choose one of the options for Java programmers. Either one will work fine to get started but if you know you're using J2EE then you can choose the larger download. Eclipse is Java software so it runs on any platform so you don't need to worry about getting the right version for Windows, Linux, etc. Just download the file, right click to unzip and choose the folder where you want the program files to end up. After unzipped, there will be an "eclipse.exe" file in the folder where you unzipped the files. Double click on it to start the program. You can also right click on it and choose to create a shortcut which you can drop on your desktop, quick launch toolbar or drag to your start menu.

Subversion

Subversion is a "version control" system. It tracks versions of your files so you can go back to previous versions in case of error. It also helps companies track which files were released to production servers so they know which versions of files are in production at any given time, and roll back to a previous successful release in case a new release causes a problem - regardless of what changes happened in between releases.

Subversion is an open source product and the source code can be downloaded from the Apache web site at:

http://subversion.apache.org

If you're on Windows you may not want to go through the build process to compile the software in order to run it - it's a little complicated. Binaries (or the files used to install and run the program on Windows) are offered on the Apache site. Collabnet's version claims to be the "certified" binaries. Always take a look at who writes and supports the software you download and where they are located when considering your options. I took a look around the CollabNet site and saw that Tim O'Reilly of O'Reilly & Associates is on the Board of Directors...figured that was a good sign.

The CollabNet version of subversion can be found here:

Subversion Binaries

Choose to run subversion as a service and it will run every time you start your computer. You can open up Windows services and set it to run manually as well. You'll choose a port on which to run the software - I chose not to run on port 80 (standard web port) so it wouldn't interfere with other things I have running on that port. You can choose a different port, say 81 or 8888 or whatever suits your fancy but doesn't conflict with other software on your machine. Typically you'll run subversion on a server but you can also run it on the same machine on which you develop if you don't have any other option.

Cannot load C:/Program Files/CollabNet/Subversion Server/httpd/modules/mod_dav_svn.so into server

Unfortunately when I opened up Windows Services (Control Panel / Administrative Tools / Services) and tried to start the two CollabNet services, the Apache service would not start. The error in the Windows Application Event Log (Control Panel / Administrative Tools / Event Logs) was:

The Apache service named reported the following error:

>>> httpd.exe: Syntax error on line 116 of C:/Program Files/CollabNet/Subversion Server/httpd/conf/httpd.conf: Cannot load C:/Program Files/CollabNet/Subversion Server/httpd/modules/mod_dav_svn.so into server: The specified module could not be found.

The service basically starts the Apache web server so I manually started the Apache web server by going to the folder in which I installed CollabNet \Subversion Server\httpd\bin\httpd.exe and running that file. That seemed to work fine. However I wanted Subversion to run as a service...

I read in some blog posts that restarting Windows might help...that did the trick.

Test SVN is running

To see if SVN is up and running I went to a command prompt (start / run / type "cmd" and hit enter) and type

svnadmin help

There I get the list of commands available from SVN admin. Seems all good.

Create SVN Repository

To create a new repository (the place where subversion saves your file revisions but in a special format that should only be accessed through subversion commands and tools), I navigate to the place where I want the repository to be. Then type:

svnadmin create myrepo [or whatever you want your repository to be named]

Ouila - repository created.

Running SVN under separate Windows account

You'll want to run this server under it's own user name for a secure environment. Set up a new user account and give it appropriate permissions. I had to use administrator over user but would be preferable to not run as a full-fledged admin or limit the permissions on files for this account to only what is required for proper functioning. Then right click on the service and change the login as to login with the user/name and password you created for this service. That way whatever actions this software takes when running will show up in the logs as "svn" rather than some generic account. This helps track down problems and setting up restrictive permissions for this user will limit potential security problems.

Error 1053 with SVN Serve Service

Another note - started getting error 1053 when I deleted the initial repository directory I configured for SVNServe. If that happens, you can [very carefully] edit Windows registry and change the path used by the service from the directory you initially set up to whatever the valid directory is that this user account has permissions to access. You can see what directory the service is using for the repository by right clicking on the service and looking at the start up information, then search for that in the registry.

SVN Authentication

You probably want to set up user names and passwords so not just anyone can access your SVN Server. There are multiple ways to do this but here's a simple way to start:

Edit the httpd.conf file (search for it or find under apache files where you installed Subversion)

There's a few lines at the end starting with:

<Location /svn>
....

Edit that section as follows:

SVNParentPath should be the folder that contains all your repositories. You can also set up separate locations for each repository using SVNPath instead of SVNParentPath if you need to configure your repositories separately.

You'll add the path to the file that contains users (AuthUserFile) and set a few other options. Read up on this further if you want to know more about all the options.


<Location /svn>
DAV svn
SVNParentPath C:\path\to\folder\containing\repositories
AuthType basic
AuthName "welcome to my repository"
AuthUserFile C:\path\to\users.txt
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>


The above options create read only access to the repository.

You can remove LimitExcept line to give a user full access or change the LimitException options as appropriate for your needs.

Restart Apache service.

That works but the CollabNet documentation says that to ensure you're not passing SVN passwords plain text over the network you'll want to use digest mode. That has some slight variations and more information can be found in Apache documentation - but here's their example which worked for me:


<Location /svn>
DAV svn
SVNParentPath /var/svn
AuthType Digest
AuthName "Subversion repository"
AuthDigestDomain /svn/
AuthUserFile /etc/svn-auth-file
Require valid-user
</Location>
Now we'll need to add a user.

First of all, I had a problem running this command below because the bin folder for Apache was not on my Path. Add that by going to your Control Panel, click System, then the Advanced tab. Very carefully edit the one that is named "PATH" in the list of variables. Add the path to the folder located in the folder in which installed subversion end with /httpd/bin.

For instance if you installed subversion in C:/SVN add C:/SVN/httpd/bin to the end of your PATH environment variable.

Hint: I always copy and paste the path so I don't make a typo...

If there are other things already listed for your PATH variable, which I'm sure there are, precede the following line with a semi-colon (;) if there isn't one there already. Each item on the path is separated with a semi-colon. hit the Apply button and close the window.

Also if you have a command prompt window open close it and open a new one to get the updated path. You can check what the PATH is in your command window and make sure your changes took effect by typing:

set PATH

Navigate to the folder where you specified your users file would be stored in your SVN configuration above.

Type:

htpasswd -c users.txt [username_here_no_brackets]

You'll be prompted to enter a password.

Woop-ti-doo. User created.

Note that if you have a large number of users you will want to consider other options such as storing user names and passwords in a MySQL database. Searching text files can lead to performance issues.

Tortoise SVN

Once you have a version control system set up you open up a command prompt window and type commands to save versions of your files, however it's a lot easier to use Tortoise SVN on Windows. Tortoise SVN provides a nice user interface that allows you to just go to any directory on your machine, right click, enter the URL to your repository and choose "checkout" to get the files in the repository for the first time. You can also easily add new files to your repository by right clicking and choosing "add".

Tortoise SVN can be downloaded here:

Tortoise SVN

Note: Make sure you bypass the ads and scroll to the bottom of the screen to get the correct links.

Prevent Password Caching

One other thing I like to do is turn off password caching so they are not saved on the server or my client machine. To do that the book I have says to change store_passwords=no in the subversion config file -- found with your Windows user account files which on XP would most likely be c:/Documets and Settings/[Your User Name]/Application Data/Subversion but might be different in another scenario).

However I found the following documentation within that file related to this parameter - looks like it gets set in the servers file in the same directory now:

### The rest of this section in this file has been deprecated.
### Both 'store-passwords' and 'store-auth-creds' can now be
### specified in the 'servers' file in your config directory.
### Anything specified in this section is overridden by settings
### specified in the 'servers' file.

Add files to the repository

OK so now it's time to add files to the repository. The typical structure for a project in svn is:

/project
/branches (branches off the main code folder ...read up on this one...)
/tags (snapshots of specific revisions of the code in time - for builds, etc)
/trunk (the main folder where the current code goes)

For more on structuring repositories...read up.

I found this book to be helpful for both Subversion and Tortoise SVN:
Practical Subversion

In order to create a new project in the repository I first created the folder where I wanted my project to live. I set up the three standard folders (tags, branches and trunk). Then right click on the folder ABOVE the top folder I want to go in subversion. Everything below will get added. Choose "subversion" then "import". Enter the URL to the repository. Hit OK.

Note - if you're trying to figure out what the url to your repository should be on your local machine, right click on the folder where your repository is stored and choose "Tortoise SVN / Repo browser". This will pop up the repository browser with the URL in the dialog box. You can just copy it and use it when you right click on your project folder to checkout, add, import and/or commit files.

And from this point on....I leave the rest to your further reading and exploration.....

Maven

Maven is a tool that is used to help "build" or compile Java programs, tracking all the dependencies in a project. It can also help with automated testing, deployment and other aspects of managing software projects.

Maven can be downloaded and installed from:

Maven

For Windows you'll want to download the pre-compiled (binary) version unless you want to compile the software youself and the zip format of the file which will look something like this:

apache-maven-x.x.x-bin.zip

Unzip the files to a location of your choice such as:

C:/Progam Files/Maven

Once unzipped you should see within the above directory a subdirectory called /bin. In other words:

C:/Program Files/Maven/bin

You'll want to add that bin directory to your PATH environment variable as described above for SVN. Find system information, advanced, environment variables. Edit the PATH environment variable and add ;C:/Program Files/Maven/bin (or whatever the path is to the /bin directory where you unzipped the files).

You'll also need ot add a new environment variable. Click the add button. Enter M2_HOME as the variable name and enter the directory that contains the bin folder as the value for the variable (i.e. for example above C:/Program Files/Maven).

Test that Maven is running by going to a command prompt (start/run type cmd and hit enter) and type:

mvn -v

This should print out the Maven version on the screen - ok Maven's running.

Alrighty then, let's create a maven project. Then we can add code to this project and use Maven to build it, test it, generate documentation, etc.

Navigate via command prompt to the folder where you want to create the project. Type something like the following, replacing the Group, Artifact and Package with whatever you want those to be. Group and Artifact identify the project so you can refer to it later. You can read more about those. Package is the Java package that the code will be in - you can read up on Java packages if you're not familiar with those. And by the way "archetype" is a fancy word for a template. So when we generate this project it's based on the standard Maven template for a project - the files and directories that are created when you run this command are based on the default Maven project template or archetype.

mvn archetype:create -DgroupId=com.somecompany.somegroup -DartifactId=component -DpackageName=com.somecompany.xyz

NOTE: Case sensitive. No extra spaces between names, equal signs, and values. No line breaks (which may throw an error like 'xyz is not a recognized internal or external command)

The first time you run this you'll notice Maven downloading a bunch of dependencies it needs to run. This is what Maven does - tracks the dependencies for software projects and grabs them from specified repositories as needed. The files will be downloaded to your local Maven repository the first time and accessed from there after that point. Your local repository on Windows is by default in the typical place Windows dumps your files in an .m2 folder (C:/Documents and Settings/your_name/.m2/repository on XP). This is configurable if you want to change it.

There are advanced ways to configure Maven to only work with certain repositories such as companies that only want employees downloading components from internal locations that have verified, secure versions of code and also minimize Internet network traffic...you can read up on that.

After running the command to create a new project, you can list the files that were created and you'll see the default project structure.

The pom.xml file in the root directory for the project is the file that you will configure to tell Maven what to do with your project. Open this file to see the default configuration that was set up. Hint: Opening with Notepad might not give you the correct line breaks. Use WordPad, IE, etc.

If you navigate within the project to the /src/main/..../App.java file this is the default main class that Maven created for your project. Obviously you can change this as needed.

OK now you have a Maven project. You can use this as a starting point to add code, compile it, run tests, configure plugins, generate documentation, etc.

To compile and put the resulting output into your local repository, you simply type:

mvn install

Maven Dependencies

Look at the pom.xml file that was generated and you'll see a dependency listed - JUnit. More about JUnit later. When Maven builds your project, it will go out and get this dependency and bring it down to your local repository. If your code requires other .jar files to run, you can add them as dependencies to your project following the example for JUnit. When you run "mvn install" Maven will automatically download the dependencies you have specified from the Maven centra repository if they do not exist in your local repository.

In order to find a dependency Maven uses the artifact id and other information in the configuration for that dependency such as version number. So you'll need to get the right information for the particular dependency you're adding to your project.

Dependencies not in Maven Repository

Sometimes you'll find a jar file you want to use is not in the central repository for Maven. In other words whomever created hasn't added it to or doesn't allow it to be added to the main repository managed by Maven so you can download it automatically by just adding the configuration to your pom file. In this case you'll have to install it into your own repository manually. Once it's in your repository you can add it to pom files to include it in projects.

To do this use mvn install:install-file command.

For example if you want to include the Microsoft SQL Server JDBC driver in your project you'll need to download the latest jar file from Microsoft. Open a command prompt and navigate to the directory where you downloaded this jar. If you've downloaded version 3.0 which is sqljdbc.jar type the following command.

mvn install:install-file -Dfile=sqljdbc.jar -DgroupId=com.microsoft.jdbcdriver -DartifactId=sqljdbc -Dversion=3.0 -Dpackaging=jar

Once you've done that you can include this jar in the pom file for a project like this:

<dependency>
<groupId>com.microsoft.jdbcdriver</groupId>
<artifactId>sqljdbc</artifactId>
<version>3.0</version>
</dependency>


Maven Plugins

Maven has a bunch of plugins that can perform various build tasks for you. In order to use a plugin you add it to your pom file. For example if I want to use the SCM plugin which integrates with our source control software (Subversion) I would add it to the default pom.xml that was created above, putting the following at the end before the closing <project> tag:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins
<artifactId>maven-scm-plugin

<configuration>
<!-- your example configuration here -->
</configuration>
</plugin>
</plugins>
</build>

When you type mvn intstall, that plugin will be downloaded if not already in your repository.

NOTE: If you need a specific version you can add that to the configuration. If you get an error that a plugin or dependency could not be downloaded, you can remove the version number to get the version that is available.

You can find a list of Maven Plugins here:

http://mvnrepository.com

Multi-Node Projects

If you want to include childe poms within a parent pom add a modules section to your parent pom file that lists the other pom artifact ids as modules. This way you can have maven run against multiple projects/poms in one step. For instance you might have a library (jar) that contains core classes used in multiple projects with artifactId as "project1" in its pom.xml file. Then you have a library containing the classes specific to the project you are working on with artifactId "project2" its pom file. You want to build both in one step so you create a parent pom and include these additional modues as follows:

<modules>
<module>project1</module>
<module>project2</module>
<modules>

Maven Plugin for Eclipse

Ok you're a Windows user so probably rather not deal with this command line stuff right? Well, then download the Maven Plugin for Eclipse which provides a UI to manage Maven through Eclipse. I found the instructions at the link below to be out of data for the latest version of Eclipse but will tell you more about M2Eclipse:

Maven Plugin for Eclipse

In the version of Eclipse I am using, I had to go to the help menu and choose "Software Updates", click on "Available Software" tab, then "Add Site" button. Then enter "http://m2eclipse.sonatype.org/sites/m2e" in the dialog box that pops up (no quotes) and click "OK". You should see the Sonatype site added to the list of software repositories in the install software dialog box. Check it and click the "Install" button. Follow the steps to install the plugin.

Ok now you can create a new Maven project in Eclise. Choose File | New | Other | Maven Project. This will allow you to generate a new project based on a Maven archetype.

You can also choose to open one the existing project you generated above using the create:archetype command by choosing File | Import | Maven | Existing Maven Projects and choose the directory that contains the pom.xml file for your existing project.

The first time I ran the Eclipse plugin I got an error:

"Maven plugin requires Eclipse to run in JDK...etc."

To fix I did the following:

1. Add the jvm to your eclipse.ini file found in the directory in which you installed Eclipse. Add this line with the correct path to the Java version and install directory you specfied above when you installed Java:

-vm
C:\Java\JDK\1.5\bin\javaw.exe

I noticed that you must put this on two different lines - if you put those two things on the same line it fails. Additionally it worked for me when I inserted it at the beginning of the eclipse.ini file.

I've seem comments in blogs that you'll need quotes around a path with spaces in it, like this:

-vm
"C:\Program Files\Java\JDK\1.5\bin\javaw.exe"

However I found this not to be true and caused an error on one machine I tried this on.

More on eclipse.ini: Eclipse ini

2. In Eclipse choose Window | Preferences. Click (+) next to Java. Click installed JREs. Click Add button. Choose standard vn and Next button. Choose the same directory you added as JAVA_HOME when you installed Java above. Click Finish. I also removed the older version of the JRE since I don't want to end up using it by mistake. For my purposes I just use the latest version of the JDK.

3. I noticed at this point still had a yellow warning about the JDK version in Eclipse for my project referencing 1.4 when 1.4 was not installed. To fix I right clicked on the project node, selected "Build Path", "Configure Build Path", then clicked on the "Libraries" tab. I removed the reference to JDK 1.4. I clicked the "Add Library" button. I chose the option "JRE System Library" which selected the JRE I configured above in Maven (which is actually JDK, not JRE, but whatever).

Next error...apparently Maven uses JDK 1.3 by default. You'll need to tell Maven to use a higher version if you want to use generics or other newer features in higher versions of the JDK. Add the following to your pom.xml file for your poject. I added this after my dependencies node:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>


Maven Book

I found this book helpful for using Maven, however I also found new useful tools that replace plugins in Maven 2.2 that are not documented in this book...so read up on new features in Maven and plug ins online.

Maven: The Definitive Guide

JUnit

JUnit is used to write unit tests. These unit tests basically call various methods in your code and verify tha the code behaves as expected - throwing and catching errors where it should and returning correct values.

An example unit test class was created in the project above we created with the Maven archetype. You'll find this code in the /src/test/java directory. The calss is called AppTest.java. Test classes typically are named the name of the class they are testing plus "Test". you can see that within the class the JUnit classes that run tests are imported at the top. The class extends (read about abstract classes if not familiar) the class TestCase so it can run tests. There's a function that returns the whole suite of tests contained in the class (which happens to be one in this case) and a function that runs a test. You can add more tests to the class following the example. I'll leave it to you to read up on how to write tests.

To run the tests via maven you can run: mvn test

Test are also run as part of: mvn install

To run the tests from within Eclipse you can right click on the class or the particular test in the project explorer tree and choose "Run As" then "Junit Test".

You'll notice that in your pom.xml file the JUnit dependency has in the configuration:

<scope>test</scope>

That means this dependency is needed for test scope only and will not be included for deployment. In other words your final application that you deploy on the web or run as an application doesn't include the tests and the JUnit dependency.

Jetty

Jetty is a web server which is efficient, fast and lightweight. In my opinion it used to be more lightweight and now seems to have a lot of things being stuffed into it. I prefer to strip most of the extraneous elements I don't need and run with a minimal version of the web server that does just what I need - no more, no less. This is both more efficient, less bugs and more secure, since every line of code is a potential bug, takes CPU and memory to process, and is a potential security problem as well. This is personal preference - some people prefer bloated code which makes it easier and faster to get things done at the expense of the other factors.

Jetty was originally created by Greg Wilkins and team but has moved over to Codehaus and can be downloaded here:

Download Jetty

Jetty is used by some well known big technology companies (like Google).

A handy way to develop web apps using Jetty is to run Jetty within Eclipse using Maven. To do that configure the Jetty Plugin and configure it. I have a separate post about that if you're interested as I ran into some issues. Then you can right click on your pom.xml file and run Jetty to test and debug your application within Eclipse as you are working.

Jetty Plugin with Maven and Eclipse

Tomcat

I've also worked at a lot of large and small companies that use Tomcat as their Java web server. Tomcat supports the various Java components you might want to run and is a very good option:

Tomcat

I've used various other Java web servers and app servers such as JBoss, Resin, JRun and JServe [which I don't think even exists anymore] but I would stick with Tomcat or Jetty.

Spring

Spring is a framework for software development used by many companies. It has various components that can be used to configure and build software projects more quickly. It is built using various Software Design Patterns - a concept any good software developer will want to know and use.

Spring can be downloaded here:

SpringSource.org

Hibernate

Hibernate is a software framework used for accessing databases. Hibernate is commonly used along with Spring. It handles various important aspects of database connections that can lead to performance problems and can speed up development of software that works with databases.

Hibernate

Databases

A lot of Java applications end up using databases. The most common are MySQL, SQL Server and Oracle.

MySQL

MySQL has a free, open source version and is used for a lot of different types of projects, small and large. The enterprise version of MySQL is competitive with SQL Server in many ways. In general it's a database that has been much, much cheaper than SQL Server and probably one of the main reasons it has been heavily used besides being a decent solution for most projects - and open source if you're really that geeky and think you want to change database code. I've used MySQL at various companies and it worked just fine.

MySQL

SQL Server

Microsoft SQL Server has a lot of great tools and support and personally I've just used it a lot and like it. I know what it can do and get things done quickly so I typically stick with it given the choice. For large companies it has some features that help integrate with other Windows networking options and is beneficial for highly scalable and robust solutions that require replication, among other things. I also know that a while back Microsoft snagged some of the best database gurus from some of their competitors. I figure if the brightest and best are developing this product it's a good product to choose. It has not let me down. There is a SQL Server express version which appears to be free - check the license for what you can and cannot do with it - and a developer version which last time I checked was under $50. I've also heard of some hosting companies offering SQL Server for web clients at $30/month which is a pretty good deal. The managed companies I've talked to typically charge in the $200-300/month range for SQL Server. I think the limitation of the web version is mainly replication but you'll have to explore that further yourself.

Search for SQL Server downloads at Microsoft.com

Oracle

Some large companies use Oracle but coming from the Northwest in the shadow of the Mothership, I don't see Oracle so much around here anymore. I know it's used for financial applications and such but the web projects I've worked on recently haven't involved Oracle. Oracle used to be "the" database when I started out and was what I started working with...now any of these three options will most certainly meet the needs of the majority of projects.

Find out more about Oracle at Oracle

Access

Access is a good database for a single user on a local machine - say an accountant that needs to import data and run customized reports. Access is *not* a good solution for a web site, a multi-user or networked application. Choose one of the others.

There are other database options, but those are by far the most commonly used databases in business applications.