Programs that reproduces itself - java

Is it possible to make a Java program that prints its source code to a new file, and compiles it, and runs the compiled program?

Update:
Okay, might as well make it autorun. Enjoy the madness. Run at your own risk.
Yes it's possible, because I actually wrote it up. It doesn't do the RUN part (that's just too crazy, because as others have mentioned, it will cause an infinite loop), but here it is: Quine.java
import java.io.*;
public class Quine {
public static void main(String[] args) throws Exception {
char q = 34;
String out = "Quine$";
String text = (
"import java.io.*; " +
"public class [OUT] { " +
"public static void main(String[] args) throws Exception { " +
"char q = 34; String out = `[OUT]$`; String text = `[TEXT]`; " +
"PrintWriter pw = new PrintWriter(out + `.java`); " +
"pw.format(text, 34, out, text); " +
"pw.close(); Runtime runtime = Runtime.getRuntime(); " +
"runtime.exec(`javac ` + out + `.java`).waitFor(); " +
"runtime.exec(`java ` + out); " +
"} " +
"}"
).replace("`", "%1$c").replace("[OUT]", "%2$s").replace("[TEXT]", "%3$s");
PrintWriter pw = new PrintWriter(out + ".java");
pw.format(text, 34, out, text);
pw.close();
Runtime runtime = Runtime.getRuntime();
runtime.exec("javac " + out + ".java").waitFor();
runtime.exec("java " + out);
}
}
So here's how to get the craziness to start:
javac Quine.java to compile
java Quine to run it
It will produce, compile and run Quine$
I've made sure Quine.java is as readable as possible, so the major difference from Quine$.java are formatting and the 3x replace. The minor difference is that Quine$.java has out set to Quine$$.
Quine$ will produce, compile and run Quine$$
Quine$$ will produce, compile and run Quine$$$
Quine$$$ will produce, compile and run Quine$$$$
...
Do note that this doesn't do any reverse-engineering or cheat by reading the .java source code, etc. Quine is a quine-generator because it produces a different code differently formatted, but Quine$ is pretty much a true self-contained quine: it does reproduce itself, it just relabels it Quine$$ (which reproduces itself and relabels to Quine$$$ etc).
So technically there's no infinite loop: it will eventually come to a halt when the file system can't handle another $. I was able to manually stop the madness by forcefully deleting all Quine$* files, but run at your own risk!!!

Yes, it is possible.
A trivial implementation would be: have the source code contain itself in a string, save the string to a file and fill its own string with the same string (otherwise, the initial string would be of infinite size, due to the recursive manner of this implementation), compile the file, and run the compiled file (which will, in turn, do the very same).
Non-trivial implementations are significantly harder.

Sure it works - Have a look at rosetta code and navigate to Quine, which is a self-referential program that can, without any external access, output its own source.
There's one example for a quine in Java.

Programs that reproduces itself or Self Replicating Programs are known as Quine Programs
Sample Program in Java which reproduces itself.
public class QuineProgram {
public static void main(String[] args){
String f = "public class QuineProgram { "
+ "public static void main(String[] args)"
+ "{ String f =%c%s%1$c;"
+ " System.out.printf(f,34,f);}} ";
System.out.printf(f, 34, f);
}
}
Output:
public class QuineProgram { public static void main(String[] args){ String f ="public class QuineProgram { public static void main(String[] args){ String f =%c%s%1$c; System.out.printf(f,34,f);}} "; System.out.printf(f,34,f);}}

You could use the Java Compiler API (JSR-199) for this. Below, code from the JSR-199 that compiles code from a String (slightly modified to make it compile). The code actually compiles source code from the String into a byte array (i.e. it doesn't write to disk), loads it and then executes it via reflection:
MemoryFileManager.java: A file manager for compiling strings to byte arrays.
ByteArrayClassLoader.java: A class loader which loads classes from byte arrays.
CompileFromString.java: The class that wrap everything together.
That could be a starting point (credits to Peter Van der Ahé, the original author).
BTW, you need of course a JDK to use this API.

I don't know exactly what you want, but I think BeanShell is something you can use.
BeanShell is an interpreter. You can run uncompiled Java-code (So you give it a String with code and he runs it).
Of course if you really want to do what you wrote, the machine where the program is running needs a JDK to compile your program.
Hope this helps

I dont think it will work in Java. Wouldn't that involve overwriting a running class file.
Suppose your program is in Quine.java compiled to Quine.class.
Now Quine.class will attempt to write its output to Quine.java (so far so good), and compile it to Quine.class. This is gonna be a problem as Quine.class is already running

Yes - don't forget to use a JDK instead of a JRE:
Bundle the app's source code files with the app. The app would copy the source files to a new set of source code files, compile the new source files, bundle the new source code with the new class files into a new app, and then spawn the new app.
or
Bundle a decompiler with the app. The app would run the decompiler on its own class files to generate new source code files, compile the new source files, bundle the decompiler with the new class files into a new app, and then spawn the new app.

Here's a Java Quine using preview text block feature (-source 13 --enable-preview) where output is formatted the same as input:
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f ="""
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f =""%c%c%s%1$c"";
System.out.printf(f, 34, 10, f);
}
}
""";
System.out.printf(f, 34, 10, f);
}
}
Output:
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f ="""
package org.sample.quine;
public class QuineProgram
{
public static void main(String...args)
{
String f =""%c%c%s%1$c"";
System.out.printf(f, 34, 10, f);
}
}
""";
System.out.printf(f, 34, 10, f);
}
}
Heavily Commented Version:
package org.sample.quine;
public class Quine
{
public static void main(String...args)
{
// Inside text block use "" followed by token or token followed by "" so that we don't prematurely close text block
String f ="""
package org.sample.quine;
public class Quine
{
public static void main(String...args)
{
// Inside text block use "" followed by token or token followed by "" so that we don't prematurely close text block
String f =""%c%c%s%1$c"";
/* Tokens in template text block, each prefixed with percent symbol
* 1(c) third quote (34) of open block delimiter
* 2(c) new line (10) of open block delimiter
* 3(s) String f text block that goes between two text block delimiters
* 4(1$c) first quote (34) of close block delimiter,
* 1$ means first argument after template argument
* 2$ would be second argument after template argument
*/
// Arguments - 1 template (String f); 2 "; 3 newline; 4 template again without replacing tokens
System.out.printf(f, 34, 10, f);
}
}
""";
/* Tokens in template text block, each prefixed with percent symbol
* 1(c) third quote (34) of open block delimiter
* 2(c) new line (10) of open block delimiter
* 3(s) String f text block that goes between two text block delimiters
* 4(1$c) first quote (34) of close block delimiter,
* 1$ means first argument after template argument
* 2$ would be second argument after template argument
*/
// Arguments - 1 template (String f); 2 "; 3 newline; 4 template again without replacing tokens
System.out.printf(f, 34, 10, f);
}
}

Related

Is there a way to store code as variables in java?

In Java, is there a way to store, edit, convert, print, access, evaluate and compare blocks of code (possibly user entered), while also being able to execute them?
An example for where this would be useful is if someone codes an software that is designed to teach people how to code, where the user would input code to the system, and the program would check if the user developed code is
I'm looking for something like this:
CodeBlock line20And21 = `String x = "hello"; System.out.println(x);`; // stores a block of code
line20And21.replace("ln",""); //edits the block of code
System.out.println(line20And21.toString()); // converts/prints the block of code
CodeBlock usersCode = Scanner.nextCodeBlock(); // accesses block of code
if(! line20And21.wouldThrowError()); // evaluates block of code
if(line20And21.wouldDoTheSameThingAs(line18And19)) // compares blocks of code
line20And21.execute(); // executes the block of code
The code I would be using is of course much more complicated than just defining a String and printing it, but I'm sure the idea would be the same.
I really appriciate any help with this. Thanks!
Since Java 9, Java includes a shell to evaluate snippets, called JShell. JShell is programatically available via jdk.shell.
First you have to create an instance of the JShell via JShell js = JShell.create().
Evaluating a String as Java code (a so called code Snippet) is done via js.eval("System.out.println(/"Hello World/")");, which returns a list of SnippetEvents you can inspect to find out what effect the execution of the code snippet had.
Since the code is stored as a String, you can edit it as you would edit any String.
Here is an example of JShell taking user inputted code and storing/evaluating it, taken from the official java docs, where code is read as string from stdin and executed:
import java.io.ByteArrayInputStream;
import java.io.Console;
import java.util.List;
import jdk.jshell.*;
import jdk.jshell.Snippet.Status;
class ExampleJShell {
public static void main(String[] args) {
Console console = System.console();
try (JShell js = JShell.create()) {
do {
System.out.print("Enter some Java code: ");
String input = console.readLine();
if (input == null) {
break;
}
List<SnippetEvent> events = js.eval(input);
for (SnippetEvent e : events) {
StringBuilder sb = new StringBuilder();
if (e.causeSnippet == null) {
// We have a snippet creation event
switch (e.status) {
case VALID:
sb.append("Successful ");
break;
case RECOVERABLE_DEFINED:
sb.append("With unresolved references ");
break;
case RECOVERABLE_NOT_DEFINED:
sb.append("Possibly reparable, failed ");
break;
case REJECTED:
sb.append("Failed ");
break;
}
if (e.previousStatus == Status.NONEXISTENT) {
sb.append("addition");
} else {
sb.append("modification");
}
sb.append(" of ");
sb.append(e.snippet.source());
System.out.println(sb);
if (e.value != null) {
System.out.printf("Value is: %s\n", e.value);
}
System.out.flush();
}
}
} while (true);
}
System.out.println("\nGoodbye");
}
}
You can do things like this with BeanShell, a Java interpreter written in Java:
import bsh.Interpreter;
class Test {
public static void main(String[] args) throws Exception {
String code = "String x = \"hello\"; System.out.println(x);";
String newCode = code.replace("ln", "");
System.out.println("Here's the result of running: " +newCode);
Interpreter p = new Interpreter();
p.eval(newCode);
}
}
If compiled and built with the right dependencies, you can evaluate the snippet:
$ javac -cp bsh-2.0b4.jar:. Test.java && java -cp bsh-2.0b4.jar:. Test
Here's the result of running: String x = "hello"; System.out.print(x);
hello$
You can run the code and get its output or return values, or whether it throws an exception. Sandboxing and comparing the output of two snippets is up to you.
Mostly: No.
Java code goes through a compilation step, code needs to be in methods (which need to be in types), and the reasons for this take quite a while to explain. The compiler does not need to be there at runtime (and often isn't).
So, if you really want to do this:
Code has to be 'complete', including a package statement, a class declaration, a method, etc.
You need to ship the compiler with the app. For javac, that's tricky (GPL); you could ship ecj (eclipse's compiler) which is MIT licensed. It's quite a dep.
You can then 'store' code as strings.
ecj can then turn this into bytecode for you, but you'll have quite a time managing the classpath properly to make this code compile correctly.
You can then dynamically load this bytecode by using a classloader which has a learning curve of a few days all by itself.
In addition, looking at code without executing it to determine if it would throw an exception or not is literally impossible - this is called the halting problem. There exists proof that it is unsolvable. You can't go faster than light. You can't determine from arbitrary code written in a 'turing complete' language (and java is turing complete) if it halts or not (or in this case, if it throws or not).
Similar rules apply to 'would this do the same thing as'.

Line number counter using java AST parser

I have some interesting exercise - to read .java file with Java, to find every code part in this .java file(like methods and etc.) and to say how many line numbers we have in every method without whitespaces and comments and also to find the count of items in every method.
Here is some example that I use - so could Java Parser. With the code I can say how many line numbers I have in method, but cannot remove the count of whitespaces and comments. Can someone help me?
The code:
public static void main(String[] args) throws ParseException, IOException {
File f = new File(".").getAbsoluteFile();
File srcRoot = new File(f, "src");
String srcFilename = TestMethodLineNumber.class.getName().replaceAll("\\.", "/") + ".java";
File src = new File(srcRoot, srcFilename);
System.out.println(f);
System.out.println(srcRoot);
System.out.println(src);
getMethodLineNumbers(src);
}
private static void getMethodLineNumbers(File src) throws ParseException, IOException {
CompilationUnit cu = JavaParser.parse(src);
new MethodVisitor().visit(cu, null);
}
/**
* Simple visitor implementation for visiting MethodDeclaration nodes.
*/
private static class MethodVisitor extends VoidVisitorAdapter {
#Override
public void visit(MethodDeclaration m, Object arg) {
System.out.println("From [" + m.getBeginLine() + "," + m.getBeginColumn() + "] to [" + m.getEndLine() + ","
+ m.getEndColumn() + "] is method:");
System.out.println(m);
}
}
}
It looks to me like JavaParser already removes blank lines, I would use a technique from this thread Removing all types of comments in java file to remove all the comments and then use JavaParser to get your results.
In general questions like these aren't always interesting unless you're actually going after executable code. Consider:
if (a)
{
runA();
}
else
{
runB();
}
You're count will be 8, what exactly does that tell you? Is it more interesting to know there is one if statement and/or two method calls? You'll really want better constraints to know what you're going after:
a ? runA() : b ? runB(): runError("nothing true");
Is only one line, but you have 3 potential execution branches. You can also run into some pretty crazy statements that span multiple lines.
MyFancyObject myFancyObject = new MyFancyObject("This is my really long name",
123113212,
"2014-11-20 18:43:12",
anotherArg, yetAnother,
moar);
Should this be 5 lines or 1?

Echo class in Java

Please help me with this HW assignment. I am supposed to modify the EchoNumber class which extends the Echo class to count the number of characters in every line in a text file in addition to displaying the text. Here is the Echo class:
import java.util.Scanner;
import java.io.*;
public class Echo{
String fileName; // external file name
Scanner scan; // Scanner object for reading from external file
public Echo(String f) throws IOException
{
fileName = f;
scan = new Scanner(new FileReader(fileName));
}
// reads lines, hands each to processLine
public void readLines(){
while(scan.hasNext()){
processLine(scan.nextLine());
}
scan.close();
}
// does the real processing work
public void processLine(String line){
System.out.println(line);
}
}
Here is the EchoNumber class, notice where it says "Your code goes here":
import java.io.*;
public class EchoNumber extends Echo
{
// the current line number
private int lineNumber;
public EchoNumber (String datafile) throws IOException
{
super( datafile);
lineNumber=1;
}
// Prints a line with a leading line number and a trailing line length
// Overrides the processLine method in Echo class
public void processLine(String line){
/* your code goes here */
}
}
Here is the EchoTester class:
import java.io.*;
import java.util.Scanner;
public class EchoTester
{
public static void main(String[] args)
{
// uses try/catch to handle IOExceptions in main
try
{
String fileName;
Scanner nameReader = new Scanner(System.in);
System.out.println("Enter a file name");
fileName = nameReader.nextLine();
EchoNumber e = new EchoNumber(fileName);
e.readLines();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
And finally the .txt file:
The best things in life are free
A stitch in time saves nine
Still waters run deep
He teaches ill who teaches all
You can not take it with you when you die
Better untaught than ill taught
Do not cross your bridges before you come to them
Soon learnt soon forgotten
Even a worm will turn
It was the last straw that broke the camels back
The way to a mans heart is through his stomach
If the stone fall upon the egg alas for the egg If the egg fall upon the stone alas for the egg
Where there is a will there is a way
Marry in haste and repent at leisure
One tongue is enough for a woman
If you wish good advice consult an old man
The best advice is found on the pillow
All clouds bring not rain
You can not tell a book by its cover
No news is good news
Bad news travels fast
Live and let live
Birds of a feather flock together
Now is the time
For all good men who actually have the time
To come to the aid of the country in which they live
The output is supposed to be something like:
1 The best things in life are free-32
2 A stitch in time saves nine-27
3 Still waters run deep-21
4 He teaches ill who teaches all-30
5 You can not take it with you when you die-41
6 Better untaught than ill taught-31
7 Do not cross your bridges before you come to them-49
8 Soon learnt soon forgotten-26
9 It was the last straw that broke the camels back-48
Except without spaces between each line. For some reason it fuses into one paragraph if I did not separate each line.
Something like this:
public void processLine(String line){
System.out.println(lineNumber + " " + line + "-" + line.length());
++lineNumber;
}
I haven't tested it, so if it isn't 100% correct, I'll leave it as an exercise for you to complete, but it should put you on the right track. Good luck.
THIS is the correct code. It is important that lineNumber++ is below the print statement!
System.out.println(lineNumber + " " + line + "-" + line.length());
lineNumber++;

args in '.bat' file contain some spaces, how could I get the args correctly?

Stat command in cmd:
start.bat -arg1 -ar g2 -arg3
How can I get the second arg? The string 'ar g2' contain one space .
I need get the args(may contain space character) from bat file, then I will handle them in the java file.
Could anybody give me a solution? Thanks very much.
On the (DOS/Windows) command line, you should always surround arguments that contain spaces, with quotes. E.g.
start.bat -arg1 "-ar g2" -arg3
Surrounding each and every argument with quotes, even ones without spaces, will not hurt, but your batch script needs to remove the quotes then (see code samples below).
This has been the case for as long as I can remember (pre-Windows 3.1 DOS days). When long filenames (which could include spaces) were implemented, this became more common. E.g.
C:\Users\adam>copy "My Documents" "My Backup Files"
(try it without quotes too).
This is the CMD way, and any programs called from the CMD will understand this correctly.
Code Samples (may be useful for debugging, to see what actually is returned. Run the Batch file or Java class with a list of arguments and play around.)
Batch script (the ~ (tilde) character is the important thing, it removes the surrounding quotes):
#echo off
FOR %%a IN (%*) DO echo [%%~a]
Java (surrounding quotes automatically removed)
public class TestArg {
public static void main(String[] args) {
for (String a : args) {
System.out.println("[" + a + "]");
}
}
}
Isnt it possible to split the string with | character, and then trim the values (left + right) ? This should preserve the spaces inbetween.
You could use something like below... just proof of concept code, the rest you'll need to do yourself... or buy a book on java programming like I did.
public static void main(String argv[])
{
String argument1 = "";
String argument2 = "";
String argument2value = "";
String argument3 = "";
for(int c=0;c<argv.length;c++)
{
if(argv[c].indexOf("-")==0)
{
if(argument1.length() == 0)
{
argument1 = argv[c].substring(1,argv[c].length());
}
if(argument2.length() == 0)
{
argument2 = argv[c].substring(1,argv[c].length());
}
}
else
{
if(argument2.length() != 0)
{
argument2value = argument2value + argv[c]
}
}
}
}

Split a string containing command-line parameters into a String[] in Java

Similar to this thread for C#, I need to split a string containing the command line arguments to my program so I can allow users to easily run multiple commands. For example, I might have the following string:
-p /path -d "here's my description" --verbose other args
Given the above, Java would normally pass the following in to main:
Array[0] = -p
Array[1] = /path
Array[2] = -d
Array[3] = here's my description
Array[4] = --verbose
Array[5] = other
Array[6] = args
I don't need to worry about any shell expansion, but it must be smart enough to handle single and double quotes and any escapes that may be present within the string. Does anybody know of a way to parse the string as the shell would under these conditions?
NOTE: I do NOT need to do command line parsing, I'm already using joptsimple to do that. Rather, I want to make my program easily scriptable. For example, I want the user to be able to place within a single file a set of commands that each of which would be valid on the command line. For example, they might type the following into a file:
--addUser admin --password Admin --roles administrator,editor,reviewer,auditor
--addUser editor --password Editor --roles editor
--addUser reviewer --password Reviewer --roles reviewer
--addUser auditor --password Auditor --roles auditor
Then the user would run my admin tool as follows:
adminTool --script /path/to/above/file
main() will then find the --script option and iterate over the different lines in the file, splitting each line into an array that I would then fire back at a joptsimple instance which would then be passed into my application driver.
joptsimple comes with a Parser that has a parse method, but it only supports a String array. Similarly, the GetOpt constructors also require a String[] -- hence the need for a parser.
Here is a pretty easy alternative for splitting a text line from a file into an argument vector so that you can feed it into your options parser:
This is the solution:
public static void main(String[] args) {
String myArgs[] = Commandline.translateCommandline("-a hello -b world -c \"Hello world\"");
for (String arg:myArgs)
System.out.println(arg);
}
The magic class Commandline is part of ant. So you either have to put ant on the classpath or just take the Commandline class as the used method is static.
If you need to support only UNIX-like OSes, there is an even better solution. Unlike Commandline from ant, ArgumentTokenizer from DrJava is more sh-like: it supports escapes!
Seriously, even something insane like sh -c 'echo "\"un'\''kno\"wn\$\$\$'\'' with \$\"\$\$. \"zzz\""' gets properly tokenized into [bash, -c, echo "\"un'kno\"wn\$\$\$' with \$\"\$\$. \"zzz\""] (By the way, when run, this command outputs "un'kno"wn$$$' with $"$$. "zzz").
You should use a fully featured modern object oriented Command Line Argument Parser I suggest my favorite Java Simple Argument Parser. And how to use JSAP, this is using Groovy as an example, but it is the same for straight Java. There is also args4j which is in some ways more modern than JSAP because it uses annotations, stay away from the apache.commons.cli stuff, it is old and busted and very procedural and un-Java-eques in its API. But I still fall back on JSAP because it is so easy to build your own custom argument handlers.
There are lots of default Parsers for URLs, Numbers, InetAddress, Color, Date, File, Class, and it is super easy to add your own.
For example here is a handler to map args to Enums:
import com.martiansoftware.jsap.ParseException;
import com.martiansoftware.jsap.PropertyStringParser;
/*
This is a StringParser implementation that maps a String to an Enum instance using Enum.valueOf()
*/
public class EnumStringParser extends PropertyStringParser
{
public Object parse(final String s) throws ParseException
{
try
{
final Class klass = Class.forName(super.getProperty("klass"));
return Enum.valueOf(klass, s.toUpperCase());
}
catch (ClassNotFoundException e)
{
throw new ParseException(super.getProperty("klass") + " could not be found on the classpath");
}
}
}
and I am not a fan of configuration programming via XML, but JSAP has a really nice way to declare options and settings outside your code, so your code isn't littered with hundreds of lines of setup that clutters and obscures the real functional code, see my link on how to use JSAP for an example, less code than any of the other libraries I have tried.
This is a direction solution to your problem as clarified in your update, the lines in your "script" file are still command lines. Read them in from the file line by line and call JSAP.parse(String);.
I use this technique to provide "command line" functionality to web apps all the time. One particular use was in a Massively Multiplayer Online Game with a Director/Flash front end that we enabled executing "commands" from the chat like and used JSAP on the back end to parse them and execute code based on what it parsed. Very much like what you are wanting to do, except you read the "commands" from a file instead of a socket. I would ditch joptsimple and just use JSAP, you will really get spoiled by its powerful extensibility.
/**
* [code borrowed from ant.jar]
* Crack a command line.
* #param toProcess the command line to process.
* #return the command line broken into strings.
* An empty or null toProcess parameter results in a zero sized array.
*/
public static String[] translateCommandline(String toProcess) {
if (toProcess == null || toProcess.length() == 0) {
//no command? no string
return new String[0];
}
// parse with a simple finite state machine
final int normal = 0;
final int inQuote = 1;
final int inDoubleQuote = 2;
int state = normal;
final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
final ArrayList<String> result = new ArrayList<String>();
final StringBuilder current = new StringBuilder();
boolean lastTokenHasBeenQuoted = false;
while (tok.hasMoreTokens()) {
String nextTok = tok.nextToken();
switch (state) {
case inQuote:
if ("\'".equals(nextTok)) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
current.append(nextTok);
}
break;
case inDoubleQuote:
if ("\"".equals(nextTok)) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
current.append(nextTok);
}
break;
default:
if ("\'".equals(nextTok)) {
state = inQuote;
} else if ("\"".equals(nextTok)) {
state = inDoubleQuote;
} else if (" ".equals(nextTok)) {
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
current.setLength(0);
}
} else {
current.append(nextTok);
}
lastTokenHasBeenQuoted = false;
break;
}
}
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
}
if (state == inQuote || state == inDoubleQuote) {
throw new RuntimeException("unbalanced quotes in " + toProcess);
}
return result.toArray(new String[result.size()]);
}
Expanding on Andreas_D's answer, instead of copying, use CommandLineUtils.translateCommandline(String toProcess) from the excellent Plexus Common Utilities library.
I use the Java Getopt port to do it.

Categories

Resources