【问题标题】:Can javah be coaxed to generate .h files with consistent line endings?javah 可以被哄骗生成具有一致行尾的 .h 文件吗?
【发布时间】:2013-01-15 04:30:25
【问题描述】:

我有一个 maven 项目,它通过执行 javah 作为 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" 属性。但是,我找不到那会是什么课程,也不知道在哪里。

【问题讨论】:

  • 或者版本控制应该更好地处理这个? help.github.com/articles/dealing-with-line-endings
  • 我宁愿不依赖版本控制系统来处理这里的行尾。我正在寻找一种适用于任何类型的版本控制系统的解决方案,即修复javah 行为的解决方案。
  • 我明白了。你如何处理其他类型的文件?他们也有类似的问题?
  • 其他文件没问题,因为大多数编辑器都知道在编辑文件时要保留行尾。但是这些文件是自动生成的,javah 不关心保留行尾。

标签: java java-native-interface newline javah


【解决方案1】:

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

【讨论】:

  • 我尝试在命令行上设置line.separator 值......然后意识到这将是一个巧妙的技巧。毕竟,如何在没有命令处理器解释的情况下将 '\n' 放在命令行上?然后以跨平台兼容的方式做到这一点? (小注:你的回答指的是javap,但我说的是javah
【解决方案2】:

我通过编写一个显式设置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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 2018-08-28
    • 2023-03-11
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 2011-09-05
    相关资源
    最近更新 更多