JxtaMulticastSocket覆写了java.net.MulticastSocket的bind方法:

@Override
public void bind(SocketAddress addr) throws SocketException {
if (isBound()) {
throw new SocketException("Already bound");
}
}
 
要求在JxtaMulticastSocket的构造函数中会调用bind方法,确保构造函数调用时socket没有被绑定,否则抛出SocketException异常
然而JxtaMulticastSocket的基类java.net.MulticastSocket的构造函数在jdk7和jdk8中的处理是不同的
 
jdk7:

    public MulticastSocket(SocketAddress bindaddr) throws IOException {
super((SocketAddress) null); // Enable SO_REUSEADDR before binding
setReuseAddress(true); if (bindaddr != null) {
bind(bindaddr);
}
}

jdk8:

    public MulticastSocket(SocketAddress bindaddr) throws IOException {
super((SocketAddress) null); // Enable SO_REUSEADDR before binding
setReuseAddress(true); if (bindaddr != null) {
try {
bind(bindaddr);
} finally {
if (!isBound())
close();
}
}
}
可见在jdk8中,如果未绑定,会额外调用close()方法,就是这个close()方法导致抛出了异常
其实在这里不能调用close()方法,从代码上看JxtaMulticastSocket在实现的时候要求此时不能绑定(见其覆写的bind方法)
而close方法也被JxtaMulticastSocket覆写了

/**
* Closes this MutlicastSocket.
*/
@Override
public synchronized void close() {
if (closed) {
return;
}
bound = false;
closed = true;
in.close();
outputPipe.close();
in = null;
}

此时in尚未初始化,故in.close()会导致java.lang.NullPointerException异常

————————————

1 简单的话,可以修改JxtaMulticastSocket的构造函数,使其不再调用父类的构造函数以避免close()问题(父类构造函数中的相关代码要在子类中重新实现一遍)。
2 或者不修改JxtaMulticastSocket的源码,我们干脆自己实现一个子类,提供自己的构造函数初始化代码。

3 较好的方式那就要全面考虑JxtaMulticastSocket的实现了,那就比较复杂了

————————————————————————

。。。

1和2现在看起来不大现实,因为父类java.net.MulticastSocket最终都调用了如下构造方法:

    /**
* Create a MulticastSocket bound to the specified socket address.
* <p>
* Or, if the address is {@code null}, create an unbound socket.
*
* <p>If there is a security manager,
* its {@code checkListen} method is first called
* with the SocketAddress port as its argument to ensure the operation is allowed.
* This could result in a SecurityException.
* <p>
* When the socket is created the
* {@link DatagramSocket#setReuseAddress(boolean)} method is
* called to enable the SO_REUSEADDR socket option.
*
* @param bindaddr Socket address to bind to, or {@code null} for
* an unbound socket.
* @exception IOException if an I/O exception occurs
* while creating the MulticastSocket
* @exception SecurityException if a security manager exists and its
* {@code checkListen} method doesn't allow the operation.
* @see SecurityManager#checkListen
* @see java.net.DatagramSocket#setReuseAddress(boolean)
*
* @since 1.4
*/
public MulticastSocket(SocketAddress bindaddr) throws IOException {
super((SocketAddress) null); // Enable SO_REUSEADDR before binding
setReuseAddress(true); if (bindaddr != null) {
try {
bind(bindaddr);
} finally {
if (!isBound())
close();
}
}
}

这意味着子类无论直接还是间接,最终都要调用到这个方法,故close()难以避免的啊!

那就只有修改JxtaMulticastSocket覆写的close()方法了,原close()方法:

    /**
* Closes this MutlicastSocket.
*/
@Override
public synchronized void close() {
if (closed) {
return;
}
bound = false;
closed = true;
in.close();
outputPipe.close();
in = null;
}

修改后:如果尚未绑定的话,close()不执行任何操作

    /**
* Closes this MutlicastSocket.
*/
@Override
public synchronized void close() {
// modified by cuizhf, 20131126
// @see http://www.cnblogs.com/cuizhf/admin/EditPosts.aspx?postid=3443599
if(!bound) {
return;
}
if (closed) {
return;
}
bound = false;
closed = true;
in.close();
outputPipe.close();
in = null;
}

或者这样写:

    /**
* Closes this MutlicastSocket.
*/
@Override
public synchronized void close() {
// modified by cuizhf, 20131126
// @see http://www.cnblogs.com/cuizhf/admin/EditPosts.aspx?postid=3443599
if (!bound || closed) {
return;
}
bound = false;
closed = true;
in.close();
outputPipe.close();
in = null;
}

虽然不是很优雅,至少应该能解决眼前的问题。(实话说Jxse的代码确实算不上优雅)

————————————————————————————————————————————————————————

另外一种修改方式就是将java.net.MulticastSocket单独从JDK中提出到在自己的工程中,然后按自己的需要修改(在构造函数中去掉close()的调用),最后使JxtaMulticastSocket继承自修改后的这个类。

 
 
 
 —————————————————————————————————————————————————————————
好吧,从今天开始,secondegg项目的开发全面转向JDK8(JavaFX8)。

jxse2.6在jdk8下,JxtaMulticastSocket存在的问题的更多相关文章

  1. JDK8下的HashMap有什么特别之处?

    一.前言 上篇认真的分析了在JDK7下的HashMap, 如果还没看过的或者忘记了的可以先去回顾下,这样可以更好的了解JDK8下的HashMap基于JDK7做了什么改动.分析JDK8下的HashMap ...

  2. JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]

    [z]http://lovestblog.cn/blog/2016/04/24/classloader-unload/ 概述 这篇文章基于最近在排查的一个问题,花了我们团队不少时间来排查这个问题,现象 ...

  3. JDK8下Object类源码理解

    JDK8中Object类提供的方法: package java.lang; /** * Class {@code Object} is the root of the class hierarchy. ...

  4. jdk8下的接口和抽象类

    接口 在java8中,接口可以定义变量和方法,其中变量必须为 public && static && final: 方法必须为public && (ab ...

  5. dubbo-admin在jdk8下不兼容

    参考这里 修改pom.xml webx的依赖改为3..6版 <dependency> <groupId>com.alibaba.citrus</groupId> & ...

  6. JDK8下maven使用maven-javadoc-plugin插件报错

    由于JDK8的doc生成机制比之前的要严谨许多,导致项目用maven打包的时候出错 解决办法: 添加-Xdoclint:none配置 完整配置如下:   <plugin> <grou ...

  7. jdk8下面的ArrayList的扩容

    一. ArrayList class ArrayList<E> extends AbstractList<E> implements List<E>, Random ...

  8. xp下安装jdk8

    下载jdk8安装包,地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载7- ...

  9. 高性能场景下,HashMap的优化使用建议

    1. HashMap 在JDK 7 与 JDK8 下的差别 顺便理一下HashMap.get(Object key)的几个关键步骤,作为后面讨论的基础. 1.1 获取key的HashCode并二次加工 ...

随机推荐

  1. hibernate自动生成映射文件

    映射文件是O/R Mapping的关键,相当于控制中心.当数据库表较多时,手动配置该映射文件非常耗时.为了快速开发程序,使开发人员的注意力集中到业务逻辑上来,Hibernate官方提供的MiddleG ...

  2. android layoutparams应用指南(转)

    LayoutParams相当于一个Layout的信息包,它封装了Layout的位置.高.宽等信息.假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉L ...

  3. python练习程序(c100经典例18)

    题目: 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字.例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制. def foo(a,n): su ...

  4. 理解matplotlib绘图

    matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包.Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件.它能让使用者很轻松地将数据图形化 ...

  5. 标准IO库函数复习

    打开文件,打开文件一定要成对写,养成好习惯很重要.比如 fopen()fclose<ol> <li>fopen()</li> <pre lang=" ...

  6. phonegap 百度云推

    1 创建新工程 -----获取api key 和secret key 2,推送设置 3,新建安卓项目,并把应用包名 和 推送中设置的包名设置一致 4,下载百度云客户端sdk 5,解压,并添加libs文 ...

  7. html中的特殊符号

    html中的特殊符号 符号 说明 编码   符号 说明 编码   符号 说明 编码 " 双引号 " × 乘号 × ← 向左箭头 ← & AND符号 & ÷ 除号 ÷ ...

  8. PubSub的一种实现

    今天在浏览JavaScript事件时,复习了下Dean Edward大神的addEvent.突然觉得可以基于他的思路实现一个结构更好的PubSub. 思路也很简单,就是要维护一个类似如下的一个仓库结构 ...

  9. Asp.net 身份验证方式?

    [Forms 身份验证] 通过其可将没有通过身份验证的请求重定向到使用 HTTP 客户端重定向的 HTML 窗体的系统.用户提供凭据并提交该窗体.如果应用程序验证该请求,系统就会发出包含凭据或密钥的 ...

  10. [Everyday Mathematics]20150302

    $$\bex |p|<\frac{1}{2}\ra \int_0^\infty \sex{\frac{x^p-x^{-p}}{1-x}}^2\rd x =2(1-2p\pi \cot 2p\pi ...