MathJax

SyntaxHighlighter

Highlight

Custom CSS

Sunday, September 7, 2008

Arguments against checking in your .project and .classpath files

Update

Note that using Maven is not always a solution to this problem; many projects just don't warrant Maven, plus there are a lot of (working) systems that are already heavily invested in Ant, and would not see a big enough benefit to move to Maven. So, assuming Maven is not being used...

Quite often I see that the .project and .classpath files are checked into the SCM in a project, which can be convenient if all the developers use Eclipse in exactly the same way. They can quickly check out the project and fire up Eclipse on a new computer and just start working on it; the alternative being to configure the project manually and adding in all the jar dependencies painstakingly (if you use ant). Many open source projects do this, including the Eclipse guys, so it can't be that bad of an idea right? Right - there are benefits to checking these files in, as I've just discussed. However, each of these touted benefits create more problems, and I will discuss them in turn:

Convenience and pollution

The general argument goes that any files or metadata that helps a developer get up and rolling should be checked in. But unless the project is intended to only be developed in Eclipse, users of other IDEs will start suggesting checkins for Netbean's nbproject folder or IDEA's *.iml files. Of course, these are just the Big Three IDEs; taking the argument further would just cause lots of folders and files not directly related to the project to pollute the project space. If I wanted to take the argument even further I'd check in my own .vimrc and add an ant task to silently overwrite the developer's ~/.vimrc (but at least in that case, a clear line has been crossed).

Convenience and maintenance

Once these files are checked in, they need to be maintained. If I configure my Eclipse project differently (not unlikely as different developers have different tastes), I will see project changes in subclipse, and it will prompt me to check in my changes when I commit. This is only a minor inconvenience, but when the actual .classpath and .project files get updated, I may get conflicts, which could totally screw up my project.

Absolute paths and global classpath variables

A big part of the problem .classpath and .project files can contain absolute paths, such as the path to a jar or a path to a linked resource. Luckily, the judicious use of classpath variables can virtually eliminate this problem. For example, setting SCALA_HOME/lib/scala-library.jar as a library, instead of /home/minhuang/dev/scala/lib/scala-library.jar allows the developer to specify SCALA_HOME and have all the dependencies satisfied without absolute paths mangling the project. However, a problem still exists when working with multiple projects.

Suppose I have two locations for SCALA_HOME: one that uses the newest version, and one that uses an older version. If the library authors were nice, and the older version differs only in minor version numbers, this probably wouldn't be a problem (as you'd expect the newest version to be backwards compatible). However, the differences between major versions are usually... well, major, and you're unlikely to see compatibility. This means that different projects will need SCALA_HOME pointing to different locations, but this isn't possible, as classpath variables are shared globally.

Solution?

Many people have proposed a solution to this: do nothing. Despite all these arguments, many people still think that checking in these files is the right way to go, and maybe it is (a project with only a handful of developers who use Eclipse in exactly the same way). I don't expect any change from these people, but for a big open source project with many contributors, a better route would be to check in a project.sample and classpath.sample, similar to the way build.properties.sample is usually checked in. An ant task like ant eclipse could copy these files over to .project and .classpath respectively, adding only one extra step for those developers who use Eclipse and absolutely must have the convenience; this way, everybody wins!

Thursday, August 14, 2008

Moving the MySQL data directory in Ubuntu

There are lots of guides on the internet that tell you how to move your data directory. Most of them fail to mention that for Ubuntu, AppArmor will render those directions useless in a silent way. If you've followed everything to the letter, and MySQL still refuses to start for some reason, tail /var/log/syslog. If you see something like this:

May 7 15:51:55 vcke-gl-linux mysqld_safe[5886]: started
May 7 15:51:55 vcke-gl-linux kernel: [ 82.391726] audit(1210139515.249:2): 
  type=1503 operation="inode_create" 
  requested_mask="w::" denied_mask="w::" 
  name="/mnt/fastdata/var/lib/mysql/vcke-gl-linux.lower-test" 
  pid=5888 profile="/usr/sbin/mysqld" namespace="default"
May 7 15:51:55 vcke-gl-linux mysqld[5890]: 080507 15:51:55 [Warning] Can't create test file
  /var/lib/mysql/vcke-gl-linux.lower-test
May 7 15:51:55 vcke-gl-linux kernel: [ 82.393387] audit(1210139515.259:3): 
  type=1503 operation="inode_create" 
  requested_mask="w::" denied_mask="w::" 
  name="/mnt/fastdata/var/lib/mysql/vcke-gl-linux.lower-test" 
  pid=5888 profile="/usr/sbin/mysqld" namespace="default"
May 7 15:51:55 vcke-gl-linux mysqld[5890]: 080507 15:51:55 [Warning] Can't create test file 
  /var/lib/mysql/vcke-gl-linux.lower-test
May 7 15:51:55 vcke-gl-linux kernel: [ 82.487247] audit(1210139515.349:4): 
  type=1503 operation="inode_create" 
  requested_mask="w::" denied_mask="w::" name="/mnt/fastdata/tmp/ib7jXL82" 
  pid=5888 profile="/usr/sbin/mysqld" namespace="default"

...then you'll know the problem applies to you. For security reasons, AppArmor will restrict MySQL to reading and writing from certain specified directories, listed in /etc/apparmor.d/usr.sbin/mysqld. If you edit that file and add the new data directory, you'll be golden. You might also need to change mysql's home directory in /etc/passwd, or create a symlink to the new home.

Tuesday, August 5, 2008

Installing IBM JDK 6.0 on Ubuntu

The IBM JDK offers performance benefits over Sun's JDK, which is especially useful when playing around with, say, the Scala interpreter. Installing it on Ubuntu can be a little tricky, but here's how you do it:

  1. Download the IBM JDK version 6 here.
  2. Install fakeroot and java-package with sudo apt-get install fakeroot java-package.
  3. Edit /usr/share/java-package/ibm-j2sdk.sh and add this on line 28:
    "ibm-java-sdk-6.0-1.0-linux-i386.tgz" ) # SUPPORTED
        j2se_version=1.6.0${revision}
        j2se_expected_min_size=82 # 85983232 bytes
        found=true
        ;;
    
  4. Navigate to the directory where the JDK was downloaded and execute fakeroot make-jpkg ibm-java-sdk-6.0-1.0-linux-i386.tgz.
  5. Install the debian package that was created.
  6. Type sudo update-alternatives --config java to choose to use the IBM JDK.

Note: Previously, I had always installed JDKs manually, but if you want to use the JDKs that come in the repositories, make sure to pick up libreadline-java and libjline-java to make it easier to work with the scala interative shell.

Tuesday, June 10, 2008

Scala: Querying an object's fields and methods with reflection

Sometimes you might want to know what the methods and fields of an object are while playing around in the Scala interpreter. Rather than holding off on what you were doing and looking through the API docs (or wishing there were a Scoogle), you can query an object for its methods dynamically using Java reflection. It won't be as painful as doing it in Java, as you can use implicit definitions to get the methods of an object just by typing object.methods (a la Ruby).

Here's what it'll look like:

scala> // This gives you a list you can work with if you want
scala> 1.methods
res8: List[String] = List(hashCode, reverseBytes(int), compareTo(Integer), 
compareTo(Object), equals(Object), toString(int,int), toString(int), ...

scala> // This prints out the methods so there is no truncation
scala> // I just truncated the list to save space.
scala> 1.methods_
hashCode, reverseBytes(int), compareTo(Integer), compareTo(Object), 
equals(Object), toString(int,int), toString(int), toString, toHexString(int), 
decode(String), getChars(int,int,char[]), valueOf(String,int), ...

scala> // Again, I truncated to save space
scala> 1.methods__
hashCode
reverseBytes(int)
compareTo(Integer)
compareTo(Object)
equals(Object)
toString(int,int)
toString(int)
...

The code, as it turned out, introduces a lot of Scala concepts which might overwhelm a newbie (and most of the time, newbies - like me - are the ones who would want to do this in the first place), so I've posted the code at the end, which you can just put into a file and type import ScalaReflection._ to make it work. If you want to know about how this all actually works, read on.

First of all, implicit definitions allow you to define a coercion that the compiler should apply when convenient. As in Java, we can't just add methods to an existing class (in this case, the class Any), however, we can define new classes with those methods, and coerce when necessary. For example, when 1.methods is called, Scala will see that method methods doesn't exist, and coerce into an AnyExtras which declares methods.

In the linked code, you'll see that AnyRef and AnyVal are treated differently. This is because Scala uses the underlying system's primitives in the case of value types like ints, doubles, chars, etc. In Java's case, ints are coerced into java.lang.Integer; however, Scala defines scala.runtime.RichInt for cases when Integer just won't cut it. This is unfortunate for our case because, silent conversions to both classes take place when using integer literals and the conversions can fail if there is ambiguity. The ambiguity here is the getClass method, which is defined in both java.lang.Integer and scala.runtime.RichInt; when getClass is called on a scala.Int, Scala won't know which conversion to apply. Of course, we want java.lang.Integer, and in general, we'll want the Java wrapper. So prior to querying the object for methods, we wrap object appropriately (if necessary) and cast it as an AnyRef if not.

Also notice the usage of NameTransformer from the scala-compiler artifact. Java (and probably .NET languages) will not allow methods with most non-alphanumerics, but Scala is much more liberal. As a result, something like def ==(...) is encoded as def $eq$eq(...), and rather than seeing that in your output, the transformer can decode $eq$eq back to ==. Other than that, we just get the methods of the object, strip away the scope qualifiers and the throws clauses, and print out the names as Strings.

Here's the code:

import scala.Console._
import scala.tools.nsc.util.NameTransformer._
 
object ScalaReflection {
  implicit def any2anyExtras(x: Any) = new AnyExtras(x)
}
 
class AnyExtras(x: Any) {
  def methods_ = println(methods.reduceLeft[String](_ + ", " + _))
  def methods__ = methods.foreach(println _)
  def fields_ = println(fields.reduceLeft[String](_ + ", " + _))
  def fields__ = fields.foreach(println _)
  
  def methods = wrapped.getClass
      .getDeclaredMethods
      .toList
      .map(m => decode(m.toString
                        .replaceFirst("\\).*", ")")
                        .replaceAll("[^(]+\\.", "")
                        .replace("()", "")))
      .filter(!_.startsWith("$tag"))
  
  def fields = wrapped.getClass
      .getDeclaredFields
      .toList
      .map(m => decode(m.toString.replaceFirst("^.*\\.", "")))
 
  private def wrapped: AnyRef = x match {
    case x: Byte => byte2Byte(x)
    case x: Short => short2Short(x)
    case x: Char => char2Character(x)
    case x: Int => int2Integer(x)
    case x: Long => long2Long(x)
    case x: Float => float2Float(x)
    case x: Double => double2Double(x)
    case x: Boolean => boolean2Boolean(x)
    case _ => x.asInstanceOf[AnyRef]
  }
}

Tuesday, May 20, 2008

Typing mechanisms redux - Part 1

Everybody and their grandmother has a has a definition of the following terms:

  • Static typing
  • Dynamic typing
  • Strong typing
  • Weak typing
  • Strict typing
  • Loose typing

A quick search on Google will reveal several different (and usually mutually exclusive) definitions for each of the terms, with some egregious offenders offering conflicting definitions on the same site.

Confusion

Here are just some random examples I found using Google:

  • "[Strong typing means] Strict enforcement of type rules with no exceptions. All types are known at compile time." - [dictionary.die.net]
  • "Static typed programming languages are those in which variables need not be defined before they're used." - [sitepoint.net]
  • "From my POV, strong typing prevents mixing operations between mismatched types" - [artima.com weblogs]
  • "[Ruby is] dynamically but strongly typed (strongly typed as: in Ruby "6" + "2" will give you "62" but in a loosely typed language like Perl or TCL that would give you 8)" - [blogs.codehaus.org]
  • "MATLAB is dynamically typed, meaning that variables can be assigned without declaring their type, and that their type can change." - [wikipedia.org]
  • "Weak typing means that a language implicitly converts (or casts) types when used." - [wikipedia.org]

Awesome, now that we've started off totally confused, I'll try to tidy things up. Rather than starting from the terms and shoehorning definitions, I'll take a look at each of the different definitions, and decide how useful and precise they are at describing certain languages. It turns out that while there is widespread disagreement on what each of the terms mean, everybody seems to "know it when they see it". That is, everybody can agree that Java is static and strong, PHP is dynamic and weak, etc. This instills a modicum of hope that these definitions actually mean something, and we can find them useful.

Definitions

First, I need to get some definitions out of the way.

  • When I say symbol, I mean either a value or expression used in describing a context-free grammar.
  • Coercion and casting has its own article.
  • Finally, by type checking, I am referring to an algorithm for ensuring that a symbol has the correct type.

Now, I'll discuss each definition in turn, and label each one so I can refer to them later:

(S-1) Type checking is done during compile time.

Associated languages: Java, C++, Haskell, etc.
Associated terms: Static typing, Strong typing, Strict typing

If we know the types at compile time, this means that the language we are discussing makes use of type annotations to describe symbols, or type can be inferred from the symbols themselves without running the program. These type annotations can be used to perform type checking. However, it should be noted that type checking during compile time cannot completely eliminate run-time errors. For example, while it is possible to check that arithmetic operators only operate on numbers, it is not possible to check for division by zero.

Is a good definition for: Static typing

This property is sufficient for static type checking in Types and Programming Languages (which, by the way, makes no mention of any of the terms above, except for a note acknowledging that "static typing" and "dynamic typing" have become synonymous with "static type checking" and "dynamic type checking").

No surprise here, as people normally agree that this property is necessary for static typing, but bicker endlessly about whether or not an additional property (usually referred to as strong typing) is also necessary. I do not include strong typing as a candidate term, because definitions (T-1) and (T-2) which normally describe strong typing do not require static typing.

Strict typing also applies to this, but just like the term "loose typing", strict typing seems to apply to any of static or strong typing, or both. As such, I will not offer strict typing as an accurate term to describe any of these concepts.

(D-1) Type checking is done during run time.

Associated languages: Erlang, PHP, Ruby, etc.
Associated terms: Dynamic typing, Weak typing, Loose typing

In this case, absolutely no type checking is done during compile time; it is all done during run time using run time type tags. As a consequence, type annotations are not useful or required in the language. Guards are typically used to test for type during execution.

Is a good definition for: Dynamic typing

By Types and Programming Languages, and from intuition, this would make a good definition for dynamic typing. It is essentially the opposite of definition (S-1).

Loose typing also applies, but just like strict typing, loose typing seems to apply to any of dynamic or weak typing, or both. I will avoid using this term from now on as well.

(S-2) Symbols can be annotated without being defined.

Associated languages: Java, C++, Haskell, etc.
Associated terms: Static typing, Strong typing, Strict typing

It seems that only languages that have the property (S-1) also have this property, so I am treating this as a possible alternate definition for static typing.

Is a good definition for: None

I would say static typing, but I've changed my mind. Java and C++, both generally regarded as statically typed, allow this. However, in Scala (also statically typed), you cannot do this except in a class definition. Since undefined symbols are then automatically given a default value (as in Java), this definition would not seem to cover Scala. Additionally, the important point is that type checking is done during compilation, and this definition doesn't hit the mark as closely as the previous one.

(D-2) Symbols cannot be annotated without being defined.

Associated languages: Erlang, PHP, Ruby, etc.
Associated terms: Dynamic typing, Weak typing, Loose typing

As the complement to (S-2), I will consider this as a possible definition for dynamic typing.

Is a good definition for: None

Every single language generally described as dynamically typed has this property. And it also implies that compile time type checking is not possible. However, I could augment any dynamically typed language with (worthless) type annotations that would break this definition. The important bit is that type checking is done during run time, and this definition does not immediately capture this fact.

(T-1) A symbol's type can at best change to a covariant type.

Associated languages: Java, C++, Haskell, Erlang, etc.
Associated terms: Static typing, Strong typing, Strict typing

A lot of the time, people just say that an identifier's type cannot change. This is trivially the case in Erlang as reassignments are not even allowed in the first place, and Haskell programmers will notice similar effects as there is no Object class that all objects inherit from.

However, in Java and Scala (both supposedly statically and strongly typed), reassignments to covariant types are allowed, while reassignments to other types are not:

// Java example
Object foo = new Integer(5);  // No error
foo = new String("Hello!");   // No error
foo = new Bar();              // No error

Is a good definition for: Strong typing

Note that this is only a good definition for strong typing, not static typing. Disagree? Read on; here comes the confusion.

For one thing, lots of people will use an example like the following in PHP (which is basically the same as the one in Java) to show that PHP is weakly typed:

// PHP example
$foo = 5;
$foo = "Hello!"
$foo = new Bar();

...suggesting that if PHP is weakly typed, then Java must be weakly typed (yet the same people will not agree on this, revealing major inconsistencies in their reasoning). Obviously, looking at covariant types only won't give us the full story. Let's look at assignments to neither covariant nor contravariant types, which PHP allows, but Java does not:

// Java example
Integer foo = 5;
foo = "Hello!" // Compile time error

A problem like this can easily be caught by the compiler, which is another source of confusion; it causes people to think that all such type errors can be caught by the compiler, so that this property and static type checking always go hand in hand. This is simply not true.

For example, casting to a contravariant type is allowed in C++ and Java, but in Java, they will result in run time errors (the C++ program may just crash):

// Java example
Integer foo = 5;
foo = (Integer) new Object();  // Run time error

With C++ regarded as a weakly typed language and Java as a strongly typed language (yet they are both static), the fact that Java raises a type error and C++ seems to suggest we have reached a good definition for "strongly typed".

One final note: do not confuse shadowing with weak typing. For example, the following Scala code typed in the interpreter raises no errors:

// Scala example
var x: Int = 5
var x: String = "Hello!"

In fact, I could have done the same thing even if x were a val! This is because the two x's are in different scopes, and the second declaration shadows the previous one.

(W-1) A symbol's type can be changed to any other type.

Associated languages: C++, PHP, Ruby
Associated terms: Dynamic typing, Weak typing, Loose typing

In these languages, no coercion is necessary, although in C++, this behavior may require a cast (with Java, a strongly typed language, the cast will fail at run time). Ruby and PHP will allow you to change a symbols type without a cast or coercion. This behavior is distinct from dynamic typing, as Erlang is dynamically typed, but does not allow changing of a symbol's type at all (suggesting that PHP and Ruby are weakly typed, while Erlang is strongly typed).

Is a good definition for: Weak typing

Is near the polar opposite of definition (T-1), and deserves the moniker "weak typing". Most people will disagree with this, preferring the following definitions, which I find either subjective or inaccurate...

(T-2) Few or no coercions are automatically applied by the compiler or interpreter.

Associated languages: Java, Haskell, Ruby, Erlang, C++, etc.
Associated terms: Static typing, Strong typing, Strict typing

Many people would ascribe the term "strongly typed" to this definition.

Before continuing, read this if you don't know what type coercion is. Now, note that this is a very subjective definition; who is to say what "few" means? Also, in all of the example languages, the compiler provides at least one coercion. For example, in Java, Objects are always automatically coerced into Strings.

Is a good definition for: None

Despite the subjective issue pointed out above, a bigger problem with this definition exists, and I will explain it in the next section. However, I do feel that there is value in saying that in general, statically typed languages provide few or no coercions.

(W-2) Many coercions are automatically applied by the compiler or interpreter.

Associated languages: PHP
Associated terms: Dynamic typing, Weak typing, Loose typing

Again, a very subjective definition.
Is a good definition for: None

Many people would ascribe the term "weakly typed" to this definition.

Saturday, May 17, 2008

Using the hosts file and lighttpd to block ads

Using the hosts file to block ad sites is more efficient than say, using the adblock plugin for Firefox. With adblock, your computer will still send a request to the spam/advertising site; adblock just hides those ads from your view (at least it did the last time I checked). Also, you are out of luck if a non-web application decides to communicate with a spam site.

Setting up the hosts file

The hosts file can be modified to get around these limitations; you can force all spam sites to resolve to your own IP, and Firefox (or any other application) will request some ad from your own machine (and chances are, you won't have it). This cuts down on network traffic and keeps other pesky applications from contacting their parents. On linux, just head over to a site like this and grab an updated hosts file. Just in case you don't know what you're doing, backup your current /etc/hosts, then append the contents of this to it. Finally, delete these lines:

127.0.0.1  localhost
127.0.0.1  localhost.localdomain
255.255.255.255 broadcasthost
::1  localhost

Fixing the ugly page not found errors

Now, wherever you would have seen an ad in Firefox, you get an ugly "Page not found" error instead. To fix this, configure the web server on your computer (assuming you're running one, assuming you're a web developer) to return an empty file on a 404. Assuming you're not a web developer and/or you don't have a web server running, grab lighttpd, or sudo apt-get install lighttpd.

Now edit the lighttpd.conf (located at /etc/lighttpd/lighttpd.conf on Ubuntu), and make sure you have these settings by either uncommenting, adding, or editing the config file. Don't touch any of the other settings.

server.error-handler-404  = "/404.html"
server.bind = "localhost"

Check the server.username and server.groupname parameters. They should both be www-data; keep this in mind.

Now go to the /var/www directory and create an empty 404.html:

cd /var/www
touch 404.html

Then check the permissions of the /var/www directory, and make sure they are owned by www-data (or whatever the server username/groupname for your machine should be). If not, change the ownership:

chown -R www-data:www-data /var/www

Now restart lighttpd (or restart your computer), and watch those page not found errors go away.

Friday, May 16, 2008

What's a type conversion?

What is a type conversion? What's the difference between an implicit conversion, an explicit conversion, a coercion, or a cast? You've no doubt heard these terms thrown around and you probably know they all loosely describe one (or several) methods to enable a programmer to treat one type as another type. But what do they mean, precisely? Even seasoned programmers may be a little confused about this topic, and this may be a root cause of why many programmers don't know the difference between static, dynamic, strong, and weak typing.

Basically, if you think of types in a computer program as mathematical sets, its much easier to understand and remember what all these terms mean. This is not a far stretch if you consider that Type Theory is just one of several versions of Set Theory invented to circumvent Russel's Paradox. Basically, suppose you have two elements a and b, where:

a ∈ A
b ∈ B

This is congruous to saying an object c is of class C, and an object d is of class D. In Java, we would write:

C c = new C();
D d = new D();

Note: The equivalent of "member of" in Java would be the instanceOf operator, as a redditor has pointed out. C c = new C(); is sufficient for c instanceOf C to be true.

Coercions

A function f:A->B is an implicit conversion of an element in A to an element in B. This is also called a coercion, because you are starting with an element in A but you really want an element of type B. You can apply f to obtain that element (call it b). In Java, we have a toString method that converts (or more precisely coerces) an Object to a String:

System.out.println(c.toString());

Casts

On the other hand, an explicit conversion (or cast) is slightly different, but also converts one type to another. Except imagine sets A and C, where A is a subset of C:

a ∈ A
A ⊆ C

Obviously, if a is a member of A, and A is a subset of C, then a must be a member of C, and you may use a whenever a member of set A or set C is expected. In programming, when you treat an object as one of its sub-types or super-types, you must perform an action called a cast, and the object itself never changes - just like how the element a never changes.

In the following Java example, suppose we have a String. Well, obviously that String is also an Object (a superclass of String), so we can perform a cast to convert a String into an Object:

String s = new String("Hello World!");
Object o = (Object) s;

Confusion

Knowing all this, it probably doesn't make sense to say "explicit coercion" or "implicit casting"; however, I do see these terms thrown around a lot. Specifically, "explicit coercion" is usually construed to mean "manual coercion"; eg the developer must manually coerce an object of one type to another. When the compiler does it, people say it is an "implicit coercion" or "implicit conversion"; these terms seem redundant and confusing, so I urge readers to use the terms "automatic coercion" and "manual coercion" instead (unless your intention is to confuse). Some people also draw a distinction between conversion and coercion (defining conversion to mean casting, and coercion to mean ... well, coercion), as if we computer scientists haven't already made enough of a mess by sloppily defining "=" to mean "member of" in Big-Oh notation. Sigh.

Summary

So in summary, we know that implicit conversions aka coercions change one type to another type, explicit conversions aka casting change one type to another sub-type or super-type. This is important because the way languages handle type conversions play a part in determining what kind of type system they are using - be it static, dynamic, strong, or weak. I know I wrote a little about type systems earlier, but I'd like to revisit and expand on the topic in the future, with this article at hand to reference.

Thursday, May 8, 2008

Fun with the scala interactive shell

Instead of running irb as a calculator, I find myself using the scala interactive shell instead. With the J9 JVM, performance is better, plus you can automatically load files on startup (just like irb). You can also add your own jars to the classpath so they are available in the interactive shell, and automatically load files at startup. Add this to your .bash_profile for the goodness:

export CLASSPATH=$CLASSPATH:/path/to/my/lib.jar
alias iss='scala -i ~/.scalarc'

Better performance with Scala with IBM J9 JVM

The title says it all; Sun's JDK is more stable but slow. I've been using the J9 JDK for a while now and scala (especially the interactive scala shell) performs much faster. You grab the linux JDK from IBM's site here (registration required).

One note though: I couldn't run Maven 2.0.9 or the embedded Maven in Netbeans 6.x (it's the 2.1-SNAPSHOT version of Maven) with the J9 JVM; I have to use Sun's JDK instead.

Saturday, April 19, 2008

gEdit and Scala

In my quest to fiddle around with a ton of development environments (because so far I've hated them all), I decided to try out gEdit to write some Scala. My initial impression is that it's very similar to jEdit (for the purpose of writing Scala), but the syntax highlighting from the Scala Bazaar doesn't work (boo). So.. I decided to write up a simple lang file for gEdit. Verdict: jEdit is now removed from my system.

Update

Copy scala.lang to /usr/share/gtksourceview-2.0/language-specs and restart gEdit to install this thing.

Update

The original file from scala-tool-support will work if you create the scala mime type in /usr/share/mime. You can view this sample file or just drop it in there. Then drop scala.lang into ~/.gnome2/gtksourceview-1.0/language-specs and you are good to go.

Update

I submitted a patch for this so you should find the language file in scala-tool-support.

Thursday, March 13, 2008

Autoscroll breaks in Firefox 2.0.0.12 on Linux

It used to be that a single middle click would start autoscroll in Firefox, but there's now a feature that loads a URL you have in the clipboard if you middle click. By default on Linux, this will screw up your autoscroll functionality (haven't tested on Windows, but I think it doesn't occur). Instead of autoscrolling, you'll get an alert to the tune of "The URL is not valid and cannot be loaded", or somesuch.

There's a bug about it here, and the quick fix solution (if you can live without contentLoadURL), is to do this:

  1. Type about:config into the address bar
  2. Search for and set general.autoScroll to true
  3. Search for and set middlemouse.contentLoadURL to false

Sunday, February 17, 2008

Maven + Scala + TestNG + Netbeans

There are lots of articles on the web on how to set up Maven with Scala, or TestNG and Scala, or Netbeans with Scala, but there aren't any resources that tell you how to tie them all together. The cursed Maven pom is a mystery, but I've managed to unearth the ancient hieroglyphs in the exact sequence that will make Maven, TestNG, and Scala work well together.

If you want to use all three along with an IDE, I hear jEdit is somewhat popular for Scala users, but I'm somewhat invested in Netbeans myself.

Update

Blast all these IDEs to hell! I've had my last straw and I'm sticking with vim! The syntax highlighting is better with jEdit and its a little more stable, but Netbeans has a cleaner, more familiar interface (in my opinion). Stability is only a problem because you have to use the dev version of Netbeans to get the Scala plugins working. Anywho, once you get your editor/IDE set up, you'll want to know exactly what type in your pom to make everything work correctly.

If you follow the links for setting up Maven and Scala, your pom will look somewhat correct, you'll need to add the TestNG dependency:

<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>5.7</version>
  <classifier>jdk15</classifier>
  <scope>test</scope>
</dependency>

Now, if you try to compile a TestNG test, you'll get compiler warnings about annotations. Make sure the target VM is set for 1.5 with the maven-scala-plugin:

<plugin>
  <groupId>org.scala-tools</groupId>
  <artifactId>maven-scala-plugin</artifactId>
  <version>2.3</version>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
        <goal>testCompile</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <scalaVersion>2.6.1</scalaVersion>
    <args>
      <arg>-target:jvm-1.5</arg>
    </args>
  </configuration>
</plugin>

By default, the 2.3 version of the maven-surefire-plugin is pulled in, but you'll want 2.4. Additionally, you'll want to add some information so surefire will find the tests you want to run:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.4</version>
  <executions>
    <execution>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <classesDirectory>target/classes</classesDirectory>
    <testClassesDirectory>target/test-classes</testClassesDirectory>
    <testSourceDirectory>src/test/scala</testSourceDirectory>
  </configuration>
</plugin>

Now if you have a test that looks like this:

import org.testng.annotations._

@Test
class MyCoolTest {
  def testConsole = {
    Console println "Hi!"
  }
}

...you'll get a nice, satisfying result:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running TestSuite
[Parser] Running:
  Command line suite

Hi!
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.411 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0