From fb6296a5647ed33ad98fcfb2f36140ff570502a9 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 16:07:40 +0100 Subject: [PATCH 1/7] Persistence models: recognise jakarta.persistence --- .../java/frameworks/javaee/Persistence.qll | 220 +++++++++++------- 1 file changed, 140 insertions(+), 80 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll index e60659426e56..b1f256878af5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll @@ -4,6 +4,10 @@ import java +private string getAPersistencePackageName() { + result = ["javax.persistence", "jakarta.persistence"] +} + /** * A `RefType` with the `@Entity` annotation that indicates that it can be persisted using a JPA * compatible framework. @@ -27,7 +31,7 @@ class PersistentEntity extends RefType { else // If the access type is not explicit, then the location of the `Id` annotation determines // which access type is used. - if this.getAMethod().hasAnnotation("javax.persistence", "Id") + if this.getAMethod().hasAnnotation(getAPersistencePackageName(), "Id") then result = "property" else result = "field" } @@ -51,14 +55,16 @@ class PersistentEntity extends RefType { * A `@javax.persistence.Access` annotation. */ class AccessAnnotation extends Annotation { - AccessAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Access") } + AccessAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Access") } } /** * A `@javax.persistence.AccessType` annotation. */ class AccessTypeAnnotation extends Annotation { - AccessTypeAnnotation() { this.getType().hasQualifiedName("javax.persistence", "AccessType") } + AccessTypeAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "AccessType") + } } /** @@ -66,7 +72,7 @@ class AccessTypeAnnotation extends Annotation { */ class AssociationOverrideAnnotation extends Annotation { AssociationOverrideAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AssociationOverride") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AssociationOverride") } } @@ -75,7 +81,7 @@ class AssociationOverrideAnnotation extends Annotation { */ class AssociationOverridesAnnotation extends Annotation { AssociationOverridesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AssociationOverrides") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AssociationOverrides") } } @@ -84,7 +90,7 @@ class AssociationOverridesAnnotation extends Annotation { */ class AttributeOverrideAnnotation extends Annotation { AttributeOverrideAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AttributeOverride") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AttributeOverride") } } @@ -93,7 +99,7 @@ class AttributeOverrideAnnotation extends Annotation { */ class AttributeOverridesAnnotation extends Annotation { AttributeOverridesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AttributeOverrides") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AttributeOverrides") } } @@ -101,14 +107,16 @@ class AttributeOverridesAnnotation extends Annotation { * A `@javax.persistence.Basic` annotation. */ class BasicAnnotation extends Annotation { - BasicAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Basic") } + BasicAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Basic") } } /** * A `@javax.persistence.Cacheable` annotation. */ class CacheableAnnotation extends Annotation { - CacheableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Cacheable") } + CacheableAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Cacheable") + } } /** @@ -116,7 +124,7 @@ class CacheableAnnotation extends Annotation { */ class CollectionTableAnnotation extends Annotation { CollectionTableAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "CollectionTable") + this.getType().hasQualifiedName(getAPersistencePackageName(), "CollectionTable") } } @@ -124,14 +132,16 @@ class CollectionTableAnnotation extends Annotation { * A `@javax.persistence.Column` annotation. */ class ColumnAnnotation extends Annotation { - ColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Column") } + ColumnAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Column") } } /** * A `@javax.persistence.ColumnResult` annotation. */ class ColumnResultAnnotation extends Annotation { - ColumnResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ColumnResult") } + ColumnResultAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "ColumnResult") + } } /** @@ -139,7 +149,7 @@ class ColumnResultAnnotation extends Annotation { */ class DiscriminatorColumnAnnotation extends Annotation { DiscriminatorColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "DiscriminatorColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "DiscriminatorColumn") } } @@ -148,7 +158,7 @@ class DiscriminatorColumnAnnotation extends Annotation { */ class DiscriminatorValueAnnotation extends Annotation { DiscriminatorValueAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "DiscriminatorValue") + this.getType().hasQualifiedName(getAPersistencePackageName(), "DiscriminatorValue") } } @@ -157,7 +167,7 @@ class DiscriminatorValueAnnotation extends Annotation { */ class ElementCollectionAnnotation extends Annotation { ElementCollectionAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ElementCollection") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ElementCollection") } } @@ -165,28 +175,32 @@ class ElementCollectionAnnotation extends Annotation { * A `@javax.persistence.Embeddable` annotation. */ class EmbeddableAnnotation extends Annotation { - EmbeddableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Embeddable") } + EmbeddableAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Embeddable") + } } /** * A `@javax.persistence.Embedded` annotation. */ class EmbeddedAnnotation extends Annotation { - EmbeddedAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Embedded") } + EmbeddedAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Embedded") } } /** * A `@javax.persistence.EmbeddedId` annotation. */ class EmbeddedIdAnnotation extends Annotation { - EmbeddedIdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "EmbeddedId") } + EmbeddedIdAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "EmbeddedId") + } } /** * A `@javax.persistence.Entity` annotation. */ class EntityAnnotation extends Annotation { - EntityAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Entity") } + EntityAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Entity") } } /** @@ -194,7 +208,7 @@ class EntityAnnotation extends Annotation { */ class EntityListenersAnnotation extends Annotation { EntityListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "EntityListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "EntityListeners") } } @@ -202,14 +216,18 @@ class EntityListenersAnnotation extends Annotation { * A `@javax.persistence.EntityResult` annotation. */ class EntityResultAnnotation extends Annotation { - EntityResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "EntityResult") } + EntityResultAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "EntityResult") + } } /** * A `@javax.persistence.Enumerated` annotation. */ class EnumeratedAnnotation extends Annotation { - EnumeratedAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Enumerated") } + EnumeratedAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Enumerated") + } } /** @@ -217,7 +235,7 @@ class EnumeratedAnnotation extends Annotation { */ class ExcludeDefaultListenersAnnotation extends Annotation { ExcludeDefaultListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ExcludeDefaultListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ExcludeDefaultListeners") } } @@ -226,7 +244,7 @@ class ExcludeDefaultListenersAnnotation extends Annotation { */ class ExcludeSuperclassListenersAnnotation extends Annotation { ExcludeSuperclassListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ExcludeSuperclassListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ExcludeSuperclassListeners") } } @@ -234,7 +252,9 @@ class ExcludeSuperclassListenersAnnotation extends Annotation { * A `@javax.persistence.FieldResult` annotation. */ class FieldResultAnnotation extends Annotation { - FieldResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "FieldResult") } + FieldResultAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "FieldResult") + } } /** @@ -242,7 +262,7 @@ class FieldResultAnnotation extends Annotation { */ class GeneratedValueAnnotation extends Annotation { GeneratedValueAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "GeneratedValue") + this.getType().hasQualifiedName(getAPersistencePackageName(), "GeneratedValue") } } @@ -250,84 +270,100 @@ class GeneratedValueAnnotation extends Annotation { * A `@javax.persistence.Id` annotation. */ class IdAnnotation extends Annotation { - IdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Id") } + IdAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Id") } } /** * A `@javax.persistence.IdClass` annotation. */ class IdClassAnnotation extends Annotation { - IdClassAnnotation() { this.getType().hasQualifiedName("javax.persistence", "IdClass") } + IdClassAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "IdClass") } } /** * A `@javax.persistence.Inheritance` annotation. */ class InheritanceAnnotation extends Annotation { - InheritanceAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Inheritance") } + InheritanceAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Inheritance") + } } /** * A `@javax.persistence.JoinColumn` annotation. */ class JoinColumnAnnotation extends Annotation { - JoinColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinColumn") } + JoinColumnAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "JoinColumn") + } } /** * A `@javax.persistence.JoinColumns` annotation. */ class JoinColumnsAnnotation extends Annotation { - JoinColumnsAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinColumns") } + JoinColumnsAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "JoinColumns") + } } /** * A `@javax.persistence.JoinTable` annotation. */ class JoinTableAnnotation extends Annotation { - JoinTableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinTable") } + JoinTableAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "JoinTable") + } } /** * A `@javax.persistence.Lob` annotation. */ class LobAnnotation extends Annotation { - LobAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Lob") } + LobAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Lob") } } /** * A `@javax.persistence.ManyToMany` annotation. */ class ManyToManyAnnotation extends Annotation { - ManyToManyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ManyToMany") } + ManyToManyAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "ManyToMany") + } } /** * A `@javax.persistence.ManyToOne` annotation. */ class ManyToOneAnnotation extends Annotation { - ManyToOneAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ManyToOne") } + ManyToOneAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "ManyToOne") + } } /** * A `@javax.persistence.MapKey` annotation. */ class MapKeyAnnotation extends Annotation { - MapKeyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKey") } + MapKeyAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKey") } } /** * A `@javax.persistence.MapKeyClass` annotation. */ class MapKeyClassAnnotation extends Annotation { - MapKeyClassAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKeyClass") } + MapKeyClassAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyClass") + } } /** * A `@javax.persistence.MapKeyColumn` annotation. */ class MapKeyColumnAnnotation extends Annotation { - MapKeyColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKeyColumn") } + MapKeyColumnAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyColumn") + } } /** @@ -335,7 +371,7 @@ class MapKeyColumnAnnotation extends Annotation { */ class MapKeyEnumeratedAnnotation extends Annotation { MapKeyEnumeratedAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyEnumerated") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyEnumerated") } } @@ -344,7 +380,7 @@ class MapKeyEnumeratedAnnotation extends Annotation { */ class MapKeyJoinColumnAnnotation extends Annotation { MapKeyJoinColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyJoinColumn") } } @@ -353,7 +389,7 @@ class MapKeyJoinColumnAnnotation extends Annotation { */ class MapKeyJoinColumnsAnnotation extends Annotation { MapKeyJoinColumnsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumns") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyJoinColumns") } } @@ -362,7 +398,7 @@ class MapKeyJoinColumnsAnnotation extends Annotation { */ class MapKeyTemporalAnnotation extends Annotation { MapKeyTemporalAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyTemporal") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyTemporal") } } @@ -371,7 +407,7 @@ class MapKeyTemporalAnnotation extends Annotation { */ class MappedSuperclassAnnotation extends Annotation { MappedSuperclassAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MappedSuperclass") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MappedSuperclass") } } @@ -379,7 +415,7 @@ class MappedSuperclassAnnotation extends Annotation { * A `@javax.persistence.MapsId` annotation. */ class MapsIdAnnotation extends Annotation { - MapsIdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapsId") } + MapsIdAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "MapsId") } } /** @@ -387,7 +423,7 @@ class MapsIdAnnotation extends Annotation { */ class NamedNativeQueriesAnnotation extends Annotation { NamedNativeQueriesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "NamedNativeQueries") + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedNativeQueries") } } @@ -396,7 +432,7 @@ class NamedNativeQueriesAnnotation extends Annotation { */ class NamedNativeQueryAnnotation extends Annotation { NamedNativeQueryAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "NamedNativeQuery") + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedNativeQuery") } } @@ -404,42 +440,50 @@ class NamedNativeQueryAnnotation extends Annotation { * A `@javax.persistence.NamedQueries` annotation. */ class NamedQueriesAnnotation extends Annotation { - NamedQueriesAnnotation() { this.getType().hasQualifiedName("javax.persistence", "NamedQueries") } + NamedQueriesAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedQueries") + } } /** * A `@javax.persistence.NamedQuery` annotation. */ class NamedQueryAnnotation extends Annotation { - NamedQueryAnnotation() { this.getType().hasQualifiedName("javax.persistence", "NamedQuery") } + NamedQueryAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedQuery") + } } /** * A `@javax.persistence.OneToMany` annotation. */ class OneToManyAnnotation extends Annotation { - OneToManyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OneToMany") } + OneToManyAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "OneToMany") + } } /** * A `@javax.persistence.OneToOne` annotation. */ class OneToOneAnnotation extends Annotation { - OneToOneAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OneToOne") } + OneToOneAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "OneToOne") } } /** * A `@javax.persistence.OrderBy` annotation. */ class OrderByAnnotation extends Annotation { - OrderByAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OrderBy") } + OrderByAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "OrderBy") } } /** * A `@javax.persistence.OrderColumn` annotation. */ class OrderColumnAnnotation extends Annotation { - OrderColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OrderColumn") } + OrderColumnAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "OrderColumn") + } } /** @@ -447,7 +491,7 @@ class OrderColumnAnnotation extends Annotation { */ class PersistenceContextAnnotation extends Annotation { PersistenceContextAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceContext") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceContext") } } @@ -456,7 +500,7 @@ class PersistenceContextAnnotation extends Annotation { */ class PersistenceContextsAnnotation extends Annotation { PersistenceContextsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceContexts") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceContexts") } } @@ -465,7 +509,7 @@ class PersistenceContextsAnnotation extends Annotation { */ class PersistencePropertyAnnotation extends Annotation { PersistencePropertyAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceProperty") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceProperty") } } @@ -474,7 +518,7 @@ class PersistencePropertyAnnotation extends Annotation { */ class PersistenceUnitAnnotation extends Annotation { PersistenceUnitAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceUnit") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceUnit") } } @@ -483,7 +527,7 @@ class PersistenceUnitAnnotation extends Annotation { */ class PersistenceUnitsAnnotation extends Annotation { PersistenceUnitsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceUnits") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceUnits") } } @@ -491,49 +535,61 @@ class PersistenceUnitsAnnotation extends Annotation { * A `@javax.persistence.PostLoad` annotation. */ class PostLoadAnnotation extends Annotation { - PostLoadAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostLoad") } + PostLoadAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "PostLoad") } } /** * A `@javax.persistence.PostPersist` annotation. */ class PostPersistAnnotation extends Annotation { - PostPersistAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostPersist") } + PostPersistAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PostPersist") + } } /** * A `@javax.persistence.PostRemove` annotation. */ class PostRemoveAnnotation extends Annotation { - PostRemoveAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostRemove") } + PostRemoveAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PostRemove") + } } /** * A `@javax.persistence.PostUpdate` annotation. */ class PostUpdateAnnotation extends Annotation { - PostUpdateAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostUpdate") } + PostUpdateAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PostUpdate") + } } /** * A `@javax.persistence.PrePersist` annotation. */ class PrePersistAnnotation extends Annotation { - PrePersistAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PrePersist") } + PrePersistAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PrePersist") + } } /** * A `@javax.persistence.PreRemove` annotation. */ class PreRemoveAnnotation extends Annotation { - PreRemoveAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PreRemove") } + PreRemoveAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PreRemove") + } } /** * A `@javax.persistence.PreUpdate` annotation. */ class PreUpdateAnnotation extends Annotation { - PreUpdateAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PreUpdate") } + PreUpdateAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PreUpdate") + } } /** @@ -541,7 +597,7 @@ class PreUpdateAnnotation extends Annotation { */ class PrimaryKeyJoinColumnAnnotation extends Annotation { PrimaryKeyJoinColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PrimaryKeyJoinColumn") } } @@ -550,7 +606,7 @@ class PrimaryKeyJoinColumnAnnotation extends Annotation { */ class PrimaryKeyJoinColumnsAnnotation extends Annotation { PrimaryKeyJoinColumnsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumns") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PrimaryKeyJoinColumns") } } @@ -558,7 +614,9 @@ class PrimaryKeyJoinColumnsAnnotation extends Annotation { * A `@javax.persistence.QueryHint` annotation. */ class QueryHintAnnotation extends Annotation { - QueryHintAnnotation() { this.getType().hasQualifiedName("javax.persistence", "QueryHint") } + QueryHintAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "QueryHint") + } } /** @@ -566,7 +624,7 @@ class QueryHintAnnotation extends Annotation { */ class SecondaryTableAnnotation extends Annotation { SecondaryTableAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SecondaryTable") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SecondaryTable") } } @@ -575,7 +633,7 @@ class SecondaryTableAnnotation extends Annotation { */ class SecondaryTablesAnnotation extends Annotation { SecondaryTablesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SecondaryTables") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SecondaryTables") } } @@ -584,7 +642,7 @@ class SecondaryTablesAnnotation extends Annotation { */ class SequenceGeneratorAnnotation extends Annotation { SequenceGeneratorAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SequenceGenerator") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SequenceGenerator") } } @@ -593,7 +651,7 @@ class SequenceGeneratorAnnotation extends Annotation { */ class SqlResultSetMappingAnnotation extends Annotation { SqlResultSetMappingAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMapping") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SqlResultSetMapping") } } @@ -602,7 +660,7 @@ class SqlResultSetMappingAnnotation extends Annotation { */ class SqlResultSetMappingsAnnotation extends Annotation { SqlResultSetMappingsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMappings") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SqlResultSetMappings") } } @@ -610,7 +668,7 @@ class SqlResultSetMappingsAnnotation extends Annotation { * A `@javax.persistence.Table` annotation. */ class TableAnnotation extends Annotation { - TableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Table") } + TableAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Table") } } /** @@ -618,7 +676,7 @@ class TableAnnotation extends Annotation { */ class TableGeneratorAnnotation extends Annotation { TableGeneratorAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "TableGenerator") + this.getType().hasQualifiedName(getAPersistencePackageName(), "TableGenerator") } } @@ -626,14 +684,16 @@ class TableGeneratorAnnotation extends Annotation { * A `@javax.persistence.Temporal` annotation. */ class TemporalAnnotation extends Annotation { - TemporalAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Temporal") } + TemporalAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Temporal") } } /** * A `@javax.persistence.Transient` annotation. */ class TransientAnnotation extends Annotation { - TransientAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Transient") } + TransientAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Transient") + } } /** @@ -641,7 +701,7 @@ class TransientAnnotation extends Annotation { */ class UniqueConstraintAnnotation extends Annotation { UniqueConstraintAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "UniqueConstraint") + this.getType().hasQualifiedName(getAPersistencePackageName(), "UniqueConstraint") } } @@ -649,12 +709,12 @@ class UniqueConstraintAnnotation extends Annotation { * A `@javax.persistence.Version` annotation. */ class VersionAnnotation extends Annotation { - VersionAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Version") } + VersionAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Version") } } /** The interface `javax.persistence.EntityManager`. */ class TypeEntityManager extends Interface { - TypeEntityManager() { this.hasQualifiedName("javax.persistence", "EntityManager") } + TypeEntityManager() { this.hasQualifiedName(getAPersistencePackageName(), "EntityManager") } /** Gets a method named `createQuery` declared in the `EntityManager` interface. */ Method getACreateQueryMethod() { @@ -677,7 +737,7 @@ class TypeEntityManager extends Interface { /** The interface `javax.persistence.Query`, which represents queries in the Java Persistence Query Language. */ class TypeQuery extends Interface { - TypeQuery() { this.hasQualifiedName("javax.persistence", "Query") } + TypeQuery() { this.hasQualifiedName(getAPersistencePackageName(), "Query") } /** Gets a method named `setParameter` declared in the `Query` interface. */ Method getASetParameterMethod() { From a5a6fd37dfc0f77f6db7bed6a9c6b5178263707c Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 16:19:42 +0100 Subject: [PATCH 2/7] Enable recognising jakarta.persistence in dead-code queries --- java/ql/lib/semmle/code/java/deadcode/DeadField.qll | 5 +++-- java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll | 3 ++- .../lib/semmle/code/java/frameworks/javaee/Persistence.qll | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll index 48cfd945375a..b1a990ac246f 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll @@ -3,6 +3,7 @@ import semmle.code.java.deadcode.DeadCode import semmle.code.java.frameworks.javaee.Persistence import semmle.code.java.frameworks.JAXB import semmle.code.java.frameworks.jackson.JacksonSerializability +import semmle.code.java.frameworks.javaee.Persistence /** * A field that is from a source file. @@ -161,10 +162,10 @@ class JpaReadField extends ReflectivelyReadField { this = entity.getAField() and ( entity.getAccessType() = "field" or - this.hasAnnotation("javax.persistence", "Access") + this.hasAnnotation(getAPersistencePackageName(), "Access") ) | - not this.hasAnnotation("javax.persistence", "Transient") and + not this.hasAnnotation(getAPersistencePackageName(), "Transient") and not this.isStatic() and not this.isFinal() ) diff --git a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll index bca78aeae05c..7c0a2fdc2d37 100644 --- a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll @@ -7,6 +7,7 @@ import semmle.code.java.deadcode.StrutsEntryPoints import semmle.code.java.deadcode.TestEntryPoints import semmle.code.java.deadcode.WebEntryPoints import semmle.code.java.frameworks.javaee.JavaServerFaces +import semmle.code.java.frameworks.javaee.Persistence import semmle.code.java.frameworks.JAXB import semmle.code.java.frameworks.JaxWS import semmle.code.java.JMX @@ -395,7 +396,7 @@ class PersistencePropertyMethod extends CallableEntryPoint { this = e.getACallable() and ( e.getAccessType() = "property" or - this.hasAnnotation("javax.persistence", "Access") + this.hasAnnotation(getAPersistencePackageName(), "Access") ) and ( this.getName().matches("get%") or diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll index b1f256878af5..482988050d2e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll @@ -4,7 +4,10 @@ import java -private string getAPersistencePackageName() { +/** + * Gets a JavaEE Persistence API package name. + */ +string getAPersistencePackageName() { result = ["javax.persistence", "jakarta.persistence"] } From 50119ae481ed4a8f6fa4f89a26b89532624e6b80 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 16:20:06 +0100 Subject: [PATCH 3/7] Update docs --- .../java/frameworks/javaee/Persistence.qll | 162 +++++++++--------- 1 file changed, 80 insertions(+), 82 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll index 482988050d2e..1cb9af2e0d9a 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll @@ -7,9 +7,7 @@ import java /** * Gets a JavaEE Persistence API package name. */ -string getAPersistencePackageName() { - result = ["javax.persistence", "jakarta.persistence"] -} +string getAPersistencePackageName() { result = ["javax.persistence", "jakarta.persistence"] } /** * A `RefType` with the `@Entity` annotation that indicates that it can be persisted using a JPA @@ -40,7 +38,7 @@ class PersistentEntity extends RefType { } /** - * Gets the access type for this entity as defined by a `@javax.persistence.Access` annotation, + * Gets the access type for this entity as defined by a `@{javax,jakarta}.persistence.Access` annotation, * if any, in lower case. */ string getAccessTypeFromAnnotation() { @@ -51,18 +49,18 @@ class PersistentEntity extends RefType { } /* - * Annotations in the `javax.persistence` package. + * Annotations in the `{javax,jakarta}.persistence` package. */ /** - * A `@javax.persistence.Access` annotation. + * A `@{javax,jakarta}.persistence.Access` annotation. */ class AccessAnnotation extends Annotation { AccessAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Access") } } /** - * A `@javax.persistence.AccessType` annotation. + * A `@{javax,jakarta}.persistence.AccessType` annotation. */ class AccessTypeAnnotation extends Annotation { AccessTypeAnnotation() { @@ -71,7 +69,7 @@ class AccessTypeAnnotation extends Annotation { } /** - * A `@javax.persistence.AssociationOverride` annotation. + * A `@{javax,jakarta}.persistence.AssociationOverride` annotation. */ class AssociationOverrideAnnotation extends Annotation { AssociationOverrideAnnotation() { @@ -80,7 +78,7 @@ class AssociationOverrideAnnotation extends Annotation { } /** - * A `@javax.persistence.AssociationOverrides` annotation. + * A `@{javax,jakarta}.persistence.AssociationOverrides` annotation. */ class AssociationOverridesAnnotation extends Annotation { AssociationOverridesAnnotation() { @@ -89,7 +87,7 @@ class AssociationOverridesAnnotation extends Annotation { } /** - * A `@javax.persistence.AttributeOverride` annotation. + * A `@{javax,jakarta}.persistence.AttributeOverride` annotation. */ class AttributeOverrideAnnotation extends Annotation { AttributeOverrideAnnotation() { @@ -98,7 +96,7 @@ class AttributeOverrideAnnotation extends Annotation { } /** - * A `@javax.persistence.AttributeOverrides` annotation. + * A `@{javax,jakarta}.persistence.AttributeOverrides` annotation. */ class AttributeOverridesAnnotation extends Annotation { AttributeOverridesAnnotation() { @@ -107,14 +105,14 @@ class AttributeOverridesAnnotation extends Annotation { } /** - * A `@javax.persistence.Basic` annotation. + * A `@{javax,jakarta}.persistence.Basic` annotation. */ class BasicAnnotation extends Annotation { BasicAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Basic") } } /** - * A `@javax.persistence.Cacheable` annotation. + * A `@{javax,jakarta}.persistence.Cacheable` annotation. */ class CacheableAnnotation extends Annotation { CacheableAnnotation() { @@ -123,7 +121,7 @@ class CacheableAnnotation extends Annotation { } /** - * A `@javax.persistence.CollectionTable` annotation. + * A `@{javax,jakarta}.persistence.CollectionTable` annotation. */ class CollectionTableAnnotation extends Annotation { CollectionTableAnnotation() { @@ -132,14 +130,14 @@ class CollectionTableAnnotation extends Annotation { } /** - * A `@javax.persistence.Column` annotation. + * A `@{javax,jakarta}.persistence.Column` annotation. */ class ColumnAnnotation extends Annotation { ColumnAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Column") } } /** - * A `@javax.persistence.ColumnResult` annotation. + * A `@{javax,jakarta}.persistence.ColumnResult` annotation. */ class ColumnResultAnnotation extends Annotation { ColumnResultAnnotation() { @@ -148,7 +146,7 @@ class ColumnResultAnnotation extends Annotation { } /** - * A `@javax.persistence.DiscriminatorColumn` annotation. + * A `@{javax,jakarta}.persistence.DiscriminatorColumn` annotation. */ class DiscriminatorColumnAnnotation extends Annotation { DiscriminatorColumnAnnotation() { @@ -157,7 +155,7 @@ class DiscriminatorColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.DiscriminatorValue` annotation. + * A `@{javax,jakarta}.persistence.DiscriminatorValue` annotation. */ class DiscriminatorValueAnnotation extends Annotation { DiscriminatorValueAnnotation() { @@ -166,7 +164,7 @@ class DiscriminatorValueAnnotation extends Annotation { } /** - * A `@javax.persistence.ElementCollection` annotation. + * A `@{javax,jakarta}.persistence.ElementCollection` annotation. */ class ElementCollectionAnnotation extends Annotation { ElementCollectionAnnotation() { @@ -175,7 +173,7 @@ class ElementCollectionAnnotation extends Annotation { } /** - * A `@javax.persistence.Embeddable` annotation. + * A `@{javax,jakarta}.persistence.Embeddable` annotation. */ class EmbeddableAnnotation extends Annotation { EmbeddableAnnotation() { @@ -184,14 +182,14 @@ class EmbeddableAnnotation extends Annotation { } /** - * A `@javax.persistence.Embedded` annotation. + * A `@{javax,jakarta}.persistence.Embedded` annotation. */ class EmbeddedAnnotation extends Annotation { EmbeddedAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Embedded") } } /** - * A `@javax.persistence.EmbeddedId` annotation. + * A `@{javax,jakarta}.persistence.EmbeddedId` annotation. */ class EmbeddedIdAnnotation extends Annotation { EmbeddedIdAnnotation() { @@ -200,14 +198,14 @@ class EmbeddedIdAnnotation extends Annotation { } /** - * A `@javax.persistence.Entity` annotation. + * A `@{javax,jakarta}.persistence.Entity` annotation. */ class EntityAnnotation extends Annotation { EntityAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Entity") } } /** - * A `@javax.persistence.EntityListeners` annotation. + * A `@{javax,jakarta}.persistence.EntityListeners` annotation. */ class EntityListenersAnnotation extends Annotation { EntityListenersAnnotation() { @@ -216,7 +214,7 @@ class EntityListenersAnnotation extends Annotation { } /** - * A `@javax.persistence.EntityResult` annotation. + * A `@{javax,jakarta}.persistence.EntityResult` annotation. */ class EntityResultAnnotation extends Annotation { EntityResultAnnotation() { @@ -225,7 +223,7 @@ class EntityResultAnnotation extends Annotation { } /** - * A `@javax.persistence.Enumerated` annotation. + * A `@{javax,jakarta}.persistence.Enumerated` annotation. */ class EnumeratedAnnotation extends Annotation { EnumeratedAnnotation() { @@ -234,7 +232,7 @@ class EnumeratedAnnotation extends Annotation { } /** - * A `@javax.persistence.ExcludeDefaultListeners` annotation. + * A `@{javax,jakarta}.persistence.ExcludeDefaultListeners` annotation. */ class ExcludeDefaultListenersAnnotation extends Annotation { ExcludeDefaultListenersAnnotation() { @@ -243,7 +241,7 @@ class ExcludeDefaultListenersAnnotation extends Annotation { } /** - * A `@javax.persistence.ExcludeSuperclassListeners` annotation. + * A `@{javax,jakarta}.persistence.ExcludeSuperclassListeners` annotation. */ class ExcludeSuperclassListenersAnnotation extends Annotation { ExcludeSuperclassListenersAnnotation() { @@ -252,7 +250,7 @@ class ExcludeSuperclassListenersAnnotation extends Annotation { } /** - * A `@javax.persistence.FieldResult` annotation. + * A `@{javax,jakarta}.persistence.FieldResult` annotation. */ class FieldResultAnnotation extends Annotation { FieldResultAnnotation() { @@ -261,7 +259,7 @@ class FieldResultAnnotation extends Annotation { } /** - * A `@javax.persistence.GeneratedValue` annotation. + * A `@{javax,jakarta}.persistence.GeneratedValue` annotation. */ class GeneratedValueAnnotation extends Annotation { GeneratedValueAnnotation() { @@ -270,21 +268,21 @@ class GeneratedValueAnnotation extends Annotation { } /** - * A `@javax.persistence.Id` annotation. + * A `@{javax,jakarta}.persistence.Id` annotation. */ class IdAnnotation extends Annotation { IdAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Id") } } /** - * A `@javax.persistence.IdClass` annotation. + * A `@{javax,jakarta}.persistence.IdClass` annotation. */ class IdClassAnnotation extends Annotation { IdClassAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "IdClass") } } /** - * A `@javax.persistence.Inheritance` annotation. + * A `@{javax,jakarta}.persistence.Inheritance` annotation. */ class InheritanceAnnotation extends Annotation { InheritanceAnnotation() { @@ -293,7 +291,7 @@ class InheritanceAnnotation extends Annotation { } /** - * A `@javax.persistence.JoinColumn` annotation. + * A `@{javax,jakarta}.persistence.JoinColumn` annotation. */ class JoinColumnAnnotation extends Annotation { JoinColumnAnnotation() { @@ -302,7 +300,7 @@ class JoinColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.JoinColumns` annotation. + * A `@{javax,jakarta}.persistence.JoinColumns` annotation. */ class JoinColumnsAnnotation extends Annotation { JoinColumnsAnnotation() { @@ -311,7 +309,7 @@ class JoinColumnsAnnotation extends Annotation { } /** - * A `@javax.persistence.JoinTable` annotation. + * A `@{javax,jakarta}.persistence.JoinTable` annotation. */ class JoinTableAnnotation extends Annotation { JoinTableAnnotation() { @@ -320,14 +318,14 @@ class JoinTableAnnotation extends Annotation { } /** - * A `@javax.persistence.Lob` annotation. + * A `@{javax,jakarta}.persistence.Lob` annotation. */ class LobAnnotation extends Annotation { LobAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Lob") } } /** - * A `@javax.persistence.ManyToMany` annotation. + * A `@{javax,jakarta}.persistence.ManyToMany` annotation. */ class ManyToManyAnnotation extends Annotation { ManyToManyAnnotation() { @@ -336,7 +334,7 @@ class ManyToManyAnnotation extends Annotation { } /** - * A `@javax.persistence.ManyToOne` annotation. + * A `@{javax,jakarta}.persistence.ManyToOne` annotation. */ class ManyToOneAnnotation extends Annotation { ManyToOneAnnotation() { @@ -345,14 +343,14 @@ class ManyToOneAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKey` annotation. + * A `@{javax,jakarta}.persistence.MapKey` annotation. */ class MapKeyAnnotation extends Annotation { MapKeyAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKey") } } /** - * A `@javax.persistence.MapKeyClass` annotation. + * A `@{javax,jakarta}.persistence.MapKeyClass` annotation. */ class MapKeyClassAnnotation extends Annotation { MapKeyClassAnnotation() { @@ -361,7 +359,7 @@ class MapKeyClassAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKeyColumn` annotation. + * A `@{javax,jakarta}.persistence.MapKeyColumn` annotation. */ class MapKeyColumnAnnotation extends Annotation { MapKeyColumnAnnotation() { @@ -370,7 +368,7 @@ class MapKeyColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKeyEnumerated` annotation. + * A `@{javax,jakarta}.persistence.MapKeyEnumerated` annotation. */ class MapKeyEnumeratedAnnotation extends Annotation { MapKeyEnumeratedAnnotation() { @@ -379,7 +377,7 @@ class MapKeyEnumeratedAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKeyJoinColumn` annotation. + * A `@{javax,jakarta}.persistence.MapKeyJoinColumn` annotation. */ class MapKeyJoinColumnAnnotation extends Annotation { MapKeyJoinColumnAnnotation() { @@ -388,7 +386,7 @@ class MapKeyJoinColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKeyJoinColumns` annotation. + * A `@{javax,jakarta}.persistence.MapKeyJoinColumns` annotation. */ class MapKeyJoinColumnsAnnotation extends Annotation { MapKeyJoinColumnsAnnotation() { @@ -397,7 +395,7 @@ class MapKeyJoinColumnsAnnotation extends Annotation { } /** - * A `@javax.persistence.MapKeyTemporal` annotation. + * A `@{javax,jakarta}.persistence.MapKeyTemporal` annotation. */ class MapKeyTemporalAnnotation extends Annotation { MapKeyTemporalAnnotation() { @@ -406,7 +404,7 @@ class MapKeyTemporalAnnotation extends Annotation { } /** - * A `@javax.persistence.MappedSuperclass` annotation. + * A `@{javax,jakarta}.persistence.MappedSuperclass` annotation. */ class MappedSuperclassAnnotation extends Annotation { MappedSuperclassAnnotation() { @@ -415,14 +413,14 @@ class MappedSuperclassAnnotation extends Annotation { } /** - * A `@javax.persistence.MapsId` annotation. + * A `@{javax,jakarta}.persistence.MapsId` annotation. */ class MapsIdAnnotation extends Annotation { MapsIdAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "MapsId") } } /** - * A `@javax.persistence.NamedNativeQueries` annotation. + * A `@{javax,jakarta}.persistence.NamedNativeQueries` annotation. */ class NamedNativeQueriesAnnotation extends Annotation { NamedNativeQueriesAnnotation() { @@ -431,7 +429,7 @@ class NamedNativeQueriesAnnotation extends Annotation { } /** - * A `@javax.persistence.NamedNativeQuery` annotation. + * A `@{javax,jakarta}.persistence.NamedNativeQuery` annotation. */ class NamedNativeQueryAnnotation extends Annotation { NamedNativeQueryAnnotation() { @@ -440,7 +438,7 @@ class NamedNativeQueryAnnotation extends Annotation { } /** - * A `@javax.persistence.NamedQueries` annotation. + * A `@{javax,jakarta}.persistence.NamedQueries` annotation. */ class NamedQueriesAnnotation extends Annotation { NamedQueriesAnnotation() { @@ -449,7 +447,7 @@ class NamedQueriesAnnotation extends Annotation { } /** - * A `@javax.persistence.NamedQuery` annotation. + * A `@{javax,jakarta}.persistence.NamedQuery` annotation. */ class NamedQueryAnnotation extends Annotation { NamedQueryAnnotation() { @@ -458,7 +456,7 @@ class NamedQueryAnnotation extends Annotation { } /** - * A `@javax.persistence.OneToMany` annotation. + * A `@{javax,jakarta}.persistence.OneToMany` annotation. */ class OneToManyAnnotation extends Annotation { OneToManyAnnotation() { @@ -467,21 +465,21 @@ class OneToManyAnnotation extends Annotation { } /** - * A `@javax.persistence.OneToOne` annotation. + * A `@{javax,jakarta}.persistence.OneToOne` annotation. */ class OneToOneAnnotation extends Annotation { OneToOneAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "OneToOne") } } /** - * A `@javax.persistence.OrderBy` annotation. + * A `@{javax,jakarta}.persistence.OrderBy` annotation. */ class OrderByAnnotation extends Annotation { OrderByAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "OrderBy") } } /** - * A `@javax.persistence.OrderColumn` annotation. + * A `@{javax,jakarta}.persistence.OrderColumn` annotation. */ class OrderColumnAnnotation extends Annotation { OrderColumnAnnotation() { @@ -490,7 +488,7 @@ class OrderColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.PersistenceContext` annotation. + * A `@{javax,jakarta}.persistence.PersistenceContext` annotation. */ class PersistenceContextAnnotation extends Annotation { PersistenceContextAnnotation() { @@ -499,7 +497,7 @@ class PersistenceContextAnnotation extends Annotation { } /** - * A `@javax.persistence.PersistenceContexts` annotation. + * A `@{javax,jakarta}.persistence.PersistenceContexts` annotation. */ class PersistenceContextsAnnotation extends Annotation { PersistenceContextsAnnotation() { @@ -508,7 +506,7 @@ class PersistenceContextsAnnotation extends Annotation { } /** - * A `@javax.persistence.PersistenceProperty` annotation. + * A `@{javax,jakarta}.persistence.PersistenceProperty` annotation. */ class PersistencePropertyAnnotation extends Annotation { PersistencePropertyAnnotation() { @@ -517,7 +515,7 @@ class PersistencePropertyAnnotation extends Annotation { } /** - * A `@javax.persistence.PersistenceUnit` annotation. + * A `@{javax,jakarta}.persistence.PersistenceUnit` annotation. */ class PersistenceUnitAnnotation extends Annotation { PersistenceUnitAnnotation() { @@ -526,7 +524,7 @@ class PersistenceUnitAnnotation extends Annotation { } /** - * A `@javax.persistence.PersistenceUnits` annotation. + * A `@{javax,jakarta}.persistence.PersistenceUnits` annotation. */ class PersistenceUnitsAnnotation extends Annotation { PersistenceUnitsAnnotation() { @@ -535,14 +533,14 @@ class PersistenceUnitsAnnotation extends Annotation { } /** - * A `@javax.persistence.PostLoad` annotation. + * A `@{javax,jakarta}.persistence.PostLoad` annotation. */ class PostLoadAnnotation extends Annotation { PostLoadAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "PostLoad") } } /** - * A `@javax.persistence.PostPersist` annotation. + * A `@{javax,jakarta}.persistence.PostPersist` annotation. */ class PostPersistAnnotation extends Annotation { PostPersistAnnotation() { @@ -551,7 +549,7 @@ class PostPersistAnnotation extends Annotation { } /** - * A `@javax.persistence.PostRemove` annotation. + * A `@{javax,jakarta}.persistence.PostRemove` annotation. */ class PostRemoveAnnotation extends Annotation { PostRemoveAnnotation() { @@ -560,7 +558,7 @@ class PostRemoveAnnotation extends Annotation { } /** - * A `@javax.persistence.PostUpdate` annotation. + * A `@{javax,jakarta}.persistence.PostUpdate` annotation. */ class PostUpdateAnnotation extends Annotation { PostUpdateAnnotation() { @@ -569,7 +567,7 @@ class PostUpdateAnnotation extends Annotation { } /** - * A `@javax.persistence.PrePersist` annotation. + * A `@{javax,jakarta}.persistence.PrePersist` annotation. */ class PrePersistAnnotation extends Annotation { PrePersistAnnotation() { @@ -578,7 +576,7 @@ class PrePersistAnnotation extends Annotation { } /** - * A `@javax.persistence.PreRemove` annotation. + * A `@{javax,jakarta}.persistence.PreRemove` annotation. */ class PreRemoveAnnotation extends Annotation { PreRemoveAnnotation() { @@ -587,7 +585,7 @@ class PreRemoveAnnotation extends Annotation { } /** - * A `@javax.persistence.PreUpdate` annotation. + * A `@{javax,jakarta}.persistence.PreUpdate` annotation. */ class PreUpdateAnnotation extends Annotation { PreUpdateAnnotation() { @@ -596,7 +594,7 @@ class PreUpdateAnnotation extends Annotation { } /** - * A `@javax.persistence.PrimaryKeyJoinColumn` annotation. + * A `@{javax,jakarta}.persistence.PrimaryKeyJoinColumn` annotation. */ class PrimaryKeyJoinColumnAnnotation extends Annotation { PrimaryKeyJoinColumnAnnotation() { @@ -605,7 +603,7 @@ class PrimaryKeyJoinColumnAnnotation extends Annotation { } /** - * A `@javax.persistence.PrimaryKeyJoinColumns` annotation. + * A `@{javax,jakarta}.persistence.PrimaryKeyJoinColumns` annotation. */ class PrimaryKeyJoinColumnsAnnotation extends Annotation { PrimaryKeyJoinColumnsAnnotation() { @@ -614,7 +612,7 @@ class PrimaryKeyJoinColumnsAnnotation extends Annotation { } /** - * A `@javax.persistence.QueryHint` annotation. + * A `@{javax,jakarta}.persistence.QueryHint` annotation. */ class QueryHintAnnotation extends Annotation { QueryHintAnnotation() { @@ -623,7 +621,7 @@ class QueryHintAnnotation extends Annotation { } /** - * A `@javax.persistence.SecondaryTable` annotation. + * A `@{javax,jakarta}.persistence.SecondaryTable` annotation. */ class SecondaryTableAnnotation extends Annotation { SecondaryTableAnnotation() { @@ -632,7 +630,7 @@ class SecondaryTableAnnotation extends Annotation { } /** - * A `@javax.persistence.SecondaryTables` annotation. + * A `@{javax,jakarta}.persistence.SecondaryTables` annotation. */ class SecondaryTablesAnnotation extends Annotation { SecondaryTablesAnnotation() { @@ -641,7 +639,7 @@ class SecondaryTablesAnnotation extends Annotation { } /** - * A `@javax.persistence.SequenceGenerator` annotation. + * A `@{javax,jakarta}.persistence.SequenceGenerator` annotation. */ class SequenceGeneratorAnnotation extends Annotation { SequenceGeneratorAnnotation() { @@ -650,7 +648,7 @@ class SequenceGeneratorAnnotation extends Annotation { } /** - * A `@javax.persistence.SqlResultSetMapping` annotation. + * A `@{javax,jakarta}.persistence.SqlResultSetMapping` annotation. */ class SqlResultSetMappingAnnotation extends Annotation { SqlResultSetMappingAnnotation() { @@ -659,7 +657,7 @@ class SqlResultSetMappingAnnotation extends Annotation { } /** - * A `@javax.persistence.SqlResultSetMappings` annotation. + * A `@{javax,jakarta}.persistence.SqlResultSetMappings` annotation. */ class SqlResultSetMappingsAnnotation extends Annotation { SqlResultSetMappingsAnnotation() { @@ -668,14 +666,14 @@ class SqlResultSetMappingsAnnotation extends Annotation { } /** - * A `@javax.persistence.Table` annotation. + * A `@{javax,jakarta}.persistence.Table` annotation. */ class TableAnnotation extends Annotation { TableAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Table") } } /** - * A `@javax.persistence.TableGenerator` annotation. + * A `@{javax,jakarta}.persistence.TableGenerator` annotation. */ class TableGeneratorAnnotation extends Annotation { TableGeneratorAnnotation() { @@ -684,14 +682,14 @@ class TableGeneratorAnnotation extends Annotation { } /** - * A `@javax.persistence.Temporal` annotation. + * A `@{javax,jakarta}.persistence.Temporal` annotation. */ class TemporalAnnotation extends Annotation { TemporalAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Temporal") } } /** - * A `@javax.persistence.Transient` annotation. + * A `@{javax,jakarta}.persistence.Transient` annotation. */ class TransientAnnotation extends Annotation { TransientAnnotation() { @@ -700,7 +698,7 @@ class TransientAnnotation extends Annotation { } /** - * A `@javax.persistence.UniqueConstraint` annotation. + * A `@{javax,jakarta}.persistence.UniqueConstraint` annotation. */ class UniqueConstraintAnnotation extends Annotation { UniqueConstraintAnnotation() { @@ -709,7 +707,7 @@ class UniqueConstraintAnnotation extends Annotation { } /** - * A `@javax.persistence.Version` annotation. + * A `@{javax,jakarta}.persistence.Version` annotation. */ class VersionAnnotation extends Annotation { VersionAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Version") } From 20839745bdef8c13662321d96c33027234d62afb Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 16:49:56 +0100 Subject: [PATCH 4/7] Remove redundant import --- java/ql/lib/semmle/code/java/deadcode/DeadField.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll index b1a990ac246f..2dcbb96f3b59 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll @@ -3,7 +3,6 @@ import semmle.code.java.deadcode.DeadCode import semmle.code.java.frameworks.javaee.Persistence import semmle.code.java.frameworks.JAXB import semmle.code.java.frameworks.jackson.JacksonSerializability -import semmle.code.java.frameworks.javaee.Persistence /** * A field that is from a source file. From 5d37ccfa9046e1d26659209bc99ee367994bd3d0 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 16:51:29 +0100 Subject: [PATCH 5/7] Change note --- java/ql/lib/change-notes/2025-04-01-jakarta-persistence.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2025-04-01-jakarta-persistence.md diff --git a/java/ql/lib/change-notes/2025-04-01-jakarta-persistence.md b/java/ql/lib/change-notes/2025-04-01-jakarta-persistence.md new file mode 100644 index 000000000000..0a5759ec3dbc --- /dev/null +++ b/java/ql/lib/change-notes/2025-04-01-jakarta-persistence.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* All existing modelling and support for `javax.persistence` now applies to `jakarta.persistence` as well. From 3c555fce112a1b699255dfd26aace94407e25c00 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 1 Apr 2025 17:12:35 +0100 Subject: [PATCH 6/7] Add basic test for SQL injection vs Jakarta Persistence --- .../CWE-089/semmle/examples/JakartaPersistence.java | 13 +++++++++++++ .../security/CWE-089/semmle/examples/options | 2 +- .../jakarta/persistence/EntityManager.java | 7 +++++++ .../jakarta/persistence/Query.java | 7 +++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/query-tests/security/CWE-089/semmle/examples/JakartaPersistence.java create mode 100644 java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/EntityManager.java create mode 100644 java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/Query.java diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/JakartaPersistence.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/JakartaPersistence.java new file mode 100644 index 000000000000..0327a75cf778 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/JakartaPersistence.java @@ -0,0 +1,13 @@ +import jakarta.persistence.EntityManager; + +public class JakartaPersistence { + + public static String source() { return null; } + + public static void test(EntityManager entityManager) { + + entityManager.createNativeQuery(source()); // $ sqlInjection + + } + +} diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/options b/java/ql/test/query-tests/security/CWE-089/semmle/examples/options index 832af0f3423c..0252ff61ad38 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/options +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.8.x:${testdir}/../../../../../stubs/apache-hive --release 21 +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.8.x:${testdir}/../../../../../stubs/apache-hive:${testdir}/../../../../../stubs/jakarta-persistence-api-3.2.0 --release 21 diff --git a/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/EntityManager.java b/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/EntityManager.java new file mode 100644 index 000000000000..3adc0fdd41e3 --- /dev/null +++ b/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/EntityManager.java @@ -0,0 +1,7 @@ +package jakarta.persistence; + +public interface EntityManager extends AutoCloseable { + + Query createNativeQuery(String sqlString); + +} diff --git a/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/Query.java b/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/Query.java new file mode 100644 index 000000000000..1bf5197b5c85 --- /dev/null +++ b/java/ql/test/stubs/jakarta-persistence-api-3.2.0/jakarta/persistence/Query.java @@ -0,0 +1,7 @@ +package jakarta.persistence; + +public interface Query { + + int executeUpdate(); + +} From 77e4d9e6920b01fb51d47177f0a061df17aa4d49 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 2 Apr 2025 10:03:49 +0100 Subject: [PATCH 7/7] Fix stray references to the javax package name Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- .../ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll index 1cb9af2e0d9a..b38cba889e00 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/Persistence.qll @@ -713,7 +713,7 @@ class VersionAnnotation extends Annotation { VersionAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Version") } } -/** The interface `javax.persistence.EntityManager`. */ +/** The interface `{javax,jakarta}.persistence.EntityManager`. */ class TypeEntityManager extends Interface { TypeEntityManager() { this.hasQualifiedName(getAPersistencePackageName(), "EntityManager") } @@ -736,7 +736,7 @@ class TypeEntityManager extends Interface { } } -/** The interface `javax.persistence.Query`, which represents queries in the Java Persistence Query Language. */ +/** The interface `{javax,jakarta}.persistence.Query`, which represents queries in the Java Persistence Query Language. */ class TypeQuery extends Interface { TypeQuery() { this.hasQualifiedName(getAPersistencePackageName(), "Query") }