13

Can javac compile from stdin? Something like this :

cat myfile | javac
kofucii
  • 7,393
  • 12
  • 51
  • 79
  • 3
    What's the practical purpose for that? – A.H. Nov 05 '11 at 17:38
  • I think the intent might be for testing simple commands (e.g. new Float.parseFloat("")) to see what they'd do. Also, possibly to try and use java for things like sed one liners, etc. Kind of like a mini LinqPad for java ;-) – Brad Parks Jun 12 '12 at 12:48

4 Answers4

6

No, there is no option to do that.

From the documentation:

There are two ways to pass source code file names to javac:

  • For a small number of source files, simply list the file names on the command line.
  • For a large number of source files, list the file names in a file, separated by blanks or line breaks. Then use the list file name on the javac command line, preceded by an @ character.

Source code file names must have .java suffixes, class file names must have .class suffixes, and both source and class files must have root names that identify the class. For example, a class called MyClass would be written in a source file called MyClass.java and compiled into a bytecode class file called MyClass.class.

Community
  • 1
  • 1
Mat
  • 202,337
  • 40
  • 393
  • 406
1

You might try with /dev/stdin as the source file (and then, you'll need to find the option which forces javac to consider it as Java source code).

But I would just make a shell script which put the stdin on some temporary file suffixed with .java.

But I think (I am not sure) that javac really wants a class Foo to be defined inside a file named Foo.java.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

This is not possible with plain javac - the reason is that most Java programs consist of more than one class, which are usually also distributed over more than one source file (compilation unit).

You can probably build a tool which does this, using the Java compiler API for the actual compilation.

You would have to create a JavaFileManager which simulates files by the text from standard input, and pass this to the compiler.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
0

You can't do it with Sun java, but you can write a script to handle the conversion of stdin to something javac can understand.

Something like this Python script:

import fileinput, re, subprocess

class_name = None

buffer = []
class_matcher = re.compile('\w+ class (?P<name>\w+)')

for line in fileinput.input():
    if None == class_name:
        buffer.append(line)
        m = class_matcher.match(line)
        if m:
            class_name = m.group('name')
            print "found %s" % class_name
            file_name = '%s.java' % class_name
            out = open(file_name, 'wb')
            out.writelines(buffer)
    else:
        out.write(line)

if None == class_name:
    print "Error: no class found"

else:
    out.close()

    print 'javac %s' % file_name
    output = subprocess.call(['javac', file_name])

Note that the script will create a file of the name of the class in the current directory. It's probably better to use something in /tmp, but keep in mind that it has to be named the same as the class. If you are testing the script don't do something like this:

cat MyImportantJava.java | python javac-stdin.py
Scott A
  • 7,745
  • 3
  • 33
  • 46