Skip to content

Command Line Arguments for Scala Programs

October 11, 2016

Introduction

When building Scala projects you may the need to pass in arguments into a program so you can control certain parts of the execution. To do this there’s a simple way and a more complete way that allows you to more dynamically specify arguments in any order. This post will include examples on how you can support passing in arguments into a Scala program.

Simple Example

The most simple method of accepting arguments into your application is to use the default args (String array) that you have to provide in the main function in the Main class.

If you want to use this method its as simple as assuming that each desired argument is at a specific position within the array.

Code

com.example.args_example.scala.Main.scala

package com.example.args_example.scala
object Main {
    def main(args: Array[String]): Unit = {
        println(args.mkString(", "))
    }
}

Running

$ scala -classpath args-example.jar com.example.args_example.scala.Main arg1 arg2 arg3

arg1, arg2, arg3

Disadvantages

The simple case is great because it doesn’t require a lot of code and you get exactly what you need from what you’re given right off the bat. However, there are limitations to this approach. The arguments that you provide need to be in a specific order and you can’t optionally drop any arguments without severely complicating your arguments parser.

Complete Example

If you come across the case where you would like to allow the user to provide optional arguments, provide the arguments in any particular order, and validate the arguments then this approach is more your speed.

Here, we’re building out a separate class to store the arguments and provide specialized functions for its validation and retrieval.

com.example.args_example.scala.Main.scala

package com.example.args_example.scala
object Main {
    def main(args: Array[String]): Unit = {
        if (args.contains("-help") || args.contains("--help")) {
            println(MainArgs.argsUsage)
            System.exit(0)
        }
        val mainArgs = MainArgs.parseJobArgs(args.toList)
        if (mainArgs == null) {
            println(MainArgs.argsUsage)
            System.exit(-1)
        }
        mainArgs.validate()
        println(mainArgs)
    }
}

com.example.args_example.scala.MainArgs.scala

package com.example.args_example.scala
import java.security.InvalidParameterException
object MainArgs {
    val argsUsage = s"MainArgs Usage: \n" +
    s"\t[-strArg string (description=Example of a String Argument. (Required))]\n" +
    s"\t[-intArg integer (description=Example of a Integer Argument.)]\n" +
    s"\t[-bolArg (description=Example of a Boolean Argument.)]\n" +
    s"\n"
    case class JobArgs(strArg: String = null, intArg: Int = 0, bolArg: Boolean = false) {
        override def toString(): String = {
            s"MainJobArgs(\n" +
            s"\tstrArg=$strArg, \n" +
            s"\tintArg=$intArg, \n" +
            s"\tbolArg=$bolArg \n" +
            s")"
        }
        def validate(): Unit = {
            val invalidMessageList = new java.util.ArrayList[String]()
            //code to ensure that strArg is required
            if(strArg == null) {
                 invalidMessageList.add("-strArg needs to be provided")
            }
            if (invalidMessageList.size() > 0) {
                 throw new InvalidParameterException("Invalid Arguments: " + invalidMessageList + "\n" + argsUsage)
            }
        }
    }
    def parseJobArgs(args: List[String], jobArgs: JobArgs = JobArgs()): JobArgs = {
        args.toList match {
            case Nil => jobArgs
            case "-strArg" :: value :: otherArgs => parseJobArgs(otherArgs, jobArgs.copy(strArg = value))
            case "-intArg" :: value :: otherArgs => parseJobArgs(otherArgs, jobArgs.copy(intArg = value.toInt))
            case "-bolArg" :: otherArgs => parseJobArgs(otherArgs, jobArgs.copy(bolArg = true))
            case option :: tail => println("Unknown option " + option); return null;
        }
    }
}

Running

$ scala -classpath args-example.jar com.example.args_example.scala.Main -help

MainArgs Usage:
[-strArg string (description=Example of a String Argument. (Required))]
[-intArg integer (description=Example of a Integer Argument.)]
[-bolArg (description=Example of a Boolean Argument.)]

$ scala -classpath args-example.jar com.example.args_example.scala.Main

Exception in thread “main” java.security.InvalidParameterException: Invalid Arguments: [-strArg needs to be provided]
MainArgs Usage:
[-strArg string (description=Example of a String Argument. (Required))]
[-intArg integer (description=Example of a Integer Argument.)]
[-bolArg (description=Example of a Boolean Argument.)]

$ scala -classpath args-example.jar com.example.args_example.scala.Main -strArg test

MainJobArgs(
strArg=test,
intArg=0,
bolArg=false
)

$ scala -classpath args-example.jar com.example.args_example.scala.Main -strArg test -intArg 100

MainJobArgs(
strArg=test,
intArg=100,
bolArg=false
)

$ scala -classpath args-example.jar com.example.args_example.scala.Main -strArg test -intArg 100 -bolArg

MainJobArgs(
strArg=test,
intArg=100,
bolArg=true
)

Equivalent in other Languages

Java

To Be Created

Python

To Be Created

Advertisements

From → Guide

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: