Error in piping java programs

908 views Asked by At

I have a class RandomSeq which prints "args[0]" random doubles and a class Average which prints the average of StdIn. I'm using DrJava for writing codes and compiling.I've downloaded the StdIn and out libraries and put them in the same folder of my classes. I'm learning Java.

First problem is in the "Interactions" section of DrJava. When I write java RandomSeq 10 > data.txt instead of creating the text file, it prints the output. Why?
Then I typed the same command in Windows command line. It created the txt file successfully.

Now I want to pipe the output of RandomSeq 10 to the input of Average. Writing java RandomSeq 10 | java Average in DrJava's Interactions section causes funny behaviour. Writing it in cmd prints the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: StdIn
        at Average.main(Average.java:7)
Caused by: java.lang.ClassNotFoundException: StdIn
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

Even java Average < data.txt shows the same error.Why?

public class RandomSeq
{
    public static void main(String[] args)
    {
        int N = Integer.parseInt(args[0]);
        for (int i = 0; i < N; i++)
        {
            System.out.println(Math.random());
        }
    }
}




public class Average
{
    public static void main(String [] args)
    {
        double S = 0;
        int i = 0;
        while (!StdIn.isEmpty())
        {
            double n = StdIn.readDouble();
            S += n;
            i++;
        }
        S = S/i;
        //StdOut.printf("The mean is %.3f", S);
        StdOut.println(S);
    }
}
2

There are 2 answers

1
matrixanomaly On BEST ANSWER

This is a related question on StdIn. StdIn is not a standard java library, as you mentioned that you're following the Princeton course, that StdIn.java is provided by the course, you probably need to compile StdIn.java as well, with the command javac StdIn.javato generate a StdIn.class file, this will solve the Class not Found Exception. (the second issue)

As to the problem of you writing java RandomSeq 10 > data.txt in DrJava (which I asked for clarification because I didn't realize DrJava is an IDE, thought it was a book), is because the Interactions section most likely directly gives the input to your program, meaning it passes whatever you type in there as args[] for your main function.

The output is printed because you call system.out.println in your code, and DrJava just takes that output and prints it out to the screen, and won't pipe to your data.txt file. I would recommend that since you're using course material that requires stuff like piping to interact with your program in the command line.

Lastly java RandomSeq 10 | java Average is the same as doing java RandomSeq 10 and then taking that output into java Average, which the second command is the same as you doing java Average < data.txt, the error isn't because of how you're piping it, but just because of StdIn not being present as a compiled .class file.

2
sparc_spread On

StdIn is not from a built-in Java library. It is part of a 3rd party library that is contained in a stdlib.jar file that can be downloaded from here.

The path to that JAR file must be in the -CLASSPATH option of your command-line javac and java invocations. The Using the standard libraries section of this page shows you how to do this; the -cp option is just shorthand for -CLASSPATH. It is important to learn how to put libraries onto your CLASSPATH, as you'll eventually be doing it all the time with Java.

Your Average.java code must also import the StdIn class. Since StdIn does not reside in a named package, you just say import StdIn; at the top of your code.

Alternatively, you could just use System.in, rather than this library. You probably also want a higher level stream construct around that. Here's a nice example.