是否可以使用javah来生成具有一致行结尾的.h文件?

时间:2013-01-15 04:30:25

标签: java java-native-interface newline javah

我有一个maven项目,它通过执行javah生成.h JNI文件,作为java库正常构建过程的一部分。然后将这些.h文件签入源代码控制(例如git)并用于构建随附的本机库。

一个小麻烦是javah生成的文件因行结尾而异,具体取决于运行它的平台。因此,如果Mac OSX开发人员运行构建并签入(UNIX样式行结尾),那么Windows开发人员随后将看到他们的构建已经更改了所有.h文件(到Windows样式行)结局)。但它们实际上并没有改变 - javah只是以平台依赖的方式表现。

如何生成.h文件时,如何使javah始终使用UNIX样式的行结尾?似乎没有适当的命令行开关:

> javah.exe
Usage:
  javah [options] <classes>
where [options] include:
  -o <file>                Output file (only one of -d or -o may be used)
  -d <dir>                 Output directory
  -v  -verbose             Enable verbose output
  -h  --help  -?           Print this message
  -version                 Print version information
  -jni                     Generate JNI-style header file (default)
  -force                   Always write output files
  -classpath <path>        Path from which to load classes
  -bootclasspath <path>    Path from which to load bootstrap classes
<classes> are specified with their fully qualified names
(for example, java.lang.Object).

也许可以手动启动与javah可执行文件启动相同的类,除非在执行此操作之前显式设置"line.separator"属性。但是,我找不到会是什么类,或者在哪里。

2 个答案:

答案 0 :(得分:1)

在这方面,'javah'与其他Java程序相同。行终止符由例如PrintWriter.println(),由系统属性'line.separator'确定。你可以尝试从命令行设置它,但我怀疑你会得到任何喜悦。我会寻找一个更加横向的解决方案,例如按照建议重新配置IDE,或者只在一台构建机器上运行javap。

答案 1 :(得分:0)

我通过编写一个显式设置line.separator属性的自定义启动器,然后在构建期间调用该启动器来解决这个问题:

public class JavahLauncher {

    public static void main(String[] args) {
        String original = System.getProperty("line.separator");
        System.setProperty("line.separator", "\n");
        try {
            com.sun.tools.javah.Main.run(args, new PrintWriter(System.out));
        }
        finally {
            System.setProperty("line.separator", original);
        }
    }
}

try-finally允许在执行构建时在另一个JVM(例如Maven的JVM实例)内调用此启动程序,而不会永久更改line.separator值。一个有趣的注意事项com.sun.tools.javah.Main.main是不可用的,因为它调用System.exit,如果作为Maven构建的一部分调用,会导致Maven退出!

编译此启动器需要依赖tools.jar,例如:

<dependency>
    <groupId>com.sun</groupId>
    <artifactId>tools</artifactId>
    <version>1.7.0</version>
    <scope>system</scope>
    <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>