1

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

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

javah例如,在生成 .h 文件时,如何哄骗始终使用 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"在这样做之前显式设置属性。但是,我找不到那会是什么课程,或者在哪里。

4

2 回答 2

1

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

于 2013-01-15T22:28:03.600 回答
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>
于 2013-01-17T05:17:43.330 回答