JNI JVM 调用类路径

2024-03-29

我正在使用 Cygwin 编写一个小型 C 程序,该程序启动 Java 虚拟机(我使用的库需要 POSIX 环境)。到目前为止,只要将所有类放在与可执行文件相同的文件夹中,我就可以让它工作。但是,我想指定一个实际的 JAR 文件,其中包含我要运行的应用程序。但这似乎不起作用,FindClass 只是返回一个 null。正如我所说,我已将其范围缩小到类路径设置的问题,因为我可以将 jar 文件提取到与可执行文件相同的目录中,并且它可以工作。这是我的代码的一个子集:

我一直在宽松地遵循本指南:http://www.inonit.com/cygwin/jni/invocableApi/ http://www.inonit.com/cygwin/jni/invocationApi/

int main( int argc, char *argv[] )
{
        void* jvmDllHandle;
        JNIEnv* jenv;
        JavaVM* jvm;
        JavaVMInitArgs args;
        JavaVMOption options[1];
        jclass cls;
        jmethodID mainMethod;
        jobjectArray appArgs;
        jstring arg0;

        assert( cygwin_internal( CW_SYNC_WINENV ) != 1UL );

        jvmDllHandle = LoadLibrary( "c:\\Path\\To\\Application\\jre\\bin\\server\\jvm.dll" );
        createJavaVM = dlsym( jvmDllHandle, "JNI_CreateJavaVM" );

        args.version = JNI_VERSION_1_6;
        args.nOptions = 1;
        options[0].optionString = "-Djava.class.path=c:\\Path\\To\\Application\\TheJarFile.jar";
        args.options = options;
        args.ignoreUnrecognized = JNI_FALSE;

        createJavaVM( &jvm, (void **) &jenv, &args );

        cls = (*jenv)->FindClass( jenv, "some/package/MainClass" );
        assert( cls != NULL );  // This fails.

        /// Omitted...

        return 0;
}

尝试使用 -classpath 和 -cp

int main( int argc, char *argv[] )
{
        void* jvmDllHandle;
        JNIEnv* jenv;
        JavaVM* jvm;
        JavaVMInitArgs args;
        JavaVMOption options[1];
        jclass cls;
        jmethodID mainMethod;
        jobjectArray appArgs;
        jstring arg0;

        assert( cygwin_internal( CW_SYNC_WINENV ) != 1UL );

        jvmDllHandle = LoadLibrary( "c:\\Path\\To\\Application\\jre\\bin\\server\\jvm.dll" );
        createJavaVM = dlsym( jvmDllHandle, "JNI_CreateJavaVM" );

        args.version = JNI_VERSION_1_6;
        args.nOptions = 1;
        options[0].optionString = "-classpath c:\\Path\\To\\Application\\TheJarFile.jar";
        args.options = options;
        args.ignoreUnrecognized = JNI_FALSE;

        createJavaVM( &jvm, (void **) &jenv, &args );

        cls = (*jenv)->FindClass( jenv, "some/package/MainClass" );
        assert( cls != NULL );  // This fails.

        /// Omitted...

        return 0;
}

我如何错误地指定了类路径?


在 x86-64 上,Oracle Windows JDK 标头定义jint as long。使用 Microsoft 编译器(Oracle JDK 是为其编写的)时为 32 位,使用 Cygwin gcc 时为 64 位。自从JavaVMInitArgs包含一些这种类型的字段,它的二进制布局会因这种差异而改变。

我通过提供本地解决方案解决了这个问题jni.h header:

#include "stdint.h"

#define __int64 int64_t
#define long int32_t
#include "jni_md.h"
#undef long

#include_next "jni.h"

我只包括jni_md.h的范围内long重新定义,因为它不包含任何其他标头,而jni.h包括一些我们也不希望受到影响的标准标头。

为了确保它始终包含在 Oracle 标头之前,请使用-I编译器选项将其目录添加到#include path.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JNI JVM 调用类路径 的相关文章

  • 如何在 C# 控制台应用程序中将修饰符(ctrl、alt、shift)按键捕获为单个按键?

    Console ReadKey 仅在按下 正常 键时捕获输入 然后将修饰符 如果有 附加为键信息的一部分 如何将单个修饰键注册为输入 提供了一种解决方案这个链接 https blogs msdn microsoft com toub 200
  • vs2008 c#:Facebook.rest.api如何使用它来获取好友列表?

    如何在此基础上取得进一步的进步 获取好友列表的下一步是什么 string APIKey ConfigurationManager AppSettings API Key string APISecret ConfigurationManag
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 列表过滤器内的 Java 8 lambda 列表

    示例 JSON id 1 products id 333 status Active id 222 status Inactive id 111 status Active id 2 products id 6 status Active
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • 子类构造函数(JAVA)中的重写函数[重复]

    这个问题在这里已经有答案了 为什么在派生类构造函数中调用超类构造函数时 id 0 当创建子对象时 什么时候在堆中为该对象分配内存 在基类构造函数运行之后还是之前 class Parent int id 10 Parent meth void
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • 抛出 Java 异常时是否会生成堆栈跟踪?

    这是假设我们不调用 printstacktrace 方法 只是抛出和捕获 我们正在考虑这样做是为了解决一些性能瓶颈 不 堆栈跟踪是在构造异常对象时生成的 而不是在抛出异常对象时生成的 Throwable 构造函数调用 fillInStack
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft

随机推荐