项目里发生很有意思的事,在利用axis2框架设计服务端时,moduleB包里包含一个classA
service包里包含一个classA,两个签字完全一样。系统运行起来后,两个classA都加载到内存中。然后调用service包里的服务impl时,某个类向上转型为classA,即发生了classcastexception!
临时的解决办法是将共有的classA放到axis2顶层的class路径中,这样就保证无论初始化module还是service仅加载一次classA。注意,同一classloader只加载相同签名的class仅一次。
现在,axis2所处容器运行了另一个web工程,该工程会请求axis2中的webservice。该场景,在两个工程的顶层class中各保存一个classA文件。启动tomcat后,axis2加载moduleB,axis2中某一classloader加载了类classA。
url请求该web的一个servlet,该servlet转而请求axis2 中的服务,此时由于服务的service包中没有classA,我们将classA保存在web工程class路径内。因此又在web的class路径中加载一次。而执行webservice的调用方法从某个类向上转型到classA却未发生classcastexception。注意此时web向axis调用走的是local协议!
现在有若干疑问:
1、为什么同样的类不同场景下同样得加载两次,却不同得发生classcastexception
2、local协议下去执行服务调用为什么会在web工程内加载服务包应有的class类,而不是去到axis2中去寻找?和local协议有关么?
3、classloader加载是按照层次代理模式加载的,那么在该jvm内,这几个classloader的关系是怎样的呢?
经过验证后,发现和local协议无关,即使http协议也会发生此,但是。当web工程和axis2分别处于不同的jvm中时(不同的tomcat实例),web工程是不会去加载classA的!(这是显而易见的),这时在web工程路径也不会去存放classA的文件。
当二者处于同一jvm内时,客户端(webclient)调用webservice的服务时,会将服务包(service.aar)加载到自己的classloader里,即他"认为"自己也是服务端,因此当发现服务包里没有classA时,就到自己的class目录中去找。二者处于不同jvm时,客户端是无论如何也不可能去加载service的实现类的,毋庸置疑。
分享到:
相关推荐
- 编译错误:如果源类型和目标类型之间没有继承或包容关系,强制类型转换会报错。例如,不能直接将`String`转换为`Integer`。 - 运行时异常:如果转换可能导致数据溢出,如`long`转`int`,且数值超出`int`范围,...
因此,当我们尝试将一个对象强制转换为另一个对象时,如果没有正确地进行类型检查,就会抛出`ClassCastException`。 解决这个问题的关键步骤如下: 1. **明确命名空间**:首先,尽可能为每个XSD文件定义一个唯一的...
1. 类型参数:类型参数是泛型的核心,它代表了一种未知的类型,用尖括号()包围,如`<T>`。这里的`T`就是一个类型参数,可以代表任意类型。在实例化泛型类或使用泛型方法时,会替换为实际的类型。 2. 泛型类:泛型...
1. 类型检查:编译器在编译时就能检测出可能的类型错误,避免了运行时的ClassCastException。 2. 代码重用:泛型类可以用于处理多种数据类型,提高了代码的复用性。 3. 自动类型转换:泛型集合会自动进行类型转换,...
- **类型转换异常(ClassCastException)**:在运行时尝试将对象强制转换为其非子类型时出现。理解类型系统和强制类型转换规则可以避免此类问题。 - **数组越界异常(ArrayIndexOutOfBoundsException)**:访问...
在没有泛型之前,开发者通常使用Object类型来存储各种数据类型的对象,这不仅需要频繁进行类型转换,而且容易引发运行时错误。引入泛型之后,可以通过在类、接口或方法声明时指定类型参数,来达到在编译阶段就确保...
泛型允许我们在类、接口和方法中使用类型参数,这样我们可以在编译时检查类型,避免了运行时类型转换的麻烦和潜在的ClassCastException风险。 在Java中,泛型的主要目的是为了实现参数化类型,这意味着我们可以创建...
1. **`java.lang.ClassCastException`**:当试图将一个对象强制转换为不兼容的引用类型时抛出该异常。例如,如果一个变量实际上是`Integer`类型的实例,而尝试将其转换为`Double`类型,则会触发此异常。 示例代码...
- **泛型**:为集合提供类型安全,避免了类型转换的麻烦和可能的ClassCastException。 5. **输入/输出(I/O)**: - **流的概念**:字符流和字节流,以及它们的读写操作。 - **文件操作**:创建、读写、删除文件,...
- **`ClassCastException`**:类型转换异常。 - **`NumberFormatException`**:数字格式异常。 - **`IllegalArgumentException`**:非法参数异常。 #### 45. 异常处理的关键字 - **`throws`**:声明可能抛出的异常...
如果我们试图将这样的数组强制转换为 `T[]` 类型,虽然可以在编译时通过,但在运行时可能会引发 `ClassCastException`。 ```java public class Generic<T> { // 泛型类的实现 } public class GenericArrayTest { ...
- 发生场景:类型不在当前类路径中时抛出。 - 解决方案:确保类型已被正确导入。 23. **UnsupportedOperationException** - 发生场景:请求的操作不支持时抛出。 - 解决方案:选择支持该操作的替代方法或类。 ...
- **ClassCastException**:类型强制转换异常,当对象无法转换为指定类型时。 - **NegativeArraySizeException**:负数组长度异常,尝试创建负数长度的数组。 - **ArrayIndexOutOfBoundsException**:数组下标越界...
这样,我们就可以创建可以处理多种类型的通用代码,同时避免了类型转换的麻烦和可能的ClassCastException。泛型通过类型擦除实现,这意味着在编译后,所有的类型参数都会被替换为它们的边界或者Object,但编译器会...
因此,当尝试将`List<String>`作为参数传递给该方法时,程序将抛出`ClassCastException`异常,因为`glom(List<Integer> ints)`方法期望的是一个`List<Integer>`类型的参数,而实际上传入的是一个`List<String>`。...
例如,一个可能的谜题是关于类型转换的,它可能会涉及到向上转型和向下转型的规则,以及何时可能出现ClassCastException。通过这样的问题,读者可以了解到Java类型的静态性和安全性,以及如何正确地进行类型转换。 ...
源码可能会展示如何处理常见的运行时异常,如空指针异常(NullPointerException)、类型转换异常(ClassCastException)等,以及如何优雅地记录并报告这些异常。 2. **自定义异常**:在某些复杂场景下,开发者可能...
- **`ClassCastException`**:类型转换异常。 - **`NumberFormatException`**:数字格式错误。 - **`IllegalArgumentException`**:非法参数异常。 #### 8. 抽象类与接口的使用场景及其互换性 - **抽象类**:...
这样可以在编译时检查类型安全,并消除运行时的类型转换错误。 **应用场景:** - **类型安全:** 使用泛型可以确保类型安全,避免在运行时出现ClassCastException。 - **代码重用:** 泛型允许编写一次代码,用于...
泛型可以限制集合中存储的数据类型,避免类型转换的麻烦和可能的ClassCastException。 9. **网络编程**:Java提供了丰富的网络编程API,如Socket和ServerSocket类,使得开发者能够编写客户端和服务器端的网络应用...