-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug in Quarkus bytecode generation #31153
Comments
You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip
|
/cc @Sanne (core), @aloubyansky (core), @geoand (core), @gsmet (core), @radcortez (core), @stuartwdouglas (core) |
@gastaldi are you looking into this? |
@geoand I am, but I am having a hard time trying to reproduce it in a test case. Wanna take a look? |
I can have a look tomorrow |
I've narrowed down to this snippet which adds the offending line. Still investigating quarkus/core/deployment/src/main/java/io/quarkus/deployment/recording/BytecodeRecorderImpl.java Lines 1253 to 1283 in d897eef
|
@rdehuyss the problem is that the BytecodeGenerator is failing to construct the
public void schedule(BeanContainer container, String id, String cron, String interval, String zoneId, String className, String methodName, List<JobParameter> parameterList) {
JobScheduler scheduler = container.instance(JobScheduler.class);
String jobId = getId(id);
String optionalCronExpression = getCronExpression(cron);
String optionalInterval = getInterval(interval);
if (StringUtils.isNullOrEmpty(cron) && StringUtils.isNullOrEmpty(optionalInterval))
throw new IllegalArgumentException("Either cron or interval attribute is required.");
if (StringUtils.isNotNullOrEmpty(cron) && StringUtils.isNotNullOrEmpty(optionalInterval))
throw new IllegalArgumentException("Both cron and interval attribute provided. Only one is allowed.");
if (Recurring.RECURRING_JOB_DISABLED.equals(optionalCronExpression) || Recurring.RECURRING_JOB_DISABLED.equals(optionalInterval)) {
if (isNullOrEmpty(jobId)) {
LOGGER.warn("You are trying to disable a recurring job using placeholders but did not define an id.");
} else {
scheduler.delete(jobId);
}
} else {
JobDetails jobDetails = new JobDetails(className, null, methodName, parameterList);
jobDetails.setCacheable(true);
if (isNotNullOrEmpty(optionalCronExpression)) {
scheduler.scheduleRecurrently(id, jobDetails, CronExpression.create(optionalCronExpression), getZoneId(zoneId));
} else {
scheduler.scheduleRecurrently(id, jobDetails, new Interval(optionalInterval), getZoneId(zoneId));
}
}
} |
I managed to reproduce this in a test case: gastaldi@dab48a0 In case you're interested @geoand ☝🏻 |
I just wanted to say - wauw! Thank you all and especially @gastaldi for taking this so serious and providing a workaround so fast! |
…sing workaround provided by @gastaldi
@gastaldi excellent investigation! Looking at your test, I immediately see that the object is not really deserialiable in bytecode, because:
If the
More information can be found here. |
@rdehuyss when you have time, can you try one of the above proposals and see if the the issue goes away? |
Hi @geoand , there is a substitution registered for the class in question, see https://github.com/jobrunr/jobrunr/blob/bugfix/689/framework-support/jobrunr-quarkus-extension/deployment/src/main/java/org/jobrunr/quarkus/extension/deployment/RecurringJobsFinder.java#L51-L66 |
Oh sorry, I had not seen that. |
I took a [not so] quick look and eventually found what I believe is the crux of the issue. The bytecode recording mechanism attempts to match constructor parameters to properties and skip setting properties that were initialized by the constructor. The assumption is that if the constructor has a parameter with the same name as the property, the property is set by the constructor. Otherwise it needs to be set using a setter. The issue is that this matching was not implemented for the "explicitly registered non-default constructor" mechanism, which is used here. That's pretty easy to fix: https://github.com/Ladicek/quarkus/commits/bytecode_recorder_collection |
Fix the test case for quarkusio#31153
Fix the test case for quarkusio#31153
Fix the test case for quarkusio#31153
Fix the test case for quarkusio#31153
Fix the test case for quarkusio#31153
Describe the bug
Hi all, I'm Ronald, the creator of JobRunr, a Quartz replacement.
JobRunr also integrates with Quarkus and to do so, I created a custom Quarkus Extension. I'm currently struggling with this extension.
In this extension, I've written a RecurringJobsFinder that searches for all methods annotated with @Recurring and schedules them using a recorder so that the bytecode is recorded.
This is all tested by means of integration tests here:
https://github.com/jobrunr/jobrunr/blob/bugfix/689/framework-support/jobrunr-quarkus-extension/tests/src/main/java/org/jobrunr/quarkus/it/TestService.java#L20-L25
All of this mostly works fine but for one of these recurring jobs, I receive the following exception:
The bytecode generated by the
Recorder
is as follows (thanks @gastaldi!):We noticed that
var8
is added twice for some reason. As((Collection)var10.getJobParameters())
returns an unmodifiable list, the second add fails. But, I do not understand the reason why the parameter is added twice in the first place as that will also cause problems later on in JobRunr (2 parameters where the method only expects 1).Expected behavior
The parameter should only be added once.
Actual behavior
The parameter is added twice.
How to Reproduce?
bugfix/689
./framework-support/jobrunr-quarkus-extension/tests/src/test/java/org/jobrunr/quarkus/it/JobRunrFunctionalityTest.java
Output of
uname -a
orver
Darwin Ronalds-MacBook-Pro.local 21.6.0 Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000 arm64
Output of
java -version
openjdk version "17.0.1" 2021-10-19 OpenJDK Runtime Environment (build 17.0.1+12-39) OpenJDK 64-Bit Server VM (build 17.0.1+12-39, mixed mode, sharing)
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.15.3
Build tool (ie. output of
mvnw --version
orgradlew --version
)Gradle 7.5.1
Additional information
See also the analysis of @gastaldi at https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/JobRunr.20Quarkus.20extension.20-.20UnsupportedOperationException
The text was updated successfully, but these errors were encountered: