jxse2.6在jdk8下,JxtaMulticastSocket存在的问题
@Override
public void bind(SocketAddress addr) throws SocketException {
if (isBound()) {
throw new SocketException("Already bound");
}
}
然而JxtaMulticastSocket的基类java.net.MulticastSocket的构造函数在jdk7和jdk8中的处理是不同的
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();
}
}
}
而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继承自修改后的这个类。
jxse2.6在jdk8下,JxtaMulticastSocket存在的问题的更多相关文章
- JDK8下的HashMap有什么特别之处?
一.前言 上篇认真的分析了在JDK7下的HashMap, 如果还没看过的或者忘记了的可以先去回顾下,这样可以更好的了解JDK8下的HashMap基于JDK7做了什么改动.分析JDK8下的HashMap ...
- JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
[z]http://lovestblog.cn/blog/2016/04/24/classloader-unload/ 概述 这篇文章基于最近在排查的一个问题,花了我们团队不少时间来排查这个问题,现象 ...
- JDK8下Object类源码理解
JDK8中Object类提供的方法: package java.lang; /** * Class {@code Object} is the root of the class hierarchy. ...
- jdk8下的接口和抽象类
接口 在java8中,接口可以定义变量和方法,其中变量必须为 public && static && final: 方法必须为public && (ab ...
- dubbo-admin在jdk8下不兼容
参考这里 修改pom.xml webx的依赖改为3..6版 <dependency> <groupId>com.alibaba.citrus</groupId> & ...
- JDK8下maven使用maven-javadoc-plugin插件报错
由于JDK8的doc生成机制比之前的要严谨许多,导致项目用maven打包的时候出错 解决办法: 添加-Xdoclint:none配置 完整配置如下: <plugin> <grou ...
- jdk8下面的ArrayList的扩容
一. ArrayList class ArrayList<E> extends AbstractList<E> implements List<E>, Random ...
- xp下安装jdk8
下载jdk8安装包,地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载7- ...
- 高性能场景下,HashMap的优化使用建议
1. HashMap 在JDK 7 与 JDK8 下的差别 顺便理一下HashMap.get(Object key)的几个关键步骤,作为后面讨论的基础. 1.1 获取key的HashCode并二次加工 ...
随机推荐
- Linux Kernel CMPXCHG函数分析
原文地址:http://blog.csdn.net/penngrove/article/details/44175387 最近看到Linux Kernel cmpxchg的代码,对实现很不理解.上网查 ...
- 用 eclipse ndk 编译 cocos2d-x for Android
Android 环境搭建不详述,,可以google,,, 我用的coco2dx 是 2.14 ,2.14 用 create_project.py 脚本创建工程,Python环境配置也是很简单,这里了不 ...
- delete-node-in-a-bst
https://leetcode.com/problems/delete-node-in-a-bst/ /** * Definition for a binary tree node. * struc ...
- 使用Gradle构建android应用
介绍: 由于Android Studio使用的构建工具是Gradle,所以如果Eclipse和Android Studio想互相构建彼此的应用,必须使用Gradle. Gradle 是以 Groovy ...
- 随便谈谈alphago与人机大战
3月16日历时8天的人机大战终于落下帷幕,alphago以4:1的比分击败了当年如日中天的李世石.这个结果让我这个围棋爱好者+计算机爱好者百感交集…… ——一个时代落幕了,一个新的时代开启了. 这次人 ...
- Asp.Net生命周期系列三
上文讲到了HttpRunTime主要做了三个事情,我们先回忆一下. 第一:雇佣了项目经理(HttpApplication). 第二:建立了HttpModule列表,项目经理(HttpRunTime)就 ...
- UVa (一道比较复杂的广搜) 816 Abbott’s Revenge
题意: 给出一个迷宫,在迷宫的节点处,面向某个方向只能向给定的方向转弯.给出起点和终点输出迷宫的最短路径,这里指的是刚刚离开起点的时刻,所以即使起点和终点重合路径也非空. 分析: 用三个变量来表示状态 ...
- Singleton模式写法
public class Singleton { /** * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载 */ ...
- 剑指offer—第二章算法之二分查找(旋转数组的最小值)
旋转数组的最小数字 题目:把一个数组最开始的若干元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如:数组{3,4,5,1,2}为{1,2,3,4, ...
- 为什么要用Java泛型
啥是泛型? 泛型(generic)是指参数化类型的能力.可以定义带泛型类型的类或方法,随后编译器会用具体的类型来代替它. 举个栗子 上述代码在编译期没有问题,但在运行期,将会报错.就是因为List的a ...