ClassCastException when using JMockitBlockToMockito
What version of OpenRewrite are you using?
I am using
- Maven plugin 5.43.0
- rewrite-testing-frameworks 2.21.0
How are you running OpenRewrite?
I am using the Maven plugin, and my project is a multi-module project.
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.43.0</version>
<configuration>
<exportDatatables>true</exportDatatables>
<activeRecipes>
<!-- <recipe>org.openrewrite.java.testing.jmockit.JMockitAnnotatedArgumentToMockito</recipe>-->
<recipe>org.openrewrite.java.testing.jmockit.JMockitBlockToMockito</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-testing-frameworks</artifactId>
<version>2.21.0</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
<artifactId>rewrite-xml</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-migrate-java</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
</plugin>
What is the smallest, simplest way to reproduce the problem?
import mockit.Expectations;
import mockit.Mocked;
import mockit.Tested;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import jakarta.enterprise.inject.spi.InjectionPoint;
import java.lang.reflect.Member;
public class LoggerProducerTest {
@Tested
private LoggerProducer loggerProducer;
@Mocked
private InjectionPoint injectionPoint;
@Mocked
private Member member;
@Test
public void shouldProduce() {
this.mockInjectionpoint();
Assertions.assertNotNull(loggerProducer);
Assertions.assertNotNull(loggerProducer.createLogger(injectionPoint));
}
private void mockInjectionpoint() {
new Expectations() { //replaced StrictExpectations
{
LoggerProducerTest.this.injectionPoint.getMember();
this.result = member;
LoggerProducerTest.this.member.getDeclaringClass();
this.result = LoggerProducerTest.class;
}
};
}
}
@Singleton
public class LoggerProducer {
@Produces
Logger createLogger(final InjectionPoint ip) {
return LoggerFactory.getLogger(ip.getMember().getDeclaringClass());
}
}
What did you see instead?
Caused by: java.lang.ClassCastException: class org.openrewrite.java.tree.J$FieldAccess cannot be cast to class org.openrewrite.java.tree.J$Identifier (org.openrewrite.java.tree.J$FieldAccess and org.openrewrite.java.tree.J$Identifier are in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @201fd61a)
What is the full stack trace of any errors you encountered?
org.openrewrite.internal.RecipeRunException: java.lang.ClassCastException: class org.openrewrite.java.tree.J$FieldAccess cannot be cast to class org.openrewrite.java.tree.J$Identifier (org.openrewrite.java.tree.J$FieldAccess and org.openrewrite.java.tree.J$Identifier are in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @201fd61a)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:290)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.visitRightPadded (JavaVisitor.java:1367)
at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4 (JavaVisitor.java:397)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.java.JavaVisitor.visitBlock (JavaVisitor.java:396)
at org.openrewrite.java.JavaIsoVisitor.visitBlock (JavaIsoVisitor.java:88)
at org.openrewrite.java.JavaIsoVisitor.visitBlock (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$Block.acceptJava (J.java:838)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.visitClassDeclaration (JavaVisitor.java:482)
at org.openrewrite.java.JavaIsoVisitor.visitClassDeclaration (JavaIsoVisitor.java:108)
at org.openrewrite.java.JavaIsoVisitor.visitClassDeclaration (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava (J.java:1278)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.lambda$visitCompilationUnit$9 (JavaVisitor.java:495)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.java.JavaVisitor.visitCompilationUnit (JavaVisitor.java:495)
at org.openrewrite.java.JavaIsoVisitor.visitCompilationUnit (JavaIsoVisitor.java:113)
at org.openrewrite.java.JavaIsoVisitor.visitCompilationUnit (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$CompilationUnit.acceptJava (J.java:1549)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:157)
at org.openrewrite.Preconditions$Check.visit (Preconditions.java:175)
at org.openrewrite.Preconditions$Check.visit (Preconditions.java:145)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$6 (RecipeRunCycle.java:186)
at io.micrometer.core.instrument.AbstractTimer.recordCallable (AbstractTimer.java:178)
at org.openrewrite.table.RecipeRunStats.recordEdit (RecipeRunStats.java:67)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$7 (RecipeRunCycle.java:182)
at org.openrewrite.scheduling.RecipeStack.reduce (RecipeStack.java:57)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$8 (RecipeRunCycle.java:155)
at org.openrewrite.internal.InMemoryLargeSourceSet.lambda$edit$0 (InMemoryLargeSourceSet.java:66)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.internal.InMemoryLargeSourceSet.edit (InMemoryLargeSourceSet.java:65)
at org.openrewrite.scheduling.RecipeRunCycle.editSources (RecipeRunCycle.java:154)
at org.openrewrite.RecipeScheduler.runRecipeCycles (RecipeScheduler.java:87)
at org.openrewrite.RecipeScheduler.scheduleRun (RecipeScheduler.java:41)
at org.openrewrite.Recipe.run (Recipe.java:376)
at org.openrewrite.Recipe.run (Recipe.java:372)
at org.openrewrite.Recipe.run (Recipe.java:368)
at org.openrewrite.maven.AbstractRewriteBaseRunMojo.runRecipe (AbstractRewriteBaseRunMojo.java:243)
at org.openrewrite.maven.AbstractRewriteBaseRunMojo.listResults (AbstractRewriteBaseRunMojo.java:154)
at org.openrewrite.maven.AbstractRewriteRunMojo.execute (AbstractRewriteRunMojo.java:64)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:193)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:180)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:539)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:635)
at java.lang.Thread.run (Thread.java:840)
Caused by: java.lang.ClassCastException: class org.openrewrite.java.tree.J$FieldAccess cannot be cast to class org.openrewrite.java.tree.J$Identifier (org.openrewrite.java.tree.J$FieldAccess and org.openrewrite.java.tree.J$Identifier are in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @201fd61a)
at org.openrewrite.java.testing.jmockit.SetupStatementsRewriter.isSetupStatement (SetupStatementsRewriter.java:110)
at org.openrewrite.java.testing.jmockit.SetupStatementsRewriter.rewriteMethodBody (SetupStatementsRewriter.java:69)
at org.openrewrite.java.testing.jmockit.JMockitBlockToMockito$RewriteJMockitBlockVisitor.visitMethodDeclaration (JMockitBlockToMockito.java:69)
at org.openrewrite.java.testing.jmockit.JMockitBlockToMockito$RewriteJMockitBlockVisitor.visitMethodDeclaration (JMockitBlockToMockito.java:59)
at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava (J.java:3651)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.visitRightPadded (JavaVisitor.java:1367)
at org.openrewrite.java.JavaVisitor.lambda$visitBlock$4 (JavaVisitor.java:397)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.java.JavaVisitor.visitBlock (JavaVisitor.java:396)
at org.openrewrite.java.JavaIsoVisitor.visitBlock (JavaIsoVisitor.java:88)
at org.openrewrite.java.JavaIsoVisitor.visitBlock (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$Block.acceptJava (J.java:838)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.visitClassDeclaration (JavaVisitor.java:482)
at org.openrewrite.java.JavaIsoVisitor.visitClassDeclaration (JavaIsoVisitor.java:108)
at org.openrewrite.java.JavaIsoVisitor.visitClassDeclaration (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$ClassDeclaration.acceptJava (J.java:1278)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visitAndCast (TreeVisitor.java:320)
at org.openrewrite.java.JavaVisitor.lambda$visitCompilationUnit$9 (JavaVisitor.java:495)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.java.JavaVisitor.visitCompilationUnit (JavaVisitor.java:495)
at org.openrewrite.java.JavaIsoVisitor.visitCompilationUnit (JavaIsoVisitor.java:113)
at org.openrewrite.java.JavaIsoVisitor.visitCompilationUnit (JavaIsoVisitor.java:30)
at org.openrewrite.java.tree.J$CompilationUnit.acceptJava (J.java:1549)
at org.openrewrite.java.tree.J.accept (J.java:59)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:250)
at org.openrewrite.TreeVisitor.visit (TreeVisitor.java:157)
at org.openrewrite.Preconditions$Check.visit (Preconditions.java:175)
at org.openrewrite.Preconditions$Check.visit (Preconditions.java:145)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$6 (RecipeRunCycle.java:186)
at io.micrometer.core.instrument.AbstractTimer.recordCallable (AbstractTimer.java:178)
at org.openrewrite.table.RecipeRunStats.recordEdit (RecipeRunStats.java:67)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$7 (RecipeRunCycle.java:182)
at org.openrewrite.scheduling.RecipeStack.reduce (RecipeStack.java:57)
at org.openrewrite.scheduling.RecipeRunCycle.lambda$editSources$8 (RecipeRunCycle.java:155)
at org.openrewrite.internal.InMemoryLargeSourceSet.lambda$edit$0 (InMemoryLargeSourceSet.java:66)
at org.openrewrite.internal.ListUtils.map (ListUtils.java:177)
at org.openrewrite.internal.InMemoryLargeSourceSet.edit (InMemoryLargeSourceSet.java:65)
at org.openrewrite.scheduling.RecipeRunCycle.editSources (RecipeRunCycle.java:154)
at org.openrewrite.RecipeScheduler.runRecipeCycles (RecipeScheduler.java:87)
at org.openrewrite.RecipeScheduler.scheduleRun (RecipeScheduler.java:41)
at org.openrewrite.Recipe.run (Recipe.java:376)
at org.openrewrite.Recipe.run (Recipe.java:372)
at org.openrewrite.Recipe.run (Recipe.java:368)
at org.openrewrite.maven.AbstractRewriteBaseRunMojo.runRecipe (AbstractRewriteBaseRunMojo.java:243)
at org.openrewrite.maven.AbstractRewriteBaseRunMojo.listResults (AbstractRewriteBaseRunMojo.java:154)
at org.openrewrite.maven.AbstractRewriteRunMojo.execute (AbstractRewriteRunMojo.java:64)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:193)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:180)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:539)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:635)
at java.lang.Thread.run (Thread.java:840)
Are you interested in [contributing a fix to OpenRewrite]
don't know if i'm able
Thanks for using the very latest to verify; I think the problem is with the unexpected LoggerProducerTest.this.injectionPoint, but would have to check.
Yes, you're right. Can't really understand why someone writes it like that. After i fixed that in all the tests i stumbled upon the next problem. A Method inside the Expectations block:
// EXPECTATIONS
new Expectations() { //replaced StrictExpectations
{
EntityResolver.valueOf(entityManager,
TestFixtures.processingContext1());
this.result = entityResolver;
for (int count = PersistenceConfig.JDBC_BATCH_SIZE; 0 < count; count--) {
this.entityResolver();
entityManager.persist(this.any);
}
entityManager.flush();
entityManager.clear();
this.entityResolver();
entityManager.persist(this.any);
entityManager.flush();
entityManager.clear();
}
private void entityResolver() {
entityResolver.enrich(TestFixtures.tenant_Mvb_MbgmClearing());
this.result = entityResolver;
entityResolver.retrieveState(this.withAny(DialogState.nullValue()));
this.result = state;
entityResolver.retrieveEnumeration(this.withAny(Datum.EINLANGE_DAT));
this.result = enumeration;
this.times = 3;
entityResolver.retrieveEnumeration(this.withAny(Referenz.CLEARING_OBJEKT_TRAEGER_REFERENZ));
this.result = enumeration;
this.times = 2;
}
}
Here the ClassCastException happens because the Recipe expects a J.Block but gets a MethodInvocation w/ 'private void entityResolver()'. I never used JMockit, so i can't tell if that's usual procedure.
Is there any way to have a recipe run through ALL files and just continue with the next file if it fails with one?
When I've seen these types of errors, unfortunately I just delete the file temporarily and rerun. But, yes, it would be great if the framework could keep running for files if see any exception - maybe a flag if don't want to default this? @sambsnyd @timtebeek fyi
In any case, this is a bug if it is generate the exception. The code is unusual however, and with the private method internal to the block, it doesn't seem to follow the expected structure of a Jmockit Expectations block: https://www.javadoc.io/doc/org.jmockit/jmockit/latest/mockit/Expectations.html
Was able to replicate it:
` @Test
void whenMethodInsideBlock() {
rewriteRun(
java(
"""
import mockit.Expectations;
import mockit.Mocked;
import mockit.integration.junit5.JMockitExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(JMockitExtension.class)
class MyTest {
@Mocked
Object myObject;
void test() {
new Expectations() {{
}
private void test() {
myObject.wait(anyLong);
}
};
myObject.wait(1L);
}
}
""",
"""
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
Object myObject;
void test() {
new Expectations() {{
}
private void test() {
myObject.wait(anyLong);
}
};
myObject.wait(1L);
}
}
"""
)
);
}
Caused by: java.lang.ClassCastException: class org.openrewrite.java.tree.J$MethodDeclaration cannot be cast to class org.openrewrite.java.tree.J$Block (org.openrewrite.java.tree.J$MethodDeclaration and org.openrewrite.java.tree.J$Block are in unnamed module of loader 'app') at org.openrewrite.java.testing.jmockit.SetupStatementsRewriter.rewriteMethodBody(SetupStatementsRewriter.java:68) at org.openrewrite.java.testing.jmockit.JMockitBlockToMockito$RewriteJMockitBlockVisitor.visitMethodDeclaration(JMockitBlockToMockito.java:69) at org.openrewrite.java.testing.jmockit.JMockitBlockToMockito$RewriteJMockitBlockVisitor.visitMethodDeclaration(JMockitBlockToMockito.java:59) at org.openrewrite.java.tree.J$MethodDeclaration.acceptJava(J.java:3651) at org.openrewrite.java.tree.J.accept(J.java:59) at org.openrewrite.TreeVisitor.visit(TreeVisitor.java:250) ... 49 more