Java Native Interface(JNI)的一个组成部分是通过C头桥接JVM代码和本机代码.生成这些头文件的方法过去非常简单:只需javah
在类文件上调用命令行实用程序即可.然后,此过程将为使用native
修饰符标记的任何方法生成原型.
但是,从Java 10开始,该javah
实用程序已被删除,其建议的替换是javac的新标志"-h".如果有可用的Java源文件,则替换可以正常工作,但是只有编译的类文件可用时才会出现问题.(引发这个问题的问题是我正在尝试从Scala源生成JNI绑定.我当前的方法是首先编译它们然后在生成的类文件上运行javah.)
在只有编译的类文件可用的情况下,有没有办法生成C头文件,类似于以往的方式javah
?
我有一个项目使用SBT作为构建系统,并将Scala/Java和本机源与JNI结合在一起.
为了保持尽可能灵活,我目前计划发布这种项目是发布两个不同的jar:一个包含纯字节码(本机二进制的引用留给最终用户)和一个胖jar也包含本机库并自动提取它们.
为了生成一个胖jar,我创建了一个名为的任务packageFat
,它基本上将任务复制packageBin
到本机库,并在名称后附加'-fat'后缀.
可以在此处查看构建配置的相关部分:https://github.com/jodersky/flow/blob/master/project/nativefat.scala
但是,使用这种配置,任何依赖于我并希望包含fat jar的项目都必须以这种形式声明依赖:
libraryDependencies += "<organization>" %% "<name>" % "<version>" artifacts Artifact("<name>-fat", "jar", "jar")
我知道使用JNI分发项目有点笨拙,但是在最后一个'%'之后的部分,使依赖真的很麻烦.所以我的问题是:SBT从一个项目中发布一个普通jar和一个胖罐的惯用方法是什么?
在用于串行通信的多线程Linux程序中,是否有可能(以及最好的方法)终止来自另一个线程的阻塞read()调用?
我希望尽可能保持一切反应,并避免在重复轮询时使用超时.
这个问题的背景是我正在尝试使用JNI为Linux创建一个Scala串行通信库.我试图保持原生方尽可能简单,除其他外,提供read()和close()函数.在Scala端,一个线程将调用read()并阻塞,直到来自串行端口的数据可用.但是,串口可以通过其他方式关闭,从而调用close().现在,为了释放被阻止的线程,我会以某种方式取消系统读取调用.
我正在尝试在配置sbt设置时打印警告消息.我最初的尝试看起来像这样:
setting := {
val log = streams.value.log
val condition = //check something
if (condition) {
log.warn("Warning, condition! Specific functionality may not work.")
//some default
} else {
//something else
}
}
Run Code Online (Sandbox Code Playgroud)
但是,由于streams
是TaskKey,因此只能从任务访问其值.此外,我的设置被其他设置重用,因此我无法将其定义为任务.
因此我的问题是:在设置初始化期间打印警告的最佳方法是什么?
作为客户端,仅使用标准 Java 库,如何在事先知道将使用该协议版本的情况下建立不安全的HTTP/2 连接?即不首先通过 HTTP/1.1 发送升级请求。
我尝试过使用 中的实用程序java.net.http
,调用version(HttpClient.Version.HTTP_2)
请求和客户端构建器,但是初始请求始终通过 HTTP/1.1 发送,并带有升级标头。到目前为止,从一开始就强制使用版本 2 的唯一方法似乎是使用 https 上的安全连接(我想避免这种情况)。
我还想坚持只使用 OpenJDK 11 中包含的类(没有 netty 等)。
POM是否可以声明(或至少发布)artifactId
包含系统属性?我的意思是实际项目的artifactId,而不是依赖项.
我正在使用maven来构建一个scala项目,因此,为了允许在pom.xml中发布不同scala版本的项目,我想声明:
<artifactId>myproject_${scalaBinaryVersion}</artifactId>
然而maven 3.3.抱怨
[警告]'artifactId'包含一个表达式,但应该是一个常量
既然我希望这个项目可以与sbt互操作,那么发布一个后缀为scala二进制版本的工件的最佳方法是什么?