tomcat RMI 停不掉

项目采用jfinal框架,做了一个RMI的服务,对其它程序提供服务。实现上,写了一个RmiPlugin

java
package com.wisdombud.cloudtalk.plugin;

import java.io.IOException;
import java.rmi.Naming;
import java.rmi.NoSuchObjectException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import javax.rmi.PortableRemoteObject;

import com.jfinal.kit.LogKit;
import com.jfinal.plugin.IPlugin;
import com.wisdombud.cloudtalk.rmi.RecommendService;
import com.wisdombud.cloudtalk.rmi.RecommendServiceImpl;

public class RmiPlugin implements IPlugin {

private Registry reg;

@Override
public boolean start() {
    RecommendService service;
    try {
        service = new RecommendServiceImpl();
        reg = LocateRegistry.createRegistry(6600);
        Naming.rebind("rmi://127.0.0.1:6600/RecommendService", service);
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

@Override
public boolean stop() {
    try {
        UnicastRemoteObject.unexportObject(reg, true);
    } catch (NoSuchObjectException e) {
        LogKit.error("UnicastRemoteObject unexportObject failed", e);
        try {
            PortableRemoteObject.unexportObject(reg);
            return true;
        } catch (NoSuchObjectException e1) {
            LogKit.error("PortableRemoteObject unexportObject failed", e1);
        }
        return false;
    }
    return true;
}

}


> 程序启动没有问题,运行也可以,但tomcat shutdown的时候停不掉。
> jstack 导出线程栈后,发现有一个“RMI reaper ”的非守护线程。google,发现了RMI的使用问题
1. Naming 和 Registry 的区别
2. 停掉的时候没有取消绑定服务

stackOverFlow的答案如下:

>Sure enough, I had a bug in the code that caused one of my (many) UnicastRemoteObjects to not unexport itself when the calling application was done utilizing it. So the answer is:
> **Unexporting all UnicastRemoteObjects within a running JVM is sufficient to close all RMI non-daemon threads.**

所以代码应该如下
```java```
package com.wisdombud.cloudtalk.plugin;

import java.io.IOException;
import java.rmi.NoSuchObjectException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import javax.rmi.PortableRemoteObject;

import com.jfinal.kit.LogKit;
import com.jfinal.plugin.IPlugin;
import com.wisdombud.cloudtalk.rmi.RecommendService;
import com.wisdombud.cloudtalk.rmi.RecommendServiceImpl;

public class RmiPlugin implements IPlugin {

    private Registry reg;

    @Override
    public boolean start() {
        RecommendService service;
        try {
            service = new RecommendServiceImpl();
            reg = LocateRegistry.createRegistry(6600);
            reg.rebind("rmi://127.0.0.1:6600/RecommendService", service);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public boolean stop() {
        try {
            String[] lNames = reg.list();
            for (String lName : lNames) {
                Remote lRemoteObj = reg.lookup(lName);
                reg.unbind(lName);
                UnicastRemoteObject.unexportObject(lRemoteObj, true);
            }
            UnicastRemoteObject.unexportObject(reg, true);

        } catch (RemoteException | NotBoundException e) {
            LogKit.error("UnicastRemoteObject unexportObject failed", e);
            try {
                PortableRemoteObject.unexportObject(reg);
                return true;
            } catch (NoSuchObjectException e1) {
                LogKit.error("PortableRemoteObject unexportObject failed", e1);
            }
            return false;
        }
        return true;
    }

}


posted @ 2017-01-07 10:40  每日懂一点  阅读(1531)  评论(0编辑  收藏  举报