[Bug]: ClassCastException due to NoSourcePosition in final CtCatchImpl
- Dominant language
- Java
- Stars
- 2k
- Forks
- 392
- Avg merge
- 11h 24m
- Merged PRs (30d)
- 36
Description
### Describe the bug
**Bug Description**
I'm comparing two versions of the org.quartz-scheduler JAR: 2.3.2 and 2.4.0 (jars attached in zip file).
While generating the CtModel with Spoon:
- Version 2.3.2 works without issues.
- Version 2.4.0 fails with a ClassCastException.
**Error Location**
The exception is thrown at this line in PositionBuilder.java:
`DeclarationSourcePosition paramPos = (DeclarationSourcePosition) catcher.getParameter().getPosition();`
**Root Cause**
From debugging, it seems the issue arises while analyzing the class CacheDelegate in version 2.4.0.
In particular, this code:
```
try (java.io.ObjectInputStream in = new java.io.ObjectInputStream(binaryInput)) {
java.lang.Object object = in.readObject();
return object;
} catch (java.lang.Throwable throwable) {
throw throwable;
}
```
results in a CtTryWithResourceImpl where the final CtCatchImpl (the catch block) has no position metadata — it returns "unknown file", and .getPosition() does not return a DeclarationSourcePosition.
**Expected Behavior**
The model should contain valid position information for all catch blocks, or Spoon should fail gracefully without a ClassCastException.
Steps to Reproduce
- Create a CtModel from org.quartz-scheduler:quartz:2.4.0 JAR
- Attempt to analyze or process CacheDelegate
- Observe the exception in PositionBuilder
[quartzJars.zip](https://github.com/user-attachments/files/21535911/quartzJars.zip)
### Source code you are trying to analyze/transform
```Java
Jars attached above.
```
### Source code for your Spoon processing
```Java
try {
JarLauncher launcher = new JarLauncher(jarFilePath);
launcher.buildModel();
return launcher.getModel();
} catch (Exception e) {
e.printStackTrace();
return null;
}
```
### Actual output
```Java
An error occurred while creating CtModel from JAR: class spoon.reflect.cu.position.NoSourcePosition cannot be cast to class spoon.reflect.cu.position.DeclarationSourcePosition (spoon.reflect.cu.position.NoSourcePosition and spoon.reflect.cu.position.DeclarationSourcePosition are in unnamed module of loader 'app')
java.lang.ClassCastException: class spoon.reflect.cu.position.NoSourcePosition cannot be cast to class spoon.reflect.cu.position.DeclarationSourcePosition (spoon.reflect.cu.position.NoSourcePosition and spoon.reflect.cu.position.DeclarationSourcePosition are in unnamed module of loader 'app')
at spoon.support.compiler.jdt.PositionBuilder.buildPosition(PositionBuilder.java:498)
at spoon.support.compiler.jdt.ParentExiter.visitCtTry(ParentExiter.java:950)
at spoon.reflect.visitor.CtInheritanceScanner.visitCtTryWithResource(CtInheritanceScanner.java:889)
at spoon.support.compiler.jdt.ParentExiter.visitCtTryWithResource(ParentExiter.java:1005)
at spoon.support.reflect.code.CtTryWithResourceImpl.accept(CtTryWithResourceImpl.java:31)
at spoon.reflect.visitor.CtInheritanceScanner.scan(CtInheritanceScanner.java:184)
at spoon.support.compiler.jdt.ParentExiter.exitParent(ParentExiter.java:139)
at spoon.support.compiler.jdt.ContextBuilder.exit(ContextBuilder.java:129)
at spoon.support.compiler.jdt.JDTTreeBuilder.endVisit(JDTTreeBuilder.java:331)
at org.eclipse.jdt.internal.compiler.ast.Block.traverse(Block.java:157)
at org.eclipse.jdt.internal.compiler.ast.TryStatement.traverse(TryStatement.java:1258)
at org.eclipse.jdt.internal.compiler.ast.Block.traverse(Block.java:154)
at org.eclipse.jdt.internal.compiler.ast.TryStatement.traverse(TryStatement.java:1254)
at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.traverse(MethodDeclaration.java:411)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.traverse(TypeDeclaration.java:1699)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.traverse(CompilationUnitDeclaration.java:827)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.traverse(CompilationUnitDeclaration.java:788)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.traverseUnitDeclaration(JDTBasedSpoonCompiler.java:479)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.lambda$buildModel$0(JDTBasedSpoonCompiler.java:436)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.forEachCompilationUnit(JDTBasedSpoonCompiler.java:463)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildModel(JDTBasedSpoonCompiler.java:434)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnitsAndModel(JDTBasedSpoonCompiler.java:371)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildSources(JDTBasedSpoonCompiler.java:334)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:115)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:98)
at spoon.Launcher.buildModel(Launcher.java:782)
```
### Expected output
```Java
```
### Spoon Version
spoon-core:11.2.0
spoon-decompiler:0.1.0
### JVM Version
17.0.12
### What operating system are you using?
Windows
Contributor guide
Assessment
This issue has not been assessed yet.