INRIA / INRIA/spoon

[Bug]: ClassCastException due to NoSourcePosition in final CtCatchImpl

Open
#6,385 0 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.