当密封.jar文件(整个.jar,而不是特定的包)时,哪些包实际上是密封的?是仅包含.class文件的包,还是包含父包和子包?
举一个例子,假设我有一个包含单个.class文件 com.company.city.london.class 的.jar,它只是 com.company.city < / em>密封的包裹?
JVM是否允许我在.jar之外创建和实例化类 com.company.city.building.house.class ?
JVM是否允许我在.jar之外创建和实例化 com.company.world.class 类?
答案 0 :(得分:4)
好的,在编写测试应用程序后,我得到了答案。在阅读文档后,它们并不是我所期望的。
我将以下两个类打包成一个已密封的.jar:
TestClass.java:
package com.company.testjar;
public class TestClass {
}
TestClass2.java:
package com.company.testjar2;
public class TestClass2 {
}
.jar清单看起来像这样:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.3
Created-By: 1.8.0_40-b26 (Oracle Corporation)
Implementation-Vendor: Company
Implementation-Title: Test Jar
Implementation-Version: 6.4.0.0
Sealed: true
根据文档,密封整个.jar密封.jar中的所有包装。但是,我发现这句话含糊不清。
然后我编写了一些JUnit测试用例来查看我可以定义的其他类,而不会导致密封的.jar出现问题。
对于我的单元测试,我还添加了以下三个测试类。请注意,这些未在.jar中定义,但使用相同的包结构 - 这对于测试很重要。
Bogus.java:
package com.company.testjar;
public class Bogus {
}
SubBogus.java
package com.company.testjar.subpackage;
public class SubBogus {
}
ParentBogus.java:
package com.company;
public class ParentBogus {
}
JUnit测试:
package com.company.test;
import static org.junit.Assert.*;
import org.junit.Test;
import com.company.ParentBogus;
import com.company.testjar.Bogus;
import com.company.testjar.TestClass;
import com.company.testjar.subpackage.SubBogus;
import com.company.testjar2.TestClass2;
/**
* A set of tests for testing the effects of .jar sealing.
*
* These tests rely on a built .jar named TestJar.jar which is built from the command line.
*
* Only one of these tests can be run at a time because one a package has been loaded, it cannot
* be unloaded again. Because of this, each test must be run separately.
*/
public class TestPackages {
@Test
public void SealedFail1() {
// Instantiate instance of TestClass from sealed .jar.
TestClass t = new TestClass();
// Following should blow up because package com.company.testjar has already
// been loaded by instantiating TestClass above.
try {
new Bogus();
// Should not get here. Throw if we do.
assertFalse(true);
} catch (SecurityException ex) {
// Expected.
}
}
@Test
public void SealedFail2() {
Bogus b = new Bogus();
// Following should blow up because package com.company.testjar has already
// been loaded by instantiating Bogus above.
try {
new TestClass();
// Should not get here. Throw if we do.
assertFalse(true);
} catch (SecurityException ex) {
// Expected.
}
}
/**
* Test to see if instantiating object from package in a sealed .jar will effectively
* load and seal all packages in that .jar.
*/
@Test
public void SealedFail3() {
// Instantiate object from com.company.testjar2 package. This package will now be
// loaded and sealed.
TestClass2 t2 = new TestClass2();
// Instantiate object from com.company.testjar package NOT from sealed .jar.
// This should work because this package has not been sealed yet!
Bogus b = new Bogus();
// This should now throw because the com.company.testjar package has already
// been loaded by instantiating Bogus above, and the TestClass is from that
// same package from the sealed .jar.
try {
new TestClass();
// Should not get here. Throw if we do.
assertFalse(true);
} catch (SecurityException ex) {
// Expected.
}
}
/**
* Test to see if instantiating an object from a sealed .jar prevents us from then
* instantiating an instance of an object from a sub-package NOT defined in the
* same .jar.
*/
@Test
public void SubPackage() {
// Instantiate instance of TestClass from sealed .jar. Loads and seals the
// com.company.testjar package.
TestClass t = new TestClass();
// Now attempt to instantiate an instance of an object from a sub-package of
// com.company.testjar which is not defined in the same .jar.
new SubBogus();
}
/**
* Test to see if instantiating an object from a sealed .jar prevents us from then
* instantiating an instance of an object from a parent package NOT defined in the
* same .jar.
*/
@Test
public void ParentPackage() {
// Instantiate instance of TestClass from sealed .jar. Loads and seals the
// com.company.testjar package.
TestClass t = new TestClass();
// Now attempt to instantiate an instance of an object from the parent-package of
// com.company.testjar which is not defined in the same .jar.
new ParentBogus();
}
}
各个测试应该独立运行,因为一旦加载了一个包,我就不会再次卸载它并且会影响测试的结果。如果您一次运行所有测试,则会出现故障,因为第一次测试会加载包并保持加载状态。
单独运行时,所有测试都会通过。
从这些测试中,我们可以确定以下内容: