Friday, May 23, 2008

Setting up Subversion + Apache

Now onto setting up SVN and apache.


First off, make sure libapache2-svn is installed. Now to the configuration in /etc/apache2/mods-available/dav_svn.conf

Mine looks like this:
<Location /svn/project>
DAV svn
SVNPath /path/to/my/project/svn

AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd
<LimitExcept GET PROPFIND OPTIONS REPORT>
Require valid-user
</LimitExcept>
</Location>


Note: I'm doing something stupid here. I'm create ONE repository for my project as opposed to using SVNParentPath where you could have multiple repositories later. Yes, this is just for one project. We'll go back and fix later. (It's a virtual machine remember!)


Next, create a password:
htpasswd2 -c /etc/apache2/dav_svn.passwd josh


Now, onto our SVN repository. Let's give apache access (while we're at it, let's fix the group from last time too)
sudo chown www-data:www-data -R /projects


Ok, now to throw some random thing in the repostiory and make sure you can see it:

sudo su www-data
cd /some/place/safe
mkdir tmp
touch tmp/README
svn import /some/place/safe/tmp file:///path/to/my/project/svn


Alright... now we restart apache (/etc/init.d/apache2 restart) and it should be up and running! if you're like me shoot over to http://localhost:8888/svn/project and you should see your SVN repostiory. (you should also make sure TRAC sees it).

Well, I think we accomplished something here! Now (if your box is on the net) you can start adding code and tracking changes. Unfortunately we have a little bit more to do before I'm ready to start my project, and that little bit is the maven infrastructure.


Side note:
I was hoping Trac could manage our passwords for SVN (and create new repositories), but it looks like that's a no. Oh well, once again we'll see how annoying it gets. If it gets too annoying, I'll make an extension. I'm hoping to find an alternative to gforge that I can host internally to a company.

Thursday, May 22, 2008

Setting up Ubuntu Development Server

Well, we're off to a rocky start. First off, the Ubuntu server kernel expects a particular processor extension that does not exist in the virtualbox emulation: see here for a fix

Anyway, after a little shell magic, we're up and running. NOW for software. You need to apt-get the following (not exhaustive) list:

trac apache2 libapache2-mod-wsgi svn python python-pysqlite2 openssl maven ant tomcat5.5 libapache2-mod-jk


Now, to test out some of said software. First, make sure you're using some reasonable networking scheme. If you're lame like me and used NAT because you didn't want another interface just now (or you really didn't know what you were doing at the time), the Help for virtual box provides you a method of doing port forwarding from the host to the client. You need to restart the virtual-box GUI after you're done.

Creating a directory for the project

Run the following:
mkdir /path/to/my/project



Setting up Subversion

Run the following:
svnadmin create /path/to/my/project/svn
Obviously replacing the path.

There's some more magic we have to do here eventually (and integrate in with Apache). I'm going to cover this later, as I'm running out of steam.

Installing Trac

you need to set up a trac project:

mkdir /path/to/my/project/trac
trac-admin /path/to/my/project/trac initenv

Enter a project name. I took all defaults except for Subversion location (/path/to/my/project/svn).

You then need to make a file for the WSGI module, mine looks like the following:
import os

os.environ['TRAC_ENV'] = '/path/to/my/project/trac'
os.environ['PYTHON_EGG_CACHE'] = '/path/to/my/project/trac/eggs'

import trac.web.main
application = trac.web.main.dispatch_request

My file is called "main.wsgi" and is located in /path/to/my/project/trac.

Apache Configuration
Now it's time to edit apache configuration (I'm lazy soo....)
sudo vi /etc/apache2/sites-available/default

Ok, inside here we need to change the app to be our TRAC project...

THEN we need to give apache ownership of the TRAC files...
chown -R www-data /path/to/my/project/trac

You now have Trac running on Apache (with an SVN repository).

Trac Plugins
Of course no software distribution is complete without the mandatory downloading of plugins. Trac is no exception. Let's pick out some fun ones:

  • ContinuTrac - Continuum integration. We'll work with this *after* we install continuum on tomcat.

  • GraphViz plugin - Yes... I can make intersting graph-like structures that will be pretty and amaze people from 1980! (Actually I *love* graphviz wiki plugins)

  • WebAdmin - A necessary web admin console. Has a lot of plugins into *it*

  • TagsPlugin - Folksonomy, or Release Tagging or Neither... you figure it out

  • ScreenshotsPlugin - Can has Bling Pix? Kthx

  • TracDownloaderPlugin - For Actually releasing products for download. (vs. libraries via Archiva)



So... if I ever get enough time I might place some script around all this to auto-generate the svn repostiory, trac directory and apache configuration, along with default installs of the plugins. That way you can make new projects quickly and easily AND get all the nice management features (which is the major point of maven).

Recap

So... What did we get this episode?

Source Code Repository (At least visualizing. More work later for http/https access).
Issue Tracker
Project Wiki
File Release System (with some plugin work)


Not bad eh? If we add the "magic project creation script" with a web front end, we might even have something to fight sourceforge with. But onto the *real* meat of this server... the nice Maven integration.

Monday, May 19, 2008

Java Maven Code Server

In need of something to distract myself, I'm planning on setting up a Java/Maven development server when I have spare time. I spent a little bit tonight playing with VirtualBox. VirtualBox is an virtual machine platform that has been bought by sun. There's an open source edition known as VirtualBox-ose. I'm running the personal eval from Sun currently, but may switch to the OpenSource edition for easier updates.


Anyway, the important aspects. What makes a good development server IMHO?

Here's my list of desirables:

  • Continuous Builder -> Apache Continuum on Tomcat (behind apache)
  • Project Management (tracking, wiki + subversion) -> Trac (hopefully behind apache)
  • Artifact Repository (both private and public) -> Apache Archiva on Tomcat (behind apache)
  • Project websites (built continuously) -> php + Apache
  • Build System -> Maven + Ant + Java
  • Nightly Backups (This is a desirable, but it's not critical in anyway (or feasible) for me to do this.), however for now I can do snapshots. until my hard drive dies...
  • No X-Server
  • Ability to snapshot/copy fully-configured (but not yet used) server and use at work.


With virtual machines becoming more prevalent in the server world, I'm surprised we haven't seen more freely available "pre-configured" server images from the open source community. I know Amazon's EC3 offers MANY images to use with their service. Anyway, I'm going to detail how to set up the ubuntu server (at least the difficult section I run into). I'll also (hopefully) point in the direction of some helpful FAQs.

Wednesday, May 14, 2008

Staticly-Duck-Typed

After talking to a coworker about all sorts of neat tricks he does to handle closing resources (using reflection), I had a realization that I should blog about how easy Scala can make this.

First off, we'll discuss scala's type system. Scala allows us to differentiate "type" from "class". A class is something that can be instantiated. A type is more like an interface in java, only a class does not need to implement it. e.g. Below is the code for a "type" closeable. *Any* class that has a close method would "fit" type closeable.

 type MyCloseable = { def close(): Unit }


That's great. Now I have a type of "objects with a close method". (Notice the close method takes no arguments and returns null. Other close methods WILL NOT fit). So... how does this become useful? Let's write a method that will call our close inside a try-catch and log exceptions (using System.err for now).


object CloseUtils {
type MyCloseable = { def close():Unit }

def close(x : MyCloseable) = {
try {
x.close();
} catch {
case _=> //TODO Log to real log
System.err.println("Trouble closing: " + x);
}
}
}


Neato! Now I can call CloseUtils.close(someThingCloseable), and I it will close and make sure we don't have exceptions thrown. Well, that's great, but I think we can do even better. I'm really annoyed with having to remember to close streams when I'm finished. It should just close at the end of the block. Does Scala offer something I can use instead of RRID? Sure does.

The next topic is what Martin Ordesky labeled "Pimp My Libraries" or just implicits. I can define an implicit conversion that the compiler will use to add functionality/methods onto a class. Let me use this with the Closable type to add a "doThenClose" method to closeables. I'm going to define a new class that takes in a closeable as reference, and defines new methods. These methods are then visible on classes of type closeable (duck-typed, remember!) as long as import the implicit functions correctly (import static.class.name._);


object CloseUtils {
type MyCloseable = { def close():Unit }

def close(x : MyCloseable) = {
try {
x.close();
} catch {
case _=> //TODO Log to real log
System.err.println("Trouble closing: " + x);
}
}
/**
* Used to add methods to Closeable types
*/
implicit def pimpCloseable(closeable:MyCloseable) = new PimpedCloseable(closeable);

/**
* Defines new scala-awesome features we want.
*/
class PimpedCloseable(closeable: MyCloseable) {
/**
* Executes a function, then closes the resource.
*/
def doThenClose(f : => Unit) : Unit = {
try {
f
} catch {
case _ => System.err.println("Trouble executing", f);
} finally {
CloseUtils.close(closeable);
}
}
}
}


Ok, so now we're set up, let's make use of our new language feature!

import CloseUtils._;
import java.io._;

var stringWriter = new StringWriter();
stringWriter doThenClose {
for(i <- 1 to 10) {
stringWriter.append("Test safe write " + i + "\n");
}
};
System.out.println("out = " + stringWriter.toString);


Notice how we make no reference to pimpedCloseable or CloseUtils... yet we get the added functionality!

Now, how about returning something from the closure? No problem... time for generics (or templates or whatever scala calls them).


object CloseUtils {
type MyCloseable = { def close():Unit }

def close(x : MyCloseable) = {
try {
x.close();
} catch {
case _=> //TODO Log to real log
System.err.println("Trouble closing: " + x);
}
}
/**
* Used to add methods to Closeable types
*/
implicit def pimpCloseable(closeable:MyCloseable) = new PimpedCloseable(closeable);

/**
* Defines new scala-awesome features we want.
*/
class PimpedCloseable(closeable: MyCloseable) {
/**
* Executes a function, then closes the resource.
*/
def doThenClose[A](f : => A) : Option[A]= {
try {
return Some(f)
} catch {
case _ => System.err.println("Trouble executing", f);
} finally {
CloseUtils.close(closeable);
}
return None;
}
}
}


So the new thing we've done here is use the Option class to have a null-safe return. If f does *not* throw an exception, we return the value it returned. Otherwise we return null. Let's see how a client would use this:


import java.io._;
import CloseUtils._;

object Testing extends Application {

var stringWriter = new StringWriter();
val result = stringWriter doThenClose {
stringWriter.append("Test safe write 2");
stringWriter.toString;
};

// If there is no result, we return the string "Problem reading string!"
System.out.println(result.getOrElse( { "Problem reading string!" }));
}


Notice the getOrElse method. This allows you to provide a default incase the function returned null.


Anyway, hoped you enjoyed my random rant. I definitely learned a lot more about scala writing this sample code (and getting it to compile)

Saturday, May 10, 2008

Give your feedback for better Maven + Eclipse

So... it's 1 am, i'm wired on caffeine and I've spent the last 6 hours in the hospital, so this will be a short post. I plan to do a tribute to the Applied Physics Laboratory sometime in the future, I just didn't have it in me tonight.


However, I did find out that Q for Eclipse (q4e) a.k.a. Eclipse IAM (Integrated Apache Maven?) is calling out for proposals for new features for the 1.0.0 release (to be included in Eclipse 3.5). I sent a minor email requesting some improvements with Maven and RCP development (i.e. I want to write a pom and have it auto-download bundles/source, and have a parent pom instead of a .product file). Anyway, If you're somewhat interesting in directing the future of this great plugin (go download it and use it first), please do so! (q4e-users@googlegroups.com)

Here's the link to the proposed features

Tuesday, May 6, 2008

Hardy as a Heron

This morning, my Ubuntu update manager informs me "There is a new version of Ubuntu available, would you like to upgrade". "Why yes, I would like to upgrade" I replied. To which the update manager said, "Please wait while downloading packages". When I got back from work, things were done. New kernel, all new packages (1300 to be exact) and everything was working. Most of my settings pulled across as well. I'm still floored that linux could be so nice (take THAT SuSE).


I did have two issues, which are as follows:
  • My display was no longer widescreen. Had to fix some issues with it.

  • I was not using the correct compiz manager, so I had to update differently


Other than that, I was really impressed that they deemed Firefox 3 Beta stable enough. However, after an hour of use, I'm noticing no issues with it, and don't really want to go back to Fireslug 2.... err... Firefox 2.

In other news, I'm planning on contributing some code to the Scala plugin. I have a limited time to do so while I can retain my IP rights to the source code, so its hard for me to *not* think about how to implement ahead of time. The "what" to implement was a general call for help from the Scala Plugin developer (specifically an interpreter). I'm hoping with some extra help, Scala can attract the attention of the hard-core Eclipse Plugin developers. My personal wish list of new features is:

  • Ctrl-1 -> fix anything wrong with my code. Add fields, methods, etc.

  • Ctrl-space ++ -> Additional context completion (specifically look through libraries and auto-import packages

  • Ctrl-Shift-T -> Refactorings (renames, pull-up, push-down,etc.)

  • Ctrl-Shift-F -> Source code formatting

  • Ctrl-Shift-O -> Organize imports



In other scala news, I found some great blogs about making Scala based OSGi bundles. I may attempt them within eclipse + equinox (vs. Maven + Felix) and post an entry about it (depending on how free time comes).

Sunday, May 4, 2008

Not Gaven, Not Graven, It's...GMaven!

Finally, Groovy has updated their Maven integration so the rest of the world can make use of the new speed/annotation support. Not only that, the plugin now boasts support of cross-compilation of groovy 1.0, 1.5 AND 1.6-beta1!

Here's a little snippet i used to use in a parent-pom for smaller projects where I might have used Groovy. I've updated it based on the groovy website but didn't have a chance to test the new groovy plugin yet.

This will check to see if a project has a src/main/groovy directory, and if so add the dependencies to the project. The downside is that the Groovy repository is added to the list of repositories to check for EVERY plugin, which is minor in my experience.


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.blogspot.suereth</groupId>
<artifactId>groovy-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<inceptionYear>2008</inceptionYear>
<name>Suereth Groovy Blog Test</name>
<repositories>
<repository>
<id>groovy-maven</id>
<name>Groovy Maven Repository</name>
<url>http://repository.codehaus.org/org/codehaus/groovy/</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>groovy-maven</id>
<name>Groovy Maven Repository</name>
<url>http://repository.codehaus.org/org/codehaus/groovy/</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>Groovy Use</id>
<activation>
<file><exists>src/main/groovy</exists></file>
</activation>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy.maven.runtime</groupId>
<artifactId>gmaven-runtime-default</artifactId>
<version>1.0-rc-3</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>

</plugins>
</build>
</profile>
</profiles>
</project>