Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javac "no source files" when using -h option

I'm trying to experiment with using the JNI and JDK 9. I have a class NativeTest.java that looks like this:

public class NativeTest {

    static {
        System.loadLibrary("hello");
    }

    private native void sayHello();

    public static void main(String[] args) {
        new NativeTest().sayHello();
    }
}

I compile the class, then use javah NativeTest to generate the header file.

Upon issuing javah, I get this warning:

Warning: The javah tool is planned to be removed in the next major
JDK release. The tool has been superseded by the '-h' option added
to javac in JDK 8. Users are recommended to migrate to using the
javac '-h' option; see the javac man page for more information.

I know it'll be quite a while before the next major JDK release, but I figured I'd start getting used to this new option now.

So upon trying javac -h NativeTest.java (and other variations like NativeTest, NativeTest.class, etc.) I keep getting this error:

javac: no source files

I haven't been able to find any help online, probably because this feature is relatively new, and I can't find anything about this new -h option in the man page.

Anyone else try this yet? What am I missing?

like image 242
David Mordigal Avatar asked Oct 05 '17 03:10

David Mordigal


People also ask

What is javac source?

Description. The javac command reads source files that contain module, package and type declarations written in the Java programming language, and compiles them into class files that run on the Java Virtual Machine. The javac command can also process annotations in Java source files and classes.

Do you have to javac everytime?

No, java programs are not automatically compiled every time they run. Java programs must be explicitly compiled before they can be executed.

How do I add a source file to javac?

There are two ways to specify source files to javac: For a small number of source files, you can list their file names on the command line. For a large number of source files, you can use the @filenameoption on the command line to specify an argument filethat lists their file names.

What are sourcefiles or classnames in javac?

javac[options] [sourcefiles-or-classnames] options Command-line options. sourcefiles-or-classnames Source files to be compiled (for example, Shape.java) or the names of previously compiled classes to be processed for annotations (for example, geometry.MyShape).

Can javac process annotations from source files?

The javaccommand can also process annotationsin Java source files and classes. Source files must have a file name extension of .java. Class files have a file name extension of .class. Both source and class files normally have file names that identify the contents.

How important is the Order of source files specified in javac?

The order of source files specified on the command line or in an argument file is not important. javacwill compile the files together, as a group, and will automatically resolve any dependencies between the declarations in the various source files.


3 Answers

The solution I discovered was that I was not specifying the directory where javac should place the header files.

Executing javac -h . NativeTest.java worked.

like image 179
David Mordigal Avatar answered Oct 24 '22 18:10

David Mordigal


In Java 8, you had to make intermediate step of generating class files to get C headers

Lets say you have following structure

recipeNo001
├── Makefile
├── README.md
├── c
│   └── recipeNo001_HelloWorld.c
├── java
│   └── recipeNo001
│       └── HelloWorld.java
├── lib
└── target

In Java (prior to JDK 9) you had to compile class and use javah with compiled sources

> export JAVA_HOME=$(/usr/libexec/java_home -v 1.8.0_11)
> ${JAVA_HOME}/bin/javac -d target java/recipeNo001/*.java
> ${JAVA_HOME}/bin/javah -d c -cp target recipeNo001.HelloWorld
# -d c       -> put generated codes inside c directory
# -cp target -> compiled classes are inside target dir

In Java 9 you can use javac -h with Java source code

> export JAVA_HOME=$(/usr/libexec/java_home -v 9)
> ${JAVA_HOME}/bin/javac -h c java/recipeNo001/HelloWorld.java
# -h c       -> create header file inside c directory
like image 40
Oo.oO Avatar answered Oct 24 '22 17:10

Oo.oO


The javah tool has been superseded by the "javac -h" feature . we should be able to just use the normal Java compiler (with the -h flag in Java 8+) to output those files during the Java compilation step.

Usage: -h directory Specifies where to place generated native header files.

When you specify this option, a native header file is generated for each class that contains native methods or that has one or more constants annotated with the java.lang.annotation.Native annotation. If the class is part of a package, then the compiler puts the native header file in a subdirectory that reflects the package name and creates directories as needed.

javac -h directory name NativeTest.java will solve the problem

like image 28
aswathy sali Avatar answered Oct 24 '22 18:10

aswathy sali