[jboss-jira] [JBoss JIRA] (HIBERNATE-174) NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4

Victor Williams Stafusa da Silva (Jira) issues at jboss.org
Tue Apr 7 05:50:00 EDT 2020


     [ https://issues.redhat.com/browse/HIBERNATE-174?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Victor Williams Stafusa da Silva updated HIBERNATE-174:
-------------------------------------------------------
    Description: 
This code works fine in Hibernate 5.4.13.Final, but gives a NullPointerException at Hibernate 6.0.0.Alpha4:

Test file:

{code:title=Hbug.java|borderStyle=solid}
package com.example;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;

/**
 * @author Victor Williams Stafusa da Silva
 */
public class Hbug {

    public static void main(String[] args) throws Exception {
        Map<String, String> props = new HashMap<>();
        props.put("javax.persistence.jdbc.user", "sa");
        props.put("javax.persistence.jdbc.password", "");
        props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
        props.put("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
        props.put("javax.persistence.schema-generation.database.action", "drop-and-create");

        PersistenceProvider pp = new HibernatePersistenceProvider();
        var spui = new SimplePersistenceUnitInfo(
                Optional.empty(),
                HibernatePersistenceProvider.class,
                "test-1",
                Set.of(Fruit.class),
                props);
        var emf = pp.createContainerEntityManagerFactory(spui, props);
        if (!(emf instanceof SessionFactory)) throw new Exception("Bad EMF");
    }
}
{code}

Utilitary class used by the above one:

{code:title=SimplePersistenceUnitInfo.java|borderStyle=solid}
package com.example;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;

/**
 * @author Victor Williams Stafusa da Silva
 */
public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {

    private final Optional<URL> url;
    private final Class<? extends PersistenceProvider> providerClass;
    private final String persistenceUnitName;
    private final List<String> classes;
    private final Map<String, String> properties;

    public SimplePersistenceUnitInfo(
            /*@NonNull*/ Optional<URL> url,
            /*@NonNull*/ Class<? extends PersistenceProvider> providerClass,
            /*@NonNull*/ String persistenceUnitName,
            /*@NonNull*/ Collection<Class<?>> classes,
            /*@NonNull*/ Map<String, String> properties)
    {
        this.url = url;
        this.providerClass = providerClass;
        this.persistenceUnitName = persistenceUnitName;
        this.classes = classes.stream().map(Class::getName).collect(Collectors.toList());
        this.properties = new HashMap<>();
        this.properties.putAll(properties);
    }

    @Override
    public String getPersistenceUnitName() {
        return persistenceUnitName;
    }

    @Override
    public String getPersistenceProviderClassName() {
        return providerClass.getName();
    }

    @Override
    public PersistenceUnitTransactionType getTransactionType() {
        return PersistenceUnitTransactionType.RESOURCE_LOCAL;
    }

    @Override
    //@Nullable
    public DataSource getJtaDataSource() {
        return null;
    }

    @Override
    //@Nullable
    public DataSource getNonJtaDataSource() {
        return null;
    }

    @Override
    public List<String> getMappingFileNames() {
        return Collections.emptyList();
    }

    @Override
    public List<URL> getJarFileUrls() {
        try {
            return Collections.list(this.getClass().getClassLoader().getResources(""));
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    //@Nullable
    @Override
    public URL getPersistenceUnitRootUrl() {
        return url.orElse(null);
    }

    @Override
    public List<String> getManagedClassNames() {
        return Collections.unmodifiableList(classes);
    }

    @Override
    public boolean excludeUnlistedClasses() {
        return false;
    }

    @Override
    public SharedCacheMode getSharedCacheMode() {
        return SharedCacheMode.UNSPECIFIED;
    }

    @Override
    public ValidationMode getValidationMode() {
        return ValidationMode.AUTO;
    }

    @Override
    public Properties getProperties() {
        Properties p = new Properties();
        p.putAll(properties);
        return p;
    }

    @Override
    public String getPersistenceXMLSchemaVersion() {
        return "2.2";
    }

    @Override
    //@Nullable
    public ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    @Override
    public void addTransformer(ClassTransformer transformer) {
    }

    @Override
    //@Nullable
    public ClassLoader getNewTempClassLoader() {
        return null;
    }
}
{code}

Sample entity class:

{code:title=Fruit.java|borderStyle=solid}
package com.example;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author Victor Williams Stafusa da Silva
 */
@Entity
@Table(name = "fruits")
public class Fruit implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String color;

    public Fruit() {}

    public Fruit(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public String getColor() {
        return color;
    }
}
{code}

Gradle script to build that:

{code:title=build.gradle|borderStyle=solid}
apply plugin: 'java'
apply plugin: 'application'

group = 'com.example'

mainClassName = 'com.example.Hbug'

repositories {
    jcenter()
}

dependencies {
    implementation 'org.hsqldb:hsqldb:2.5.0'
    //implementation 'org.hibernate:hibernate-core:5.4.13.Final'
    implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
}
{code}

  was:
This code works fine in Hibernate 5.4.13.Final, but gives a NullPointerException at Hibernate 6.0.0.Alpha4:

Test file:

{code:title=Hbug.java|borderStyle=solid}
package com.example;

import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.PersistenceProviderImpl;
import org.eclipse.persistence.jpa.JpaEntityManagerFactory;
import org.hibernate.SessionFactory;
import org.hibernate.jpa.HibernatePersistenceProvider;

/**
 * @author Victor Williams Stafusa da Silva
 */
public class Hbug {

    public static void main(String[] args) {
        List.<TestSomething>of(Hbug::testHibernate, Hbug::testEclipselink, Hbug::testOpenJpa)
                .forEach(TestSomething::outer);
    }

    private interface TestSomething {
        public void inner() throws Exception;

        public default void outer() {
            try {
                inner();
                System.out.println("Ok");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static void testHibernate() throws Exception {
        Map<String, String> props = new HashMap<>();
        props.put("javax.persistence.jdbc.user", "sa");
        props.put("javax.persistence.jdbc.password", "");
        props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
        props.put("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
        props.put("javax.persistence.schema-generation.database.action", "drop-and-create");

        Set<Class<?>> entities = new HashSet<>();
        entities.add(Fruit.class);

        String pu = "test-1";

        javax.persistence.spi.PersistenceProvider pp = new HibernatePersistenceProvider();
        var spui = new SimplePersistenceUnitInfo(Optional.empty(), HibernatePersistenceProvider.class, pu, entities, props);
        var emf = pp.createContainerEntityManagerFactory(spui, props);
        if (!(emf instanceof SessionFactory)) throw new Exception("Bad EMF");
    }

    private static void testEclipselink() throws Exception {
        Map<String, String> props = new HashMap<>();
        props.put("javax.persistence.jdbc.user", "sa");
        props.put("javax.persistence.jdbc.password", "");
        props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
        props.put("javax.persistence.schema-generation.database.action", "drop-and-create");

        Set<Class<?>> entities = new HashSet<>();
        entities.add(Fruit.class);

        String pu = "test-1";

        javax.persistence.spi.PersistenceProvider pp = new org.eclipse.persistence.jpa.PersistenceProvider();
        var spui = new SimplePersistenceUnitInfo(Optional.of(new URL("http://0.0.0.0/")), pp.getClass(), pu, entities, props);
        var emf = pp.createContainerEntityManagerFactory(spui, props);
        if (!(emf instanceof JpaEntityManagerFactory)) throw new Exception("Bad EMF");
    }

    private static void testOpenJpa() throws Exception {
        Map<String, String> props = new HashMap<>();
        props.put("javax.persistence.jdbc.user", "sa");
        props.put("javax.persistence.jdbc.password", "");
        props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
        props.put("javax.persistence.jdbc.driver", "org.hsqldb.jdbc.JDBCDriver");
        props.put("javax.persistence.schema-generation.database.action", "drop-and-create");
        props.put("openjpa.DynamicEnhancementAgent", "true");
        props.put("openjpa.RuntimeUnenhancedClasses", "supported");

        Set<Class<?>> entities = new HashSet<>();
        entities.add(Fruit.class);

        String pu = "test-1";

        javax.persistence.spi.PersistenceProvider pp = new PersistenceProviderImpl();
        var spui = new SimplePersistenceUnitInfo(Optional.empty(), pp.getClass(), pu, entities, props);
        var emf = pp.createContainerEntityManagerFactory(spui, props);
        if (!(emf instanceof OpenJPAEntityManagerFactory)) throw new Exception("Bad EMF");
    }
}
{code}

Utilitary class used by the above one:

{code:title=SimplePersistenceUnitInfo.java|borderStyle=solid}
package com.example;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import javax.persistence.SharedCacheMode;
import javax.persistence.ValidationMode;
import javax.persistence.spi.ClassTransformer;
import javax.persistence.spi.PersistenceProvider;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;

/**
 * @author Victor Williams Stafusa da Silva
 */
public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {

    private final Optional<URL> url;
    private final Class<? extends PersistenceProvider> providerClass;
    private final String persistenceUnitName;
    private final List<String> classes;
    private final Map<String, String> properties;

    public SimplePersistenceUnitInfo(
            /*@NonNull*/ Optional<URL> url,
            /*@NonNull*/ Class<? extends PersistenceProvider> providerClass,
            /*@NonNull*/ String persistenceUnitName,
            /*@NonNull*/ Collection<Class<?>> classes,
            /*@NonNull*/ Map<String, String> properties)
    {
        this.url = url;
        this.providerClass = providerClass;
        this.persistenceUnitName = persistenceUnitName;
        this.classes = classes.stream().map(Class::getName).collect(Collectors.toList());
        this.properties = new HashMap<>();
        this.properties.putAll(properties);
    }

    @Override
    public String getPersistenceUnitName() {
        return persistenceUnitName;
    }

    @Override
    public String getPersistenceProviderClassName() {
        return providerClass.getName();
    }

    @Override
    public PersistenceUnitTransactionType getTransactionType() {
        return PersistenceUnitTransactionType.RESOURCE_LOCAL;
    }

    @Override
    //@Nullable
    public DataSource getJtaDataSource() {
        return null;
    }

    @Override
    //@Nullable
    public DataSource getNonJtaDataSource() {
        return null;
    }

    @Override
    public List<String> getMappingFileNames() {
        return Collections.emptyList();
    }

    @Override
    public List<URL> getJarFileUrls() {
        try {
            return Collections.list(this.getClass().getClassLoader().getResources(""));
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    //@Nullable
    @Override
    public URL getPersistenceUnitRootUrl() {
        return url.orElse(null);
    }

    @Override
    public List<String> getManagedClassNames() {
        return Collections.unmodifiableList(classes);
    }

    @Override
    public boolean excludeUnlistedClasses() {
        return false;
    }

    @Override
    public SharedCacheMode getSharedCacheMode() {
        return SharedCacheMode.UNSPECIFIED;
    }

    @Override
    public ValidationMode getValidationMode() {
        return ValidationMode.AUTO;
    }

    @Override
    public Properties getProperties() {
        Properties p = new Properties();
        p.putAll(properties);
        return p;
    }

    @Override
    public String getPersistenceXMLSchemaVersion() {
        return "2.2";
    }

    @Override
    //@Nullable
    public ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    @Override
    public void addTransformer(ClassTransformer transformer) {
    }

    @Override
    //@Nullable
    public ClassLoader getNewTempClassLoader() {
        return null;
    }
}
{code}

Sample entity class:

{code:title=Fruit.java|borderStyle=solid}
package com.example;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author Victor Williams Stafusa da Silva
 */
@Entity
@Table(name = "fruits")
public class Fruit implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String color;

    public Fruit() {}

    public Fruit(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public String getColor() {
        return color;
    }
}
{code}

Gradle script to build that:

{code:title=build.gradle|borderStyle=solid}
apply plugin: 'java'
apply plugin: 'application'

group = 'com.example'

mainClassName = 'com.example.Hbug'

repositories {
    jcenter()
}

dependencies {
    implementation 'org.hsqldb:hsqldb:2.5.0'
    //implementation 'org.hibernate:hibernate-core:5.4.13.Final'
    implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
}
{code}



> NullPointerException at org.hibernate.boot.archive.scan.spi.ClassFileArchiveEntryHandler.toClassDescriptor - Hibernate 6.0.0.Alpha4
> -----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HIBERNATE-174
>                 URL: https://issues.redhat.com/browse/HIBERNATE-174
>             Project: Hibernate Integration
>          Issue Type: Bug
>            Reporter: Victor Williams Stafusa da Silva
>            Assignee: Steve Ebersole
>            Priority: Critical
>
> This code works fine in Hibernate 5.4.13.Final, but gives a NullPointerException at Hibernate 6.0.0.Alpha4:
> Test file:
> {code:title=Hbug.java|borderStyle=solid}
> package com.example;
> import java.util.HashMap;
> import java.util.Map;
> import java.util.Optional;
> import java.util.Set;
> import javax.persistence.spi.PersistenceProvider;
> import org.hibernate.SessionFactory;
> import org.hibernate.jpa.HibernatePersistenceProvider;
> /**
>  * @author Victor Williams Stafusa da Silva
>  */
> public class Hbug {
>     public static void main(String[] args) throws Exception {
>         Map<String, String> props = new HashMap<>();
>         props.put("javax.persistence.jdbc.user", "sa");
>         props.put("javax.persistence.jdbc.password", "");
>         props.put("javax.persistence.jdbc.url", "jdbc:hsqldb:mem:test1");
>         props.put("hibernate.hbm2ddl.import_files_sql_extractor", "org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor");
>         props.put("javax.persistence.schema-generation.database.action", "drop-and-create");
>         PersistenceProvider pp = new HibernatePersistenceProvider();
>         var spui = new SimplePersistenceUnitInfo(
>                 Optional.empty(),
>                 HibernatePersistenceProvider.class,
>                 "test-1",
>                 Set.of(Fruit.class),
>                 props);
>         var emf = pp.createContainerEntityManagerFactory(spui, props);
>         if (!(emf instanceof SessionFactory)) throw new Exception("Bad EMF");
>     }
> }
> {code}
> Utilitary class used by the above one:
> {code:title=SimplePersistenceUnitInfo.java|borderStyle=solid}
> package com.example;
> import java.io.IOException;
> import java.io.UncheckedIOException;
> import java.net.URL;
> import java.util.Collection;
> import java.util.Collections;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
> import java.util.Optional;
> import java.util.Properties;
> import java.util.stream.Collectors;
> import javax.persistence.SharedCacheMode;
> import javax.persistence.ValidationMode;
> import javax.persistence.spi.ClassTransformer;
> import javax.persistence.spi.PersistenceProvider;
> import javax.persistence.spi.PersistenceUnitInfo;
> import javax.persistence.spi.PersistenceUnitTransactionType;
> import javax.sql.DataSource;
> /**
>  * @author Victor Williams Stafusa da Silva
>  */
> public final class SimplePersistenceUnitInfo implements PersistenceUnitInfo {
>     private final Optional<URL> url;
>     private final Class<? extends PersistenceProvider> providerClass;
>     private final String persistenceUnitName;
>     private final List<String> classes;
>     private final Map<String, String> properties;
>     public SimplePersistenceUnitInfo(
>             /*@NonNull*/ Optional<URL> url,
>             /*@NonNull*/ Class<? extends PersistenceProvider> providerClass,
>             /*@NonNull*/ String persistenceUnitName,
>             /*@NonNull*/ Collection<Class<?>> classes,
>             /*@NonNull*/ Map<String, String> properties)
>     {
>         this.url = url;
>         this.providerClass = providerClass;
>         this.persistenceUnitName = persistenceUnitName;
>         this.classes = classes.stream().map(Class::getName).collect(Collectors.toList());
>         this.properties = new HashMap<>();
>         this.properties.putAll(properties);
>     }
>     @Override
>     public String getPersistenceUnitName() {
>         return persistenceUnitName;
>     }
>     @Override
>     public String getPersistenceProviderClassName() {
>         return providerClass.getName();
>     }
>     @Override
>     public PersistenceUnitTransactionType getTransactionType() {
>         return PersistenceUnitTransactionType.RESOURCE_LOCAL;
>     }
>     @Override
>     //@Nullable
>     public DataSource getJtaDataSource() {
>         return null;
>     }
>     @Override
>     //@Nullable
>     public DataSource getNonJtaDataSource() {
>         return null;
>     }
>     @Override
>     public List<String> getMappingFileNames() {
>         return Collections.emptyList();
>     }
>     @Override
>     public List<URL> getJarFileUrls() {
>         try {
>             return Collections.list(this.getClass().getClassLoader().getResources(""));
>         } catch (IOException e) {
>             throw new UncheckedIOException(e);
>         }
>     }
>     //@Nullable
>     @Override
>     public URL getPersistenceUnitRootUrl() {
>         return url.orElse(null);
>     }
>     @Override
>     public List<String> getManagedClassNames() {
>         return Collections.unmodifiableList(classes);
>     }
>     @Override
>     public boolean excludeUnlistedClasses() {
>         return false;
>     }
>     @Override
>     public SharedCacheMode getSharedCacheMode() {
>         return SharedCacheMode.UNSPECIFIED;
>     }
>     @Override
>     public ValidationMode getValidationMode() {
>         return ValidationMode.AUTO;
>     }
>     @Override
>     public Properties getProperties() {
>         Properties p = new Properties();
>         p.putAll(properties);
>         return p;
>     }
>     @Override
>     public String getPersistenceXMLSchemaVersion() {
>         return "2.2";
>     }
>     @Override
>     //@Nullable
>     public ClassLoader getClassLoader() {
>         return Thread.currentThread().getContextClassLoader();
>     }
>     @Override
>     public void addTransformer(ClassTransformer transformer) {
>     }
>     @Override
>     //@Nullable
>     public ClassLoader getNewTempClassLoader() {
>         return null;
>     }
> }
> {code}
> Sample entity class:
> {code:title=Fruit.java|borderStyle=solid}
> package com.example;
> import java.io.Serializable;
> import javax.persistence.Entity;
> import javax.persistence.GeneratedValue;
> import javax.persistence.GenerationType;
> import javax.persistence.Id;
> import javax.persistence.Table;
> /**
>  * @author Victor Williams Stafusa da Silva
>  */
> @Entity
> @Table(name = "fruits")
> public class Fruit implements Serializable {
>     private static final long serialVersionUID = 1L;
>     @Id
>     @GeneratedValue(strategy = GenerationType.IDENTITY)
>     private Integer id;
>     private String name;
>     private String color;
>     public Fruit() {}
>     public Fruit(String name, String color) {
>         this.name = name;
>         this.color = color;
>     }
>     public String getName() {
>         return name;
>     }
>     public String getColor() {
>         return color;
>     }
> }
> {code}
> Gradle script to build that:
> {code:title=build.gradle|borderStyle=solid}
> apply plugin: 'java'
> apply plugin: 'application'
> group = 'com.example'
> mainClassName = 'com.example.Hbug'
> repositories {
>     jcenter()
> }
> dependencies {
>     implementation 'org.hsqldb:hsqldb:2.5.0'
>     //implementation 'org.hibernate:hibernate-core:5.4.13.Final'
>     implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha4'
> }
> {code}



--
This message was sent by Atlassian Jira
(v7.13.8#713008)


More information about the jboss-jira mailing list