zoukankan      html  css  js  c++  java
  • 又见net.jxta.exception.ServiceNotFoundException

    与以前帖子中提到的原因(JXSE的bug)不一样,不过这个也蛮奇怪的。

    异常堆栈提示并不明显。在一堆日志中发现这么几行:

    Exception in startApp() : jxmessenger.jxse.presenceservice.PresenceServiceImpl@1a33efb

    java.lang.NullPointerException

    Line 202 net.jxta.socket.JxtaMulticastSocket.joinGroup()

    ....

    Service failed to start (-1) : jxmessenger.jxse.presenceservice.PresenceServiceImpl@1a33efb

     在确认了数遍后,确定startApp函数并没有问题?

    在与之前正常的代码比较之后,发现在startApp()函数开始的地方少了

    discovery = group.getDiscoveryService();
    if(discovery == null) {
        
    return Module.START_AGAIN_PROGRESS;
    }

     因为后来该Service的实现不再需要发现服务,故上面这段代码被删除了,结果就出现了上面的问题。

    奇怪的是,该Service并不需要发现服务。继续跟踪源代码...

    --------------------------------------------------------------------------------------------------------

     找到原因了,是MulticastSocket引起的问题,请看修改前有问题的startApp代码

    @Override
    public int startApp(String[] args) {
        
    // ...
        try {
            mcastSocket 
    = new JxtaMulticastSocket(group, createSocketAdvertisement());
        } 
    catch(IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        
        
    // ...

        
    return Module.START_OK;
    }

     在JxtaMulticastSocket.java的代码中,我们看到

        /**
         * joins MutlicastSocket to specified pipe within the context of group
         *
         * 
    @param group  group context
         * 
    @param pipeAd PipeAdvertisement
         * 
    @throws IOException if an io error occurs
         
    */
        
    public void joinGroup(PeerGroup group, PipeAdvertisement pipeAd) throws IOException {

            
    if (pipeAd.getType() != null && !pipeAd.getType().equals(PipeService.PropagateType)) {
                
    throw new IOException("Only propagate pipe advertisements are supported");
            }
            
    if (pipeAd.getPipeID() == null) {
                
    throw new IOException("Invalid pipe advertisement");
            }

            
    this.group = group;
            
    this.pipeAdv = pipeAd;
            pipeSvc = group.getPipeService();
            
    this.in = pipeSvc.createInputPipe(pipeAd, this);
            
    this.credentialDoc = getCredDoc(group);
            outputPipe 
    = pipeSvc.createOutputPipe(pipeAd, 1);
            String id 
    = group.getPeerID().toString();

            srcElement 
    = new StringMessageElement(SRCIDTAG, id, null);

            Logging.logCheckedInfo(LOG, 
    "Starting JxtaMulticastSocket on pipe id :", pipeAdv.getID());

            String pipeStr 
    = pipeAd.getPipeID().getUniqueValue().toString();

            localAddress 
    = InetAddress.getByAddress(pipeStr, fauxip);
            socketAddress 
    = new InetSocketAddress(localAddress, 0);
            bound 
    = true;
        }

     黄色底色两行需要管道服务,而通过调试,正是这个管道服务对象为null。可见MulticastSocket是依赖于管道服务的。这就提醒我们,在自定义服务中,如果使用

    MulticastSocket,则必须保证管道服务优先加载。方法是在startApp方法中加入

    PipeService pipeService = group.getPipeService();
    if(pipeService == null) {
        
    return Module.START_AGAIN_PROGRESS;
    }
    // ....

     而之前我们在现象描述时说加入类似的发现服务是也能使得程序正常,应该是一种巧合,刚好此时管道服务也被加载了。

     好了,原因及解决方法就到这里。

    以后在涉及这种隐性依赖的时候需要注意处理,如果在自定义服务中使用高级的管道服务(JxtaBiDiPipe或JxtaSocket)可能也会遇到这种情况。



  • 相关阅读:
    Asp.net MVC 利用 Nopi 导出 Excel
    React 中 调用 Asp.net WebApi
    Node.js mysql 连接池使用事务自动回收连接
    __far和__near的小问题
    注册博客园了,以后在这里写写随笔。
    Electron客户端开发入门必备的知识点
    公司组织构架的三大类型
    经济学中的人性抉择(下)
    经济学中的人性抉择(上)
    模拟音乐播放器播放条样式
  • 原文地址:https://www.cnblogs.com/cuizhf/p/2181461.html
Copyright © 2011-2022 走看看