我有一个服务器应用程序在大多数情况下运行良好,但在一台 solaris 机器上它无法打开选择器,对于 root 用户它工作正常。对于其他用户,它给出以下异常
java.io.IOException: Permission denied
at sun.nio.ch.DevPollArrayWrapper.init(Native Method)
at sun.nio.ch.DevPollArrayWrapper.<init>(DevPollArrayWrapper.java:74)
at sun.nio.ch.DevPollSelectorImpl.<init>(DevPollSelectorImpl.java:54)
at sun.nio.ch.DevPollSelectorProvider.openSelector(DevPollSelectorProvider.java:18)
at java.nio.channels.Selector.open(Selector.java:209)
对此有任何建议。
最佳答案
如果没有来自 native 包装器的更全面的错误消息,请使用 truss
在以非 root
用户身份运行时识别失败的低级系统调用(很可能是 EACCES
):
truss -l -d -f -vall -wall -o truss.out java ... TestOrAppClass
在 Java 应用程序抛出异常并终止(或被终止)后,您希望在 truss.out
中看到什么——注意 I O E x c e p t i o n
中的交错空格:
...
...
...
...
23515/1: 0.2912 some_system_call(params) Err#13 EACCES [ALL]
...
23515/1: 0.2923 write(2, 0x08044F84, 39) = 39
23515/1: j a v a . i o . I O E x c e p t i o n : P e r m i s s i o n
23515/1: d e n i e d
...
...
...
...
如果有问题的应用程序太复杂并生成太多输出(或者难以从命令行调用),则编写并编译一个小型测试类,通过调用 java.nio 重现问题。 channels.Selector.open()
直接。
如果您没有/不能编写一个简单的测试类,请记住您始终可以使用 -wall
选项记录的额外输出来关联时间(和线程/LWP)堆栈跟踪打印输出是实际系统调用产生的,它应该在不久之前失败。
在上面的示例 truss.out
输出中,23515
是进程 ID,/1
是 LWP ID(兼作“线程” "如果 JVM 使用 native 线程的标识符,它几乎肯定会在 Solaris 上使用),0.2912
是时间戳(自 java
进程/跟踪启动以来的秒数),以及 some_system_call
因 EACCES
而失败是感兴趣的调用。
您使用的是什么版本的 JDK?
关于java - 无法在 solaris 中为非 root 用户打开选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3623745/