Closed famod closed 3 months ago
/cc @DavideD (hibernate-reactive), @FroMage (panache), @gavinking (hibernate-reactive), @geoand (kotlin), @loicmathieu (panache)
/cc also @yrodiere
Btw, unsurprisingly git bisect
identified this commit: https://github.com/quarkusio/quarkus/pull/40102/commits/78952bcd4193042c2f569c3cf3b13d95be618b9a
@FroMage I think we'll need you to figure this out, as this seems caused by your patches to jpamodelgen...
@FroMage I think we'll need you to figure this out, as this seems caused by your patches to jpamodelgen...
Also I'm discovering just now these patches, and find them highly questionable... why do we have references to Panache in Hibernate ORM itself? Why isn't there rather some extension mechanism (ServiceLoader
or other) that Panache implements?
It's not a dependency from ORM to panache, but a way for it to detect that it's running in Quarkus with Panache. Apparently Quarkus Spring Data uses ORM/Panache, so that's where it's detected.
This should have no effect on metamodel generation, though. It should run, and just not assume you have either one of those (ORM or HR).
The only thing this detection changes is how your metamodel type-safe queries turn into static methods or bean methods. It's a bug if it stops running, I suppose.
So, my patch is definitely not meant to turn off metamodel generation. But also I've no idea why it can find a io.quarkus.hibernate.reactive.panache
package from that classpath you showed.
In any case, I think we need two things:
Also, I'm pretty sure we have tests in our CI that make sure the jpametamodel is generated for Panache, no?
a quick fix/workaround (I wonder if the call you make to get the package always returns something even if the package is not around?).
No, this is tested in jpamodelgen tests
Another option would be that somehow you have the package in the build (deployment) classpath
That'd be weird, no?
as Yoann said, a proper way to push this information to JPA Modelgen. Relying on packages is brittle. If we have to change the packages at some point, we will need an ORM release. It can come in a second time but I don't think we will want to keep a Quarkus specific path in Hibernate ORM. It needs to be made more generic
This is how jpamodelgen works. It does the same to detect @Inject
and transactions, and Jakarta Data. I don't think it's brittle, we will never change these packages, they're part of our API.
as Yoann said, a proper way to push this information to JPA Modelgen. Relying on packages is brittle. If we have to change the packages at some point, we will need an ORM release. It can come in a second time but I don't think we will want to keep a Quarkus specific path in Hibernate ORM. It needs to be made more generic
This is how jpamodelgen works. It does the same to detect
@Inject
and transactions, and Jakarta Data. I don't think it's brittle, we will never change these packages, they're part of our API.
EDIT: created https://hibernate.atlassian.net/browse/HHH-18159
@famod
Could you get the full dependency tree with ./mvnw quarkus:dependency-tree
and see if there's anything suspicious?
Also, it will sound like a stupid question, but could you make sure you don't have the package in your app?
Also, can we have a reproducer? Because detection of Panache in the processor should have zero effect on generation of the metamodel.
Do you know if it's generated when compiled by Maven?
If you run with -X
, perhaps you see an exception during annotation processing?
@FroMage
So, my patch is definitely not meant to turn off metamodel generation.
Thanks for confirming, I had a feeling that this warning might not hint at all at the actual root cause of entirely missing code generation.
Maybe it's related to the eclipse compiler (ECJ) which we are using via maven-compiler-plugin
.
Will try to get more annotation processor output.
I've had issues where jpamodelgen processor errors where just hidden from me, very frustratingly.
Maybe it's related to the eclipse compiler (ECJ) which we are using via
maven-compiler-plugin
.
Confirmed, switching to the default compiler fixes both the warning and the actual metamodel generation. Meaning something has changed in jpamodelgen in 6.5 that breaks it for ECJ.
This also means that a much smaller proportion of users is affected because (I think) the vast majority is using the default compiler.
Btw, I'm not fond of moving to the default compiler permanently because it's ~50% slower in my case.
If you manage to get the processor to log things, you should see those logs:
context.logMessage( Diagnostic.Kind.OTHER, "Starting new round" );
try {
processClasses( roundEnvironment );
createMetaModelClasses();
}
catch (Exception e) {
final StringWriter stack = new StringWriter();
e.printStackTrace( new PrintWriter(stack) );
final Throwable cause = e.getCause();
final String message =
cause != null && cause != e
? e.getMessage() + " caused by " + cause.getMessage()
: e.getMessage();
context.logMessage( Diagnostic.Kind.ERROR, "Error running Hibernate processor: " + message );
context.logMessage( Diagnostic.Kind.ERROR, stack.toString() );
}
Ah, I obviously missed the fact that the metamodel classes are generated, but -X
reveals e.g.:
1. ERROR in /home/famod/work/someproj/register/dev3/core/target/generated-sources/annotations/someproj/register/core/persistence/entity/_ApplicationLock.java (at line 4)
import jakarta.data.metamodel.SortableAttribute;
^^^^^^^^^^^^
The import jakarta.data cannot be resolved
Also affected: jakarta.data.metamodel.StaticMetamodel
(which should be jakarta.persistence.metamodel.StaticMetamodel
instead)
So it seems that somehow with ECJ that experimental Jakarta Data support is active? https://github.com/hibernate/hibernate-orm/blob/6.5/migration-guide.adoc#jakarta-data
Yeah, ok, so what's most likely is that ECG will pretend that every package exists, so the entire jpamodelgen strategy for detecting things is broken in ECG. This is used for many other dependencies.
So, all those will be broken, I suppose:
final PackageElement jakartaInjectPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.inject" );
final PackageElement jakartaAnnotationPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.annotation" );
final PackageElement jakartaContextPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.enterprise.context" );
final PackageElement jakartaTransactionsPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.transactions" );
final PackageElement jakartaDataPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.data" );
final PackageElement quarkusOrmPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm" );
PackageElement quarkusOrmPanachePackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm.panache" );
PackageElement quarkusReactivePanachePackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.reactive.panache" );
I can confirm via debugging that all those PackageElement
s are non-null with ECJ. Bummer!
Thanks for the feedback @famod .
I created https://hibernate.atlassian.net/browse/HHH-18160 to address the problem upstream. That probably won't get solved in time for the Quarkus 3.11 platform release, though.
One workaround is to override the version of Jpamodelgen to 6.4.8.Final. It's not guaranteed to work, but there's a decent chance it does.
Thanks @yrodiere for backporting the fix already to Hibernate 6.5!
After that fix I started to have one class and one interface being generated in my projects on Eclipse. :(
and the _BaseEntity one is with an error due a missing jakarta.data.metamodel
package on the classpath
import jakarta.annotation.Generated;
import jakarta.persistence.metamodel.MappedSuperclassType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.StaticMetamodel;
import java.time.ZonedDateTime;
@StaticMetamodel(BaseEntity.class)
@Generated("org.hibernate.processor.HibernateProcessor")
public abstract class BaseEntity_ {
import jakarta.annotation.Generated;
import jakarta.data.metamodel.SortableAttribute;
import jakarta.data.metamodel.StaticMetamodel;
import jakarta.data.metamodel.TextAttribute;
import jakarta.data.metamodel.impl.SortableAttributeRecord;
import jakarta.data.metamodel.impl.TextAttributeRecord;
@StaticMetamodel(BaseEntity.class)
@Generated("org.hibernate.processor.HibernateProcessor")
public interface _BaseEntity {
Can I ask which fix are you talking about... ? https://hibernate.atlassian.net/browse/HHH-18019 is fixed in Hibernate ORM 6.5.3, which hasn't even been released yet.
If you need HHH-18019 to fix your Eclipse workspace, it's on its way.
If you have other problems with static model generation, I suggest you create an issue on the Hibernate Jira with a reproducer. Quarkus has little to do with that annotation processor, especially in your IDE.
Describe the bug
I'm leveraging https://github.com/quarkusio/quarkus/blob/3.11.0/bom/application/pom.xml#L5168-L5172 in
annotationProcessorPaths
ofmaven-compiler-plugin
so that I don't need to specify an explicit version (that needs to be compatible to the actual Hibernate version in Quarkus). Since Quarkus 3.11.0 has updated to Hibernate 6.5.2.Final, the annotation processor is also updated for that version (coming from 6.4.7.Final in Quarkus 3.10.2).Thing is I haven't structurally changed any dependencies, just tired updating. I cannot spot any Hibernate Reactive (nor Panache) dependencies in my dep tree so I'm puzzled why this bit in jpamodelgen seems to be finding a
io.quarkus.hibernate.reactive.panache
package.This might actually be an upstream issue in Hibernate but for a start I chose to report it here.
Expected behavior
Working jpamodelgen like in 3.10.2
Actual behavior
jpamodelgen does not generate metamodel classes anymore and logs a warning, consequently my app doesn't compile anymore.
How to Reproduce?
n/a for now
Output of
uname -a
orver
No response
Output of
java -version
17.0.11
Quarkus version or git rev
3.11.0
Build tool (ie. output of
mvnw --version
orgradlew --version
)No response
Additional information