sealing violation

[b][size=small]一般以下两种情况会触发sealing安全异常
1)当被密封(seal)的package已经被加载,此时再试图去加载其他jar中的同名package,就会触发sealing violation异常
2)当没有被密封的package已经被加载,此时再去加载其他jar中同名且被密封的package,也会触发sealing violation异常
[/size][/b]

假设某次发布的jar(v1.jar)中包含NumerUtils和StringUtils这俩工具类
package com.seal.util;

import java.text.DecimalFormat;

public class NumberUtils {
public static String format(double d) {
return new DecimalFormat("#,##0.00").format(d);
}
}
package com.seal.util;

public class StringUtils {
public static String format(String str) {
return "Format:" + str;
}
}

/**
javac -d v1 NumberUtils.java StringUtils.java
编译源文件至v1目录,多个源文件用空格分隔

jar -cvfm v1.jar mf.mf -C v1 .
将v1目录下的所有子目录和文件都压缩成jar文件,
jar文件的MANIFEST.MF采用自己定义的mf.mf

mf.mf内容如下:
Manifest-Version: 1.0
Created-By: 1.6.0_33 (Sun Microsystems Inc.)

Name: com/seal/util/
Sealed: true
*/


一段时间后,需要对该v1.jar进行升级,加入一个新的工具类DateUtils.java
同样的,采用上面的步骤进行编译、打包得到v2.jar
package com.seal.util;

import java.util.Date;
import java.text.SimpleDateFormat;

public class DateUtils {
public static String format(Date date) {
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
}


import com.seal.util.NumberUtils;
import com.seal.util.StringUtils;
import com.seal.util.DateUtils;
public class MainTest {
public static void main(String[] args) {
System.out.println(NumberUtils.format(1.2));
System.out.println(StringUtils.format("str"));
System.out.println(DateUtils.format(new java.util.Date()));
}
}
/**
javac -cp v1.jar;v2.jar MainTest.java
编译MainTest源文件

java -cp .;v1.jar;v2.jar MainTest
运行MainTest 此时classpath同时包含v1.jar跟v2.jar
因为jvm加载package的顺序是根据jar在classpath出现的先后顺便来进行的,所以此时先从v1.jar加载了seal的com.seal.util,但是DateUtils需要从v2.jar获得,所以就会触发sealing violation安全异常

Exception in thread "main" java.lang.SecurityException: sealing violation: packa
ge com.seal.util is sealed
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at MainTest.main(MainTest.java:10)

相反的,如果一开始加载的v1的package不是seal的,要从v2加载seal的同名package就会触发另一个sealing violation安全异常
Exception in thread "main" java.lang.SecurityException: sealing violation: can't
seal package com.seal.util: already loaded
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at MainTest.main(MainTest.java:10)
*/
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值