Skip to content

Commit

Permalink
Fixing classpath issue when running from Maven
Browse files Browse the repository at this point in the history
  • Loading branch information
Derek Berner committed Aug 24, 2017
1 parent aaf754e commit 2831956
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.3</version>
<version>3.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,29 @@
import liquibase.ext.hibernate.database.connection.HibernateDriver;
import liquibase.logging.LogFactory;
import liquibase.logging.Logger;
import org.hibernate.annotations.common.reflection.ClassLoaderDelegate;
import org.hibernate.annotations.common.reflection.ClassLoadingException;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.internal.MetadataBuilderImpl;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataBuilderImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.service.ServiceRegistry;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicReference;

/**
* Base class for all Hibernate Databases. This extension interacts with Hibernate by creating standard liquibase.database.Database implementations that
Expand Down Expand Up @@ -132,7 +140,6 @@ protected final Metadata buildMetadata() throws DatabaseException {
}
}


return buildMetadataFromPath();
}

Expand All @@ -148,7 +155,23 @@ protected Metadata buildMetadataFromPath() throws DatabaseException {
MetadataBuilder metadataBuilder = sources.getMetadataBuilder();
configureMetadataBuilder(metadataBuilder);

return metadataBuilder.build();
AtomicReference<Throwable> thrownException = new AtomicReference<>();
AtomicReference<Metadata> result = new AtomicReference<>();

Thread t = new Thread(() -> result.set(metadataBuilder.build()));
t.setContextClassLoader(getHibernateConnection().getResourceAccessor().toClassLoader());
t.setUncaughtExceptionHandler((_t,e) -> thrownException.set(e));
t.start();
try {
t.join();
} catch (InterruptedException e) {
throw new DatabaseException(e);
}
Throwable thrown = thrownException.get();
if (thrown != null) {
throw new DatabaseException(thrown);
}
return result.get();
}


Expand Down Expand Up @@ -178,7 +201,6 @@ protected MetadataSources createMetadataSources() throws DatabaseException {
.build();

return new MetadataSources(standardRegistry);

}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.jpa.boot.spi.Bootstrap;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
import org.springframework.orm.jpa.persistenceunit.SmartPersistenceUnitInfo;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
Expand Down Expand Up @@ -67,6 +68,7 @@ protected boolean isXmlFile(DatabaseConnection connection) {

protected EntityManagerFactory createEntityManagerFactory() {
DefaultPersistenceUnitManager internalPersistenceUnitManager = new DefaultPersistenceUnitManager();
internalPersistenceUnitManager.setResourceLoader(new DefaultResourceLoader(getHibernateConnection().getResourceAccessor().toClassLoader()));

String[] packagesToScan = getHibernateConnection().getPath().split(",");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package liquibase.ext.hibernate.database.connection;

import liquibase.resource.ResourceAccessor;

import java.io.IOException;
import java.io.StringReader;
import java.net.URLDecoder;
Expand All @@ -17,15 +19,17 @@ public class HibernateConnection implements Connection {
private String url;

private String path;
private ResourceAccessor resourceAccessor;
private Properties properties;

public HibernateConnection(String url) {
public HibernateConnection(String url, ResourceAccessor resourceAccessor) {
this.url = url;

this.prefix = url.replaceFirst(":[^:]+$", "");

// Trim the prefix off the URL for the path
path = url.substring(prefix.length() + 1);
this.resourceAccessor = resourceAccessor;

// Check if there is a parameter/query string value.
properties = new Properties();
Expand Down Expand Up @@ -315,4 +319,8 @@ public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException {
//@Override only in java 1.7
public void setSchema(String arg0) throws SQLException {
}

public ResourceAccessor getResourceAccessor() {
return resourceAccessor;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package liquibase.ext.hibernate.database.connection;

import liquibase.database.LiquibaseExtDriver;
import liquibase.resource.ResourceAccessor;

import java.sql.*;
import java.util.Properties;
import java.util.logging.Logger;
Expand All @@ -8,10 +11,12 @@
* Implements the standard java.sql.Driver interface to allow the Hibernate integration to better fit into
* what Liquibase expects.
*/
public class HibernateDriver implements Driver {
public class HibernateDriver implements Driver, LiquibaseExtDriver {

private ResourceAccessor resourceAccessor;

public Connection connect(String url, Properties info) throws SQLException {
return new HibernateConnection(url);
return new HibernateConnection(url, resourceAccessor);
}

public boolean acceptsURL(String url) throws SQLException {
Expand All @@ -38,4 +43,9 @@ public boolean jdbcCompliant() {
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}

@Override
public void setResourceAccessor(ResourceAccessor accessor) {
this.resourceAccessor = accessor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void runGeneratedChangeLog() throws Exception {
Database hibernateDatabase = new HibernateClassicDatabase();
// hibernateDatabase.setDefaultSchemaName("PUBLIC");
// hibernateDatabase.setDefaultCatalogName("TESTDB");
hibernateDatabase.setConnection(new JdbcConnection(new HibernateConnection("hibernate:classic:" + HIBERNATE_CONFIG_FILE)));
hibernateDatabase.setConnection(new JdbcConnection(new HibernateConnection("hibernate:classic:" + HIBERNATE_CONFIG_FILE, new ClassLoaderResourceAccessor())));

DiffResult diffResult = liquibase.diff(hibernateDatabase, database, compareControl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void runGeneratedChangeLog() throws Exception {
Database hibernateDatabase = new HibernateSpringPackageDatabase();
hibernateDatabase.setDefaultSchemaName("PUBLIC");
hibernateDatabase.setDefaultCatalogName("TESTDB");
hibernateDatabase.setConnection(new JdbcConnection(new HibernateConnection("hibernate:spring:" + PACKAGES + "?dialect=" + HSQLDialect.class.getName())));
hibernateDatabase.setConnection(new JdbcConnection(new HibernateConnection("hibernate:spring:" + PACKAGES + "?dialect=" + HSQLDialect.class.getName(), new ClassLoaderResourceAccessor())));

DiffResult diffResult = liquibase.diff(hibernateDatabase, database, compareControl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import liquibase.exception.DatabaseException;
import liquibase.ext.hibernate.database.connection.HibernateConnection;
import liquibase.integration.commandline.CommandLineUtils;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.snapshot.DatabaseSnapshot;
import liquibase.snapshot.SnapshotControl;
import liquibase.snapshot.SnapshotGeneratorFactory;
Expand Down Expand Up @@ -35,7 +36,7 @@ public void tearDown() throws Exception {

@Test
public void testSpringUrlSimple() throws DatabaseException {
conn = new JdbcConnection(new HibernateConnection("hibernate:spring:spring.ctx.xml?bean=sessionFactory"));
conn = new JdbcConnection(new HibernateConnection("hibernate:spring:spring.ctx.xml?bean=sessionFactory", new ClassLoaderResourceAccessor()));
db = new HibernateSpringBeanDatabase();
db.setConnection(conn);
assertNotNull(db.getMetadata().getEntityBinding(AuctionItem.class.getName()));
Expand All @@ -45,7 +46,7 @@ public void testSpringUrlSimple() throws DatabaseException {

@Test
public void testSpringPackageScanningMustHaveItemClassMapping() throws DatabaseException {
conn = new JdbcConnection(new HibernateConnection("hibernate:spring:com.example.ejb3.auction?dialect=" + H2Dialect.class.getName()));
conn = new JdbcConnection(new HibernateConnection("hibernate:spring:com.example.ejb3.auction?dialect=" + H2Dialect.class.getName(), new ClassLoaderResourceAccessor()));
db = new HibernateSpringPackageDatabase();
db.setConnection(conn);
assertNotNull(db.getMetadata().getEntityBinding(Bid.class.getName()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package liquibase.ext.hibernate.database.connection;

import liquibase.resource.ClassLoaderResourceAccessor;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
Expand All @@ -23,15 +24,15 @@ public void tearDown() throws Exception {

@Test
public void testHibernateUrlSimple() {
HibernateConnection conn = new HibernateConnection("hibernate:classic:" + FILE_PATH);
HibernateConnection conn = new HibernateConnection("hibernate:classic:" + FILE_PATH, new ClassLoaderResourceAccessor());
Assert.assertEquals("hibernate:classic", conn.getPrefix());
assertEquals(FILE_PATH, conn.getPath());
assertEquals(0, conn.getProperties().size());
}

@Test
public void testHibernateUrlWithProperties() {
HibernateConnection conn = new HibernateConnection("hibernate:classic:" + FILE_PATH + "?foo=bar&name=John+Doe");
HibernateConnection conn = new HibernateConnection("hibernate:classic:" + FILE_PATH + "?foo=bar&name=John+Doe", new ClassLoaderResourceAccessor());
assertEquals("hibernate:classic", conn.getPrefix());
assertEquals(FILE_PATH, conn.getPath());
assertEquals(2, conn.getProperties().size());
Expand All @@ -41,15 +42,15 @@ public void testHibernateUrlWithProperties() {

@Test
public void testEjb3UrlSimple() {
HibernateConnection conn = new HibernateConnection("hibernate:ejb3:" + FILE_PATH);
HibernateConnection conn = new HibernateConnection("hibernate:ejb3:" + FILE_PATH, new ClassLoaderResourceAccessor());
assertEquals("hibernate:ejb3", conn.getPrefix());
assertEquals(FILE_PATH, conn.getPath());
assertEquals(0, conn.getProperties().size());
}

@Test
public void testEjb3UrlWithProperties() {
HibernateConnection conn = new HibernateConnection("hibernate:ejb3:" + FILE_PATH + "?foo=bar&name=John+Doe");
HibernateConnection conn = new HibernateConnection("hibernate:ejb3:" + FILE_PATH + "?foo=bar&name=John+Doe", new ClassLoaderResourceAccessor());
assertEquals("hibernate:ejb3", conn.getPrefix());
assertEquals(FILE_PATH, conn.getPath());
assertEquals(2, conn.getProperties().size());
Expand Down

0 comments on commit 2831956

Please sign in to comment.