Here’s a way to ensure that only one instance of your application runs at a time. Perhaps it updates a resource and you need to prevent duplicate updates. Or, in another use, I recently wanted to make sure an application was always running. So I wrote a cron job to periodically start the program; if it was already running, the new start failed.
A traditional method for ensure single instances of program uses file locking and PIDs. A program, upon start up, would get its process id (PID) from the OS, then write it to a file called “program.lock” in a known, fixed location. Then it would read the file and check the written PID against its own. If they match, great; continue. If they don’t match, it means that another file succeeded at creating the file, ie got the lock, so this application must shut down. You might think that if the file exists, then no check is necessary. However, the idea is to handle the situation when multiple instances start at nearly identical times. Neither sees the file and tries to create it, but only one succeeds because Unix file creation is atomic.
The traditional method is clever, but challenging to get right. Lock files must be removed on exit, requiring more code. If the program terminates unexpectedly, provisions must be made to catch the exit signal and clean up or use additional methods to reap leftover lockfiles.
Here’s a much simpler method. Like the traditional method, each application attempts to hold a shared resource. Only one succeeds, and the resource hold is automatically released on program termination. The resource? A OS network port. So the only risk is accidentally choosing a port needed by another application for actual communication.
All you have to do is choose a port to use as an “application exclusion group id”. Several applications use the id. But only one application among the group sharing the id can run at a time.
Here’s the code. Include the file in your program, then call SingletonApp.performSolo as shown in the demo. To demo, just run multiple copies of the file as shown in the comments. Only one will run at a time…
import java.net.BindException
import java.net.ServerSocket
/**
* This class enables applications to ensure that only one instance
* of the application runs at a time.
*
* @author Gary Boone, PhD
* @version 1.0, 2010/02/24
*/
object SingletonApp {
var serverSocket:ServerSocket = null
/**
* Pick a port number to use as the application exclusion
* group id. Choose a port that won't conflict with other
* applications. See
* http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
* for common port numbers.
*
* Additionally, pass in a closure to be run if the application
* is already running.
*/
def performSolo( portToHold:Int)( fail: => Unit ) = {
try {
serverSocket = new ServerSocket(portToHold)
} catch {
case e:BindException => fail
}
}
/**
* Demo the SingletonApp class
*
* Compile, or run with:
* scala -i SingletonApp.scala -e 'SingletonApp.main(null)' &
* Then start another instance to see it fail.
*/
def main( args:Array[String] ) : Unit = {
val DEMO_PORT_TO_HOLD = 15486
// ensure single instance
SingletonApp.performSolo(DEMO_PORT_TO_HOLD) {
println("failing due to already-running instance.")
exit
}
println("Application started. Try to start another instance.")
Thread.sleep(300000) // 3e6 ms = 300 sec = 5 min
println("exiting")
}
}
Sometimes you need the top k items in a list. A naive way to do it is to sort the list, then take the first k items. The problem with that approach is that you don’t need to sort the whole list, so it’s inefficient and becomes more so as the list length, n, increases relative to k.
To sort just the top k items, you can use a bounded priority queue; after feeding the whole list into it, the queue contains the top k items. This approach is better, but expends unnecessary effort maintaining the sort in the queue as items are added. If n is much larger than k, it would be faster to find the top items without sorting, then sort only the final list of top items.
The code below does a partial sort in linear time. Upon return, the first k positions of the array contain the largest or smallest items of the array, depending on the compare() function provided by the Ordered trait of the class contained in the array. The items in the first k positions are not sorted.
package scala
/*
* FirstK
*
* These functions provide a linear partial sort of an array of Ordered objects. The array is
* sorted in-place and upon return the the k smallest or largest items are in the first k positions.
* The first k values are not sorted, but are less than or equal to the values in the rest of the
* array. Whether the first k items are the largest or the smallest of the array is determined
* by the compare function of the objects in the array.
*
* For example:
* case class Foo(n: Int) extends Ordered[Foo] { def compare(other: Foo) = this.n.compare(other.n) }
* means that firstK will return the smallest n values in Array[Foo]
* case class Foo(n: Int) extends Ordered[Foo] { def compare(other: Foo) = -this.n.compare(other.n) }
* means that firstK will return the largest n values in Array[Foo]
*
* Example from scalatest unit test:
*
* case class Foo(n: Int) extends Ordered[Foo] {
* def compare(other: Foo) = this.n.compare(other.n)
* }
*
* test(" Test findFirstK() Length 2" ) {
* val array = Array(new Foo(2), new Foo(1))
* FirstK.findFirstK(array, 1) // k = 1
* assert(array.deepEquals(Array(Foo(1), Foo(2))))
* }
*/
object FirstK {
def swap[T](array: Array[T], x: Int, y: Int) = {
val t = array(x)
array(x) = array(y)
array(y) = t
}
// Lomuto Partition
def partition[T <% Ordered[T]](array: Array[T], left: Int, right:Int, pivotIndex: Int): Int = {
val pivotValue = array(pivotIndex)
swap(array, pivotIndex, right) // Move pivot to end
var storeIndex = left
for (i <- left until right ) {
if (array(i) <= pivotValue) { // will use the compare fn, so may use > for desc sort
swap(array, storeIndex, i)
storeIndex += 1
}
}
swap(array, right, storeIndex) // Move pivot to its final place
storeIndex
}
// Note that p here is the position that ends the range of 'first' values.
def findFirstToP[T <% Ordered[T]](array: Array[T], left: Int, right:Int, p: Int): Unit = {
if (right > left) {
val pivotIndex = (left + right) / 2
val pivotNewIndex = partition(array, left, right, pivotIndex)
if (pivotNewIndex > p)
findFirstToP(array, left, pivotNewIndex - 1, p)
if (pivotNewIndex < p)
findFirstToP(array, pivotNewIndex + 1, right, p)
}
}
// intended entry fn; includes parameter checking. Modifies the array so that the first k items
// are largest/smallest of the array.
def findFirstK[T <% Ordered[T]](array: Array[T], k: Int) : Unit = {
if (array==null || k==0 || k>array.size) {
throw new IllegalArgumentException()
}
findFirstToP(array, 0, array.length - 1, k-1) // fn is position-based so, k-1 for 'first k'
}
}
If you’ve played around with the Option class, you know that it allows you to note that no value is available and do so without nulls. For example, using getOrElse() you can access a value or a default when no value is present:
scala> val a:Option[Int] = Some(5)
a: Option[Int] = Some(5)
scala> val b:Option[Int] = None
b: Option[Int] = None
scala> a.getOrElse(0)
res1: Int = 5
scala> b.getOrElse(0)
res2: Int = 0
But a problem you’re likely to come across is how to access an instance variable when a class is stored in an option? For example,
scala> case class S(lines:Int, pages:Int)
defined class S
scala> val sOpt:Option[S] = Some(new S(16,5) )
sOpt: Option[S] = Some(S(16,5))
scala> val nOpt:Option[S] = None
nOpt: Option[S] = None
Here, we’ve created a simple class an put an instance of it into an Option. Then we made another option container for the class containing None. So given an Option[S], how do you get the lines value out of it? You can’t do it directly because the Option may contain None.
The answer is to use map, passing in the accessor or other function you want to apply. In this case, we just use the accessor lines. An Option is returned, so getOrElse() then returns the value or a default.
scala> val numLines = sOpt.map{ _.lines }.getOrElse(0)
numLines: Int = 16
scala> val numLines = nOpt.map{ _.lines }.getOrElse(0)
numLines: Int = 0
The underscore is an abbreviation for the object in the map. Don’t forget that you can also pass functions into the map.
scala> sOpt.map{println}
S(16,5)
scala> nOpt.map{println}
Not that the instance toString() was printed by the first line, whereas the second printed nothing because the Option contained a None. (I’ve omitted the REPL result lines.)
Finally, note that complex functions can be built using the normal block “=>” syntax. Here, we print as well as accessing the lines instance variable:
scala> val numLines = sOpt.map{x => println(x); x.lines}.getOrElse(0)
S(16,5)
numLines: Int = 16
scala> val numLines = nOpt.map{x => println(x); x.lines}.getOrElse(0)
numLines: Int = 0
scala>
The Jersey package is Sun’s reference implementation of the JAX-RS standard for RESTful web services. It’s easy to use; with a few annotations, you’ll have your own REST api. The examples show how to use the included Grizzly server, allowing you to create embedded servers. That is, instead of fussy XML configurations for the large web servers, you can create small, easily deployable servers that you control via REST calls.
Using eclipse, just create your project, adding the jars required by Jersey. Follow the Getting Started guide for an example.
To deploy, you can package your project into a single jar using “File | Export…” Then you can run the jar using
java -Xmx512m -jar MyServer.jar
where you use -Xmx to make sure your server has enough memory. There’s just one problem…
When you run the jar, the program will start up cleanly. But when you hit it with a url, you see
The ResourceConfig instance does not contain any root resource classes.
followed by some exception. The problem is the server can’t find your classes. The simple trick is to add your bin directory to your classpath. Use “Project | Properties | Java Build Path.” On the Libraries tab, click “Add External Class Folder…” and add the “bin” directory in your project root.
Next time you run, you’ll see
Scanning for root resource and provider classes in the packages:
main
Root resource classes found:
class main.MyClass1Resource
class main.MyClass2Resource
class main.MyClass3Resource
class main.MyClass4Resource
as the embedded Grizzly server scans the package (”main”) you gave it when you initialized it:
initParams.put(”com.sun.jersey.config.property.packages”, “main”);
Instant RESTful server, one line deploy. What’s not to love?
// Sum the values in a list
val sum = (0.0 /: list){ _ + _ }
// What it says: it's an abbreviated form of
// list.leftFold(0.0) { (s,i) => s + i }
// Find the minimum value in a list
val minValue = list.reduceLeft( _ min _ )
// What it says: Note that it's reduce, not fold. It applies the
// min function to the series of results obtained by applying
// the function from the left.
// Note the difference between fold and reduce: fold takes an
// initial value, while reduce does not.
Tags: Scala
To work effectively with an API, you have to be able to search it quickly. The best way I’ve found to do so is with a locally installed copy in CHM format. That’s the Windows helpfile format. With a good CHM browser, search-as-you-type allows you to find classes and methods as fast as you can type.
To view on a Mac, the best CHM browser I’ve found is ArCHMock.
Trying to start a program created with the eclipse Scala plugin, I saw an error that the main class couldn’t be found. That was cryptic, as there was a main. Stranger still, this is a program I had run successfully before.
The first part of solving the problem was to look for clues in the Problems view. Opening it, I saw this:
error while loading Configgy, Scala signature Configgy has wrong version expected: 5.0 found: 4.1 in /Users/…
So the first error was due to the compilation failing and not producing a main class that eclipse could launch.
After further digging, the version error turned out to be caused by a mismatch between the Scala version (2.7.5) I used to compile the Configgy library and the Scala version (2.8) that the eclipse plugin used to compile the rest of the program. I didn’t install Scala 2.8, so how could this occur? The Scala plugin installs its own version of Scala. Because I had selected the nightly build version of the plugin, the Scala versions drifted apart during one of the eclipse updates.
You can tell which version the eclipse Scala plugin uses by looking at the jar name in the eclipse/plugins directory. Eg, scala.tools.nsc_2.75.final.jar
The solution was to revert to the stable, release version of the plugin. Do that by using this url in the eclipse Software Updates | Available Software | Manage Sites… list.
http://www.scala-lang.org/scala-eclipse-plugin
More complete directions here.
In NetBeans, creating a runnable jar for your Scala program is even easier. It’s done automatically when you build your project. The compile output even reminds you how to run the jar file.
The first time I did it, I saw an error about finding a Scala object. Solve that by adding the scala-library.jar to your project. Right-click on the libraries folder in the Projects tab on the left sidebar. Choose Add JAR/Folder and find your scala-library.jar. Because I installed Scala with MacPorts, mine was under
/opt/local/var/macports/software/scala/2.7.4_0/opt/local/share/scala/lib
See this blog entry for more on finding MacPorts installations.
Add any other required libaries this way. Rebuild. Then you can run your program via
$ java -jar YourProgram
in the dist/ directory.
Note that by default, the NetBeans jar mechanism creates a jar file for your program and then adds the libraries you specified into a lib directory. So it’s not a single executable jar. You can then zip and distribute the jar/directory. The advantage of this approach is that you can update the libraries in the lib directory without having to rejar everything. You can probably also save space by using symbolic links in the lib directory to point to your jar locations. I haven’t tried that, though.
You can ignore the lib directory by directly linking to your libraries in the java command using Xbootclasspath. Here, I’ve added two libraries, Configgy and the Scala jar, to my project, but note that I also had to include the path to the Java SDK:
java -Xbootclasspath:/opt/local/var/macports/software/scala/2.7.4_0/opt/local/share/scala/lib/scala-library.jar:../configgy/dist/configgy-1.3/configgy-1.3.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar -jar ScalaApplication1.jar
If you want to create a single jar with all of the required files, then add a few lines to your build.xml file. There are many varying pages on the web about this; I found these directions simplest:
1. Add
<target name="-pre-jar">
<unjar dest="${build.classes.dir}" src="${file.reference.theLibraryName.jar}">
</target>
to the build.xml file, replacing theLibraryName with the appropriate jar filename.
2. Rebuild
To get the correct library filename, switch to the Files tab in the left sidebar and look in the project.properties file. Find lines that look like these:
<unjar dest="${build.classes.dir}" src="${file.reference.configgy-1.3.jar}"/>
<unjar dest="${build.classes.dir}" src="${file.reference.scala-library.jar}"/>
You can ls -l your program in the dist directory and see that it’s much larger; it now contains the libraries. The lib directory is still there, but you don’t need it anymore.
Tags: NetBeans, runnable jar
How do you create a single runnable jar that contains all the files it needs to run? This is one of those questions that should be easier to answer. Here’s how to do it in eclipse and NetBeans.
First, eclipse, following the post here:
1. Create a Java class to run your Scala main:
package scala.loader;
import java.util.*;
public class ScalaEntryPoint
{
public static void main(String[] args) {
List<string> argList = new ArrayList<string>();
argList.add("YourScalaObjectWithMain");
for (String s : args) argList.add(s);
scala.tools.nsc.MainGenericRunner.main(argList.toArray(new String[0]));
}
}
Be sure to change YourScalaObjectWithMain to your class. Also, you’ll have to add the Scala tools jar to your projects classpath: Project | Properties | Java Build Path tab | Libraries tab | Add External Jars… button. Then pick the scala.tools.nsc file in your eclipse/plugins folder.
2. Create a Run Configuration to run the Java class. Check that it runs.
3. Then choose File | Export…, then Java | Runnable JAR File, then pick the Java run configuration to export and a destination. Optionally, you can save the ant XML file that does the export. Later, after some edits, you can rejar using
ant -f yourjarXMLfile.xml
If you change your libraries, be sure to repeat the complete Export process to make sure your jar scrips includes the correct jars.
Tags: eclipse, runnable jar