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. diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll index 48cfd945375a..2dcbb96f3b59 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll @@ -161,10 +161,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 e60659426e56..b38cba889e00 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,11 @@ import java +/** + * Gets a JavaEE Persistence API package name. + */ +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,13 +32,13 @@ 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" } /** - * 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() { @@ -44,617 +49,673 @@ 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("javax.persistence", "Access") } + AccessAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Access") } } /** - * A `@javax.persistence.AccessType` annotation. + * A `@{javax,jakarta}.persistence.AccessType` annotation. */ class AccessTypeAnnotation extends Annotation { - AccessTypeAnnotation() { this.getType().hasQualifiedName("javax.persistence", "AccessType") } + AccessTypeAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "AccessType") + } } /** - * A `@javax.persistence.AssociationOverride` annotation. + * A `@{javax,jakarta}.persistence.AssociationOverride` annotation. */ class AssociationOverrideAnnotation extends Annotation { AssociationOverrideAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AssociationOverride") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AssociationOverride") } } /** - * A `@javax.persistence.AssociationOverrides` annotation. + * A `@{javax,jakarta}.persistence.AssociationOverrides` annotation. */ class AssociationOverridesAnnotation extends Annotation { AssociationOverridesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AssociationOverrides") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AssociationOverrides") } } /** - * A `@javax.persistence.AttributeOverride` annotation. + * A `@{javax,jakarta}.persistence.AttributeOverride` annotation. */ class AttributeOverrideAnnotation extends Annotation { AttributeOverrideAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AttributeOverride") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AttributeOverride") } } /** - * A `@javax.persistence.AttributeOverrides` annotation. + * A `@{javax,jakarta}.persistence.AttributeOverrides` annotation. */ class AttributeOverridesAnnotation extends Annotation { AttributeOverridesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "AttributeOverrides") + this.getType().hasQualifiedName(getAPersistencePackageName(), "AttributeOverrides") } } /** - * A `@javax.persistence.Basic` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.Cacheable` annotation. */ class CacheableAnnotation extends Annotation { - CacheableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Cacheable") } + CacheableAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Cacheable") + } } /** - * A `@javax.persistence.CollectionTable` annotation. + * A `@{javax,jakarta}.persistence.CollectionTable` annotation. */ class CollectionTableAnnotation extends Annotation { CollectionTableAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "CollectionTable") + this.getType().hasQualifiedName(getAPersistencePackageName(), "CollectionTable") } } /** - * A `@javax.persistence.Column` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.ColumnResult` annotation. */ class ColumnResultAnnotation extends Annotation { - ColumnResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ColumnResult") } + ColumnResultAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "ColumnResult") + } } /** - * A `@javax.persistence.DiscriminatorColumn` annotation. + * A `@{javax,jakarta}.persistence.DiscriminatorColumn` annotation. */ class DiscriminatorColumnAnnotation extends Annotation { DiscriminatorColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "DiscriminatorColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "DiscriminatorColumn") } } /** - * A `@javax.persistence.DiscriminatorValue` annotation. + * A `@{javax,jakarta}.persistence.DiscriminatorValue` annotation. */ class DiscriminatorValueAnnotation extends Annotation { DiscriminatorValueAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "DiscriminatorValue") + this.getType().hasQualifiedName(getAPersistencePackageName(), "DiscriminatorValue") } } /** - * A `@javax.persistence.ElementCollection` annotation. + * A `@{javax,jakarta}.persistence.ElementCollection` annotation. */ class ElementCollectionAnnotation extends Annotation { ElementCollectionAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ElementCollection") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ElementCollection") } } /** - * A `@javax.persistence.Embeddable` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.Entity` annotation. */ class EntityAnnotation extends Annotation { - EntityAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Entity") } + EntityAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Entity") } } /** - * A `@javax.persistence.EntityListeners` annotation. + * A `@{javax,jakarta}.persistence.EntityListeners` annotation. */ class EntityListenersAnnotation extends Annotation { EntityListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "EntityListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "EntityListeners") } } /** - * A `@javax.persistence.EntityResult` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.Enumerated` annotation. */ class EnumeratedAnnotation extends Annotation { - EnumeratedAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Enumerated") } + EnumeratedAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Enumerated") + } } /** - * A `@javax.persistence.ExcludeDefaultListeners` annotation. + * A `@{javax,jakarta}.persistence.ExcludeDefaultListeners` annotation. */ class ExcludeDefaultListenersAnnotation extends Annotation { ExcludeDefaultListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ExcludeDefaultListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ExcludeDefaultListeners") } } /** - * A `@javax.persistence.ExcludeSuperclassListeners` annotation. + * A `@{javax,jakarta}.persistence.ExcludeSuperclassListeners` annotation. */ class ExcludeSuperclassListenersAnnotation extends Annotation { ExcludeSuperclassListenersAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "ExcludeSuperclassListeners") + this.getType().hasQualifiedName(getAPersistencePackageName(), "ExcludeSuperclassListeners") } } /** - * A `@javax.persistence.FieldResult` annotation. + * A `@{javax,jakarta}.persistence.FieldResult` annotation. */ class FieldResultAnnotation extends Annotation { - FieldResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "FieldResult") } + FieldResultAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "FieldResult") + } } /** - * A `@javax.persistence.GeneratedValue` annotation. + * A `@{javax,jakarta}.persistence.GeneratedValue` annotation. */ class GeneratedValueAnnotation extends Annotation { GeneratedValueAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "GeneratedValue") + this.getType().hasQualifiedName(getAPersistencePackageName(), "GeneratedValue") } } /** - * A `@javax.persistence.Id` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.MapKeyColumn` annotation. */ class MapKeyColumnAnnotation extends Annotation { - MapKeyColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKeyColumn") } + MapKeyColumnAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyColumn") + } } /** - * A `@javax.persistence.MapKeyEnumerated` annotation. + * A `@{javax,jakarta}.persistence.MapKeyEnumerated` annotation. */ class MapKeyEnumeratedAnnotation extends Annotation { MapKeyEnumeratedAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyEnumerated") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyEnumerated") } } /** - * A `@javax.persistence.MapKeyJoinColumn` annotation. + * A `@{javax,jakarta}.persistence.MapKeyJoinColumn` annotation. */ class MapKeyJoinColumnAnnotation extends Annotation { MapKeyJoinColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyJoinColumn") } } /** - * A `@javax.persistence.MapKeyJoinColumns` annotation. + * A `@{javax,jakarta}.persistence.MapKeyJoinColumns` annotation. */ class MapKeyJoinColumnsAnnotation extends Annotation { MapKeyJoinColumnsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumns") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyJoinColumns") } } /** - * A `@javax.persistence.MapKeyTemporal` annotation. + * A `@{javax,jakarta}.persistence.MapKeyTemporal` annotation. */ class MapKeyTemporalAnnotation extends Annotation { MapKeyTemporalAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MapKeyTemporal") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MapKeyTemporal") } } /** - * A `@javax.persistence.MappedSuperclass` annotation. + * A `@{javax,jakarta}.persistence.MappedSuperclass` annotation. */ class MappedSuperclassAnnotation extends Annotation { MappedSuperclassAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "MappedSuperclass") + this.getType().hasQualifiedName(getAPersistencePackageName(), "MappedSuperclass") } } /** - * A `@javax.persistence.MapsId` annotation. + * A `@{javax,jakarta}.persistence.MapsId` annotation. */ class MapsIdAnnotation extends Annotation { - MapsIdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapsId") } + MapsIdAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "MapsId") } } /** - * A `@javax.persistence.NamedNativeQueries` annotation. + * A `@{javax,jakarta}.persistence.NamedNativeQueries` annotation. */ class NamedNativeQueriesAnnotation extends Annotation { NamedNativeQueriesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "NamedNativeQueries") + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedNativeQueries") } } /** - * A `@javax.persistence.NamedNativeQuery` annotation. + * A `@{javax,jakarta}.persistence.NamedNativeQuery` annotation. */ class NamedNativeQueryAnnotation extends Annotation { NamedNativeQueryAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "NamedNativeQuery") + this.getType().hasQualifiedName(getAPersistencePackageName(), "NamedNativeQuery") } } /** - * A `@javax.persistence.NamedQueries` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.OrderColumn` annotation. */ class OrderColumnAnnotation extends Annotation { - OrderColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OrderColumn") } + OrderColumnAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "OrderColumn") + } } /** - * A `@javax.persistence.PersistenceContext` annotation. + * A `@{javax,jakarta}.persistence.PersistenceContext` annotation. */ class PersistenceContextAnnotation extends Annotation { PersistenceContextAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceContext") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceContext") } } /** - * A `@javax.persistence.PersistenceContexts` annotation. + * A `@{javax,jakarta}.persistence.PersistenceContexts` annotation. */ class PersistenceContextsAnnotation extends Annotation { PersistenceContextsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceContexts") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceContexts") } } /** - * A `@javax.persistence.PersistenceProperty` annotation. + * A `@{javax,jakarta}.persistence.PersistenceProperty` annotation. */ class PersistencePropertyAnnotation extends Annotation { PersistencePropertyAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceProperty") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceProperty") } } /** - * A `@javax.persistence.PersistenceUnit` annotation. + * A `@{javax,jakarta}.persistence.PersistenceUnit` annotation. */ class PersistenceUnitAnnotation extends Annotation { PersistenceUnitAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceUnit") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceUnit") } } /** - * A `@javax.persistence.PersistenceUnits` annotation. + * A `@{javax,jakarta}.persistence.PersistenceUnits` annotation. */ class PersistenceUnitsAnnotation extends Annotation { PersistenceUnitsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PersistenceUnits") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PersistenceUnits") } } /** - * A `@javax.persistence.PostLoad` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.PreUpdate` annotation. */ class PreUpdateAnnotation extends Annotation { - PreUpdateAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PreUpdate") } + PreUpdateAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "PreUpdate") + } } /** - * A `@javax.persistence.PrimaryKeyJoinColumn` annotation. + * A `@{javax,jakarta}.persistence.PrimaryKeyJoinColumn` annotation. */ class PrimaryKeyJoinColumnAnnotation extends Annotation { PrimaryKeyJoinColumnAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumn") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PrimaryKeyJoinColumn") } } /** - * A `@javax.persistence.PrimaryKeyJoinColumns` annotation. + * A `@{javax,jakarta}.persistence.PrimaryKeyJoinColumns` annotation. */ class PrimaryKeyJoinColumnsAnnotation extends Annotation { PrimaryKeyJoinColumnsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumns") + this.getType().hasQualifiedName(getAPersistencePackageName(), "PrimaryKeyJoinColumns") } } /** - * A `@javax.persistence.QueryHint` annotation. + * A `@{javax,jakarta}.persistence.QueryHint` annotation. */ class QueryHintAnnotation extends Annotation { - QueryHintAnnotation() { this.getType().hasQualifiedName("javax.persistence", "QueryHint") } + QueryHintAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "QueryHint") + } } /** - * A `@javax.persistence.SecondaryTable` annotation. + * A `@{javax,jakarta}.persistence.SecondaryTable` annotation. */ class SecondaryTableAnnotation extends Annotation { SecondaryTableAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SecondaryTable") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SecondaryTable") } } /** - * A `@javax.persistence.SecondaryTables` annotation. + * A `@{javax,jakarta}.persistence.SecondaryTables` annotation. */ class SecondaryTablesAnnotation extends Annotation { SecondaryTablesAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SecondaryTables") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SecondaryTables") } } /** - * A `@javax.persistence.SequenceGenerator` annotation. + * A `@{javax,jakarta}.persistence.SequenceGenerator` annotation. */ class SequenceGeneratorAnnotation extends Annotation { SequenceGeneratorAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SequenceGenerator") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SequenceGenerator") } } /** - * A `@javax.persistence.SqlResultSetMapping` annotation. + * A `@{javax,jakarta}.persistence.SqlResultSetMapping` annotation. */ class SqlResultSetMappingAnnotation extends Annotation { SqlResultSetMappingAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMapping") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SqlResultSetMapping") } } /** - * A `@javax.persistence.SqlResultSetMappings` annotation. + * A `@{javax,jakarta}.persistence.SqlResultSetMappings` annotation. */ class SqlResultSetMappingsAnnotation extends Annotation { SqlResultSetMappingsAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMappings") + this.getType().hasQualifiedName(getAPersistencePackageName(), "SqlResultSetMappings") } } /** - * A `@javax.persistence.Table` annotation. + * A `@{javax,jakarta}.persistence.Table` annotation. */ class TableAnnotation extends Annotation { - TableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Table") } + TableAnnotation() { this.getType().hasQualifiedName(getAPersistencePackageName(), "Table") } } /** - * A `@javax.persistence.TableGenerator` annotation. + * A `@{javax,jakarta}.persistence.TableGenerator` annotation. */ class TableGeneratorAnnotation extends Annotation { TableGeneratorAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "TableGenerator") + this.getType().hasQualifiedName(getAPersistencePackageName(), "TableGenerator") } } /** - * A `@javax.persistence.Temporal` annotation. + * A `@{javax,jakarta}.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. + * A `@{javax,jakarta}.persistence.Transient` annotation. */ class TransientAnnotation extends Annotation { - TransientAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Transient") } + TransientAnnotation() { + this.getType().hasQualifiedName(getAPersistencePackageName(), "Transient") + } } /** - * A `@javax.persistence.UniqueConstraint` annotation. + * A `@{javax,jakarta}.persistence.UniqueConstraint` annotation. */ class UniqueConstraintAnnotation extends Annotation { UniqueConstraintAnnotation() { - this.getType().hasQualifiedName("javax.persistence", "UniqueConstraint") + this.getType().hasQualifiedName(getAPersistencePackageName(), "UniqueConstraint") } } /** - * A `@javax.persistence.Version` annotation. + * A `@{javax,jakarta}.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`. */ +/** The interface `{javax,jakarta}.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() { @@ -675,9 +736,9 @@ 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("javax.persistence", "Query") } + TypeQuery() { this.hasQualifiedName(getAPersistencePackageName(), "Query") } /** Gets a method named `setParameter` declared in the `Query` interface. */ Method getASetParameterMethod() { 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(); + +}