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. Home Server

    今天分享一个作品--HomeServer,一个基于云存储理念的集家庭数据存储.共享.管理及远程访问为一体的家用存储设备.通俗的讲,就是一个家庭数据银行,为家庭的数据提供专业.安全.便捷.持久.全天候的 ...

  2. HDU 3555 Bomb (数位DP-记忆化搜索模板)

    题意 求区间[1,n]内含有相邻49的数. 思路 比较简单的按位DP思路.这是第一次学习记忆化搜索式的数位DP,确实比递推形式的更好理解呐,而且也更通用~可以一般化: [数位DP模板总结] int d ...

  3. MySQL的性能调优工具:比mysqlreport更方便的tuning-primer.sh

    年初的时候收藏过一篇关于mysqlreport的报表解读,和内置的show status,和show variables相比mysqlreport输出一个可读性更好的报表:但Sundry MySQL提 ...

  4. 给产品经理讲技术,不得不懂的TCP和UDP

    TCP/IP协议,你一定经常听说吧,其中TCP(Transmission Control Protocol)称为传输控制协议,IP(Internet Protocol)称为因特网互联协议,好吧,这都是 ...

  5. 为Linux版本Oracle 11gR2配置HugePage

    HugePage是Oracle在Linux版本下一种性能优化手段.对于共享内存区域(SGA)的数据库系统,Oracle通常都推荐在操作系统层面配置上HugePage,为Oracle实例准备更大的可用共 ...

  6. python 对数函数

    from math import logfrom math import e print e #自然对数print log(e) #log函数默认是以e为底print log(100,10) #以10 ...

  7. mysql 插入汉字出现问号 解决方法

    mysql中文显示乱码或者问号是因为选用的编码不对或者编码不一致造成的,最简单的方法就是修改mysql的配置文件my.cnf.在[mydqld]和[client]段加入 default-charact ...

  8. [Everyday Mathematics]20150225

    设 $f:\bbR\to\bbR$ 二次可微, 适合 $f(0)=0$. 试证: $$\bex \exists\ \xi\in\sex{-\frac{\pi}{2},\frac{\pi}{2}},\s ...

  9. 十六进制字符串转化成字符串输出HexToStr(Delphi版、C#版)

    //注意:Delphi2010以下版本默认的字符编码是ANSI,VS2010的默认编码是UTF-8,delphi版得到的字符串须经过Utf8ToAnsi()转码才能跟C#版得到的字符串显示结果一致. ...

  10. django-grappelli 安装配置

    在python34/scripts文件夹下pip3 install django-grappelli pip安装一般会装在python34的tools或lib之类的文件夹下,一定要找到那个文件夹,gr ...