有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法在solaris中为非root用户打开选择器

我有一个服务器应用程序,在大多数情况下运行良好,但在一台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)

有什么建议吗


共 (1) 个答案

  1. # 1 楼答案

    在本机包装器没有更全面的错误消息的情况下,使用^{}标识在以非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使用本机线程,则加倍为“线程”标识符,这几乎可以肯定在Solaris上是这样做的),0.2912是时间戳(自java进程/跟踪启动后的秒数),而some_system_call失败的EACCES是感兴趣的调用

    您使用的是哪个版本的JDK