From a41233be3fa9de35e717d14fbdc30f8e95f7da86 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Tue, 25 Sep 2018 16:36:35 +1000 Subject: [PATCH] Add support for using Agroal Datasources in hibernate If persistence.xml does not have a connection URL defined then the Agroal datasource will be used instead. --- .../shamrock/deployment/RuntimePriority.java | 2 +- examples/strict/pom.xml | 5 - .../DatabaseManagerReplacement.java | 83 ------------- .../example/datasource/DatasourceSetup.java | 7 ++ .../datasource/HSQLDriverReplacement.java | 115 ------------------ .../main/resources/META-INF/persistence.xml | 3 - .../resources/META-INF/shamrock-build.yaml | 6 +- .../test/DataSourceTransactionITCase.java | 9 ++ .../test/DataSourceTransactionTestCase.java | 30 +++++ .../example/test/DatasourceTestCase.java | 43 ------- .../example/test/JPABootstrapTestCase.java | 1 - .../example/test/JPAReflectionTestCase.java | 33 ----- .../protean/impl/FastBootMetadataBuilder.java | 3 + .../impl/LightPersistenceXmlDescriptor.java | 3 - .../jpa/HibernateResourceProcessor.java | 2 +- .../jpa/runtime/JPADeploymentTemplate.java | 33 +++-- .../jboss/shamrock/junit/ShamrockTest.java | 17 ++- 17 files changed, 91 insertions(+), 304 deletions(-) delete mode 100644 examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatabaseManagerReplacement.java delete mode 100644 examples/strict/src/main/java/org/jboss/shamrock/example/datasource/HSQLDriverReplacement.java create mode 100644 examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionITCase.java create mode 100644 examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionTestCase.java delete mode 100644 examples/strict/src/test/java/org/jboss/shamrock/example/test/JPAReflectionTestCase.java diff --git a/core/deployment/src/main/java/org/jboss/shamrock/deployment/RuntimePriority.java b/core/deployment/src/main/java/org/jboss/shamrock/deployment/RuntimePriority.java index 6c291243048a25..8c363b98823204 100644 --- a/core/deployment/src/main/java/org/jboss/shamrock/deployment/RuntimePriority.java +++ b/core/deployment/src/main/java/org/jboss/shamrock/deployment/RuntimePriority.java @@ -8,7 +8,6 @@ public class RuntimePriority { public static final int UNDERTOW_CREATE_DEPLOYMENT = 100; - public static final int JPA_DEPLOYMENT = 150; public static final int UNDERTOW_REGISTER_SERVLET = 200; public static final int FAULT_TOLERANCE_DEPLOYMENT = 250; public static final int HEALTH_DEPLOYMENT = 260; @@ -16,6 +15,7 @@ public class RuntimePriority { public static final int JAXRS_DEPLOYMENT = 350; public static final int ARC_DEPLOYMENT = 300; public static final int UNDERTOW_DEPLOY = 400; + public static final int JPA_DEPLOYMENT = 500; public static final int BEAN_VALIDATION_DEPLOYMENT = 600; public static final int TRANSACTIONS_DEPLOYMENT = 700; public static final int DATASOURCE_DEPLOYMENT = 700; diff --git a/examples/strict/pom.xml b/examples/strict/pom.xml index d024f67a4f8d8c..437e167bf47e10 100644 --- a/examples/strict/pom.xml +++ b/examples/strict/pom.xml @@ -128,11 +128,6 @@ shamrock-graal test - - org.hsqldb - hsqldb - 2.4.0 - diff --git a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatabaseManagerReplacement.java b/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatabaseManagerReplacement.java deleted file mode 100644 index 65d92c4efa27a0..00000000000000 --- a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatabaseManagerReplacement.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.jboss.shamrock.example.datasource; - -import java.util.Vector; - -import org.hsqldb.Database; -import org.hsqldb.DatabaseManager; -import org.hsqldb.DatabaseType; -import org.hsqldb.Session; -import org.hsqldb.lib.Notified; -import org.hsqldb.persist.HsqlProperties; - -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; - -/** - * We don't want to suck all of HSQL into the native image, just the client driver - * this substitution means that only the client part of the jar will be included - */ -@TargetClass(DatabaseManager.class) -final class DatabaseManagerReplacement { - - @Substitute - public static Vector getDatabaseURIs() { - throw new RuntimeException(); - } - - @Substitute - public static void closeDatabases(int mode) { - throw new RuntimeException(); - } - - @Substitute - public static Session newSession(int dbID, String user, String password, - String zoneString, int timeZoneSeconds) { - throw new RuntimeException(); - } - - @Substitute - public static Session newSession(String type, String path, String user, - String password, HsqlProperties props, - String zoneString, int timeZoneSeconds) { - throw new RuntimeException(); - } - - @Substitute - public static Session getSession(int dbId, long sessionId) { - throw new RuntimeException(); - } - - @Substitute - public static int getDatabase(String type, String path, Notified server, - HsqlProperties props) { - throw new RuntimeException(); - } - - @Substitute - public static Database getDatabase(int id) { - throw new RuntimeException(); - } - - @Substitute - public static void shutdownDatabases(Notified server, int shutdownMode) { - throw new RuntimeException(); - } - - @Substitute - public static Database getDatabase(String dbtype, String path, - HsqlProperties props) { - throw new RuntimeException(); - } - - - @Substitute - public static synchronized Database lookupDatabaseObject(DatabaseType type, - String path) { - throw new RuntimeException(); - } - - @Substitute - public static void deRegisterServer(Notified server) { - throw new RuntimeException(); - } -} diff --git a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatasourceSetup.java b/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatasourceSetup.java index 792db088b61e61..f3b2863abc5ec5 100644 --- a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatasourceSetup.java +++ b/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/DatasourceSetup.java @@ -19,12 +19,19 @@ public void seetup() throws Exception { try (Connection con = dataSource.getConnection()) { try (Statement statement = con.createStatement()) { + try { + statement.execute("drop table a"); + statement.execute("drop table tx"); + } catch (Exception ignored) { + + } statement.execute("create table a (b int)"); statement.execute("create table tx (b int)"); } } } + public void doInit() { } diff --git a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/HSQLDriverReplacement.java b/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/HSQLDriverReplacement.java deleted file mode 100644 index e0b67e366b45ff..00000000000000 --- a/examples/strict/src/main/java/org/jboss/shamrock/example/datasource/HSQLDriverReplacement.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.jboss.shamrock.example.datasource; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -import org.hsqldb.DatabaseURL; -import org.hsqldb.error.ErrorCode; -import org.hsqldb.jdbc.JDBCConnection; -import org.hsqldb.jdbc.JDBCDriver; -import org.hsqldb.jdbc.JDBCUtil; -import org.hsqldb.persist.HsqlProperties; - -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; - -@TargetClass(JDBCDriver.class) -final class HSQLDriverReplacement { - - - @Substitute - public static Connection getConnection(String url, - Properties info) throws SQLException { - - final HsqlProperties props = DatabaseURL.parseURL(url, true, false); - - if (props == null) { - - // supposed to be an HSQLDB driver url but has errors - throw JDBCUtil.invalidArgument(); - } else if (props.isEmpty()) { - - // is not an HSQLDB driver url - return null; - } - - long timeout = 0; - - if (info != null) { - timeout = HsqlProperties.getIntegerProperty(info, "loginTimeout", 0); - } - - props.addProperties(info); - - if (timeout == 0) { - timeout = DriverManager.getLoginTimeout(); - } - - // @todo: maybe impose some sort of sane restriction - // on network connections regardless of user - // specification? - if (timeout == 0) { - - // no timeout restriction - return new JDBCConnection(props); - } - - String connType = props.getProperty("connection_type"); - - if (DatabaseURL.isInProcessDatabaseType(connType)) { - return new JDBCConnection(props); - } - - // @todo: Better: ThreadPool? HsqlTimer with callback? - final JDBCConnection[] conn = new JDBCConnection[1]; - final SQLException[] ex = new SQLException[1]; - Thread t = new Thread() { - - public void run() { - - try { - conn[0] = new JDBCConnection(props); - } catch (SQLException se) { - ex[0] = se; - } - } - }; - - t.start(); - - try { - t.join(1000 * timeout); - } catch (InterruptedException ie) { - } - - try { - - // PRE: - // deprecated, but should be ok, since neither - // the HSQLClientConnection or the HTTPClientConnection - // constructor will ever hold monitors on objects in - // an inconsistent state, such that damaged objects - // become visible to other threads with the - // potential of arbitrary behavior. - //t.stop(); - } catch (Exception e) { - } finally { - try { - t.setContextClassLoader(null); - } catch (Throwable th) { - } - } - - if (ex[0] != null) { - throw ex[0]; - } - - if (conn[0] != null) { - return conn[0]; - } - - throw JDBCUtil.sqlException(ErrorCode.X_08501); - } -} diff --git a/examples/strict/src/main/resources/META-INF/persistence.xml b/examples/strict/src/main/resources/META-INF/persistence.xml index c04f0ec1230c4a..45f4f67af762ee 100644 --- a/examples/strict/src/main/resources/META-INF/persistence.xml +++ b/examples/strict/src/main/resources/META-INF/persistence.xml @@ -16,9 +16,6 @@ - - - diff --git a/examples/strict/src/main/resources/META-INF/shamrock-build.yaml b/examples/strict/src/main/resources/META-INF/shamrock-build.yaml index cbdd188b5b0861..b47f3049bcf89c 100644 --- a/examples/strict/src/main/resources/META-INF/shamrock-build.yaml +++ b/examples/strict/src/main/resources/META-INF/shamrock-build.yaml @@ -1,3 +1,5 @@ datasource: - url: "jdbc:hsqldb:hsql://localhost:7676/test" - driver: "org.hsqldb.jdbc.JDBCDriver" \ No newline at end of file + url: ${postgres.url} + driver: "org.postgresql.Driver" + username: "hibernate_orm_test" + password: "hibernate_orm_test" \ No newline at end of file diff --git a/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionITCase.java b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionITCase.java new file mode 100644 index 00000000000000..b94d8e30e18808 --- /dev/null +++ b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionITCase.java @@ -0,0 +1,9 @@ +package org.jboss.shamrock.example.test; + +import org.jboss.shamrock.junit.GraalTest; +import org.junit.runner.RunWith; + +@RunWith(GraalTest.class) +public class DataSourceTransactionITCase extends DataSourceTransactionTestCase { + +} diff --git a/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionTestCase.java b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionTestCase.java new file mode 100644 index 00000000000000..c8e20ce5f5023f --- /dev/null +++ b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DataSourceTransactionTestCase.java @@ -0,0 +1,30 @@ +package org.jboss.shamrock.example.test; + +import org.jboss.shamrock.example.testutils.URLResponse; +import org.jboss.shamrock.example.testutils.URLTester; +import org.jboss.shamrock.junit.ShamrockTest; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(ShamrockTest.class) +public class DataSourceTransactionTestCase { + + @Test + public void testTransactionalAnnotation() { + //TODO: this does not really belong here, but it saves having to set all the DB stuff up again + + Assert.assertEquals("PASSED", URLTester.relative("rest/datasource/txninterceptor0").invokeURL().asString()); + + try { + URLResponse resp = URLTester.relative("rest/datasource/txninterceptor1").invokeURL(); + Assert.fail(resp.asString()); + } catch (RuntimeException expected) { + + } + Assert.assertEquals("PASSED", URLTester.relative("rest/datasource/txninterceptor2").invokeURL().asString()); + + + } + +} diff --git a/examples/strict/src/test/java/org/jboss/shamrock/example/test/DatasourceTestCase.java b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DatasourceTestCase.java index cf099fb3b52975..aed4f03f5d9768 100644 --- a/examples/strict/src/test/java/org/jboss/shamrock/example/test/DatasourceTestCase.java +++ b/examples/strict/src/test/java/org/jboss/shamrock/example/test/DatasourceTestCase.java @@ -1,40 +1,14 @@ package org.jboss.shamrock.example.test; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.hsqldb.Server; -import org.jboss.shamrock.example.testutils.URLResponse; import org.jboss.shamrock.example.testutils.URLTester; import org.jboss.shamrock.junit.ShamrockTest; -import org.junit.AfterClass; import org.junit.Assert; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(ShamrockTest.class) public class DatasourceTestCase { - static Server ws; - - @BeforeClass - public static void setup() throws Exception { - Path dir = Files.createTempDirectory("shamrock-test"); - ws = new Server(); - ws.setPort(7676); - ws.setAddress("localhost"); - ws.setDatabaseName(0, "test"); - ws.setDatabasePath(0, dir.toAbsolutePath().toString() + File.separator + "tempdb"); - ws.start(); - } - - @AfterClass - public static void tearDown() { - ws.stop(); - } @Test public void testDataSource() { @@ -46,21 +20,4 @@ public void testDataSourceTransactions() { Assert.assertEquals("PASSED", URLTester.relative("rest/datasource/txn").invokeURL().asString()); } - @Test - public void testTransactionalAnnotation() { - //TODO: this does not really belong here, but it saves having to set all the DB stuff up again - - Assert.assertEquals("PASSED", URLTester.relative("rest/datasource/txninterceptor0").invokeURL().asString()); - - try { - URLResponse resp = URLTester.relative("rest/datasource/txninterceptor1").invokeURL(); - Assert.fail(resp.asString()); - } catch (RuntimeException expected) { - - } - Assert.assertEquals("PASSED", URLTester.relative("rest/datasource/txninterceptor2").invokeURL().asString()); - - - } - } diff --git a/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPABootstrapTestCase.java b/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPABootstrapTestCase.java index 0573f8bfad26b3..bc682a61cdddb9 100644 --- a/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPABootstrapTestCase.java +++ b/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPABootstrapTestCase.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertEquals; import org.jboss.shamrock.example.testutils.URLTester; -import org.jboss.shamrock.junit.GraalTest; import org.jboss.shamrock.junit.ShamrockTest; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPAReflectionTestCase.java b/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPAReflectionTestCase.java deleted file mode 100644 index 7f645aa2774192..00000000000000 --- a/examples/strict/src/test/java/org/jboss/shamrock/example/test/JPAReflectionTestCase.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.jboss.shamrock.example.test; - -import static org.junit.Assert.assertEquals; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import org.jboss.shamrock.junit.ShamrockTest; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * Test reflection around JPA entities - * - * @author Emmanuel Bernard emmanuel@hibernate.org - */ -@RunWith(ShamrockTest.class) -public class JPAReflectionTestCase { - - @Test - public void testFieldAndGetterReflectionOnEntity() throws Exception { - Class custClass = Class.forName("org.jboss.shamrock.example.jpa.Customer"); - Object instance = custClass.newInstance(); - Field id = custClass.getDeclaredField("id"); - id.setAccessible(true); - assertEquals("id should be reachable and null", null, id.get(instance)); - Method setter = custClass.getDeclaredMethod("setName", String.class); - Method getter = custClass.getDeclaredMethod("getName"); - setter.invoke(instance, "Emmanuel"); - assertEquals("getter / setter should be reachable and usable", "Emmanuel", getter.invoke(instance)); - } - -} diff --git a/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/FastBootMetadataBuilder.java b/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/FastBootMetadataBuilder.java index 6f3d7e3fcb7261..da569fd6717fd8 100644 --- a/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/FastBootMetadataBuilder.java +++ b/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/FastBootMetadataBuilder.java @@ -170,6 +170,9 @@ private BootstrapServiceRegistry buildBootstrapServiceRegistry(ClassLoaderServic private MergedSettings mergeSettings(PersistenceUnitDescriptor persistenceUnit) { final MergedSettings mergedSettings = new MergedSettings(); + if(persistenceUnit.getJtaDataSource() != null) { + mergedSettings.configurationValues.put("hibernate.connection.datasource", persistenceUnit.getJtaDataSource()); + } // Protean specific! mergedSettings.configurationValues.put( "hibernate.temp.use_jdbc_metadata_defaults", "false" ); diff --git a/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/LightPersistenceXmlDescriptor.java b/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/LightPersistenceXmlDescriptor.java index 4af5e5e9ad1e4e..4ad21bd27de222 100644 --- a/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/LightPersistenceXmlDescriptor.java +++ b/ext/hibernate-protean/hibernate-orm-protean/src/main/java/org/hibernate/protean/impl/LightPersistenceXmlDescriptor.java @@ -40,9 +40,6 @@ private static void verifyIgnoredFields(final PersistenceUnitDescriptor toClone) if ( toClone.getNonJtaDataSource() != null ) { throw new UnsupportedOperationException( "Value found for #getNonJtaDataSource : not supported yet" ); } - if ( toClone.getJtaDataSource() != null ) { - throw new UnsupportedOperationException( "Value found for #getJtaDataSource : not supported yet" ); - } //This one needs to be ignored: // if ( toClone.getPersistenceUnitRootUrl() != null ) { // throw new UnsupportedOperationException( "Value found for #getPersistenceUnitRootUrl : not supported yet" ); diff --git a/jpa/deployment/src/main/java/org/jboss/shamrock/jpa/HibernateResourceProcessor.java b/jpa/deployment/src/main/java/org/jboss/shamrock/jpa/HibernateResourceProcessor.java index 7b74e574ca776a..f0a80263824796 100644 --- a/jpa/deployment/src/main/java/org/jboss/shamrock/jpa/HibernateResourceProcessor.java +++ b/jpa/deployment/src/main/java/org/jboss/shamrock/jpa/HibernateResourceProcessor.java @@ -54,7 +54,7 @@ public void process(final ArchiveContext archiveContext, final ProcessorContext try (BytecodeRecorder recorder = processorContext.addStaticInitTask(RuntimePriority.JPA_DEPLOYMENT)) { recorder.registerNonDefaultConstructor(ParsedPersistenceXmlDescriptor.class.getDeclaredConstructor(URL.class), (i) -> Collections.singletonList(i.getPersistenceUnitRootUrl())); - recorder.getRecordingProxy(JPADeploymentTemplate.class).initMetadata(descriptors, scanner); + recorder.getRecordingProxy(JPADeploymentTemplate.class).initMetadata(descriptors, scanner, null); } diff --git a/jpa/runtime/src/main/java/org/jboss/shamrock/jpa/runtime/JPADeploymentTemplate.java b/jpa/runtime/src/main/java/org/jboss/shamrock/jpa/runtime/JPADeploymentTemplate.java index 70223ac1e1eae9..7bb6dddf452290 100644 --- a/jpa/runtime/src/main/java/org/jboss/shamrock/jpa/runtime/JPADeploymentTemplate.java +++ b/jpa/runtime/src/main/java/org/jboss/shamrock/jpa/runtime/JPADeploymentTemplate.java @@ -1,5 +1,13 @@ package org.jboss.shamrock.jpa.runtime; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.util.AnnotationLiteral; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + import org.hibernate.boot.archive.scan.spi.Scanner; import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor; import org.hibernate.protean.Hibernate; @@ -8,19 +16,14 @@ import org.jboss.shamrock.runtime.BeanContainer; import org.jboss.shamrock.runtime.ContextObject; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; - -import javax.enterprise.util.AnnotationLiteral; -import javax.persistence.EntityManagerFactory; - /** * @author Emmanuel Bernard emmanuel@hibernate.org */ public class JPADeploymentTemplate { private List entities = new ArrayList<>(); + private static final String CONNECTION_URL = "hibernate.connection.url"; + public void addEntity(String entityClass) { entities.add(entityClass); } @@ -35,7 +38,7 @@ public void callHibernateFeatureInit() { public void boostrapPu(@ContextObject("bean.container") BeanContainer beanContainer, boolean synthetic) { //TODO: we need to take qualifiers into account, at the moment we can only have one EM, but this is probably fine for the PoC - if(synthetic) { + if (synthetic) { beanContainer.instance(EntityManagerFactory.class, new AnnotationLiteral() { @Override @@ -48,7 +51,19 @@ public Class annotationType() { } } - public void initMetadata(List parsedPersistenceXmlDescriptors, Scanner scanner) { + public void initMetadata(List parsedPersistenceXmlDescriptors, Scanner scanner, @ContextObject("bean.container") BeanContainer beanContainer) { + + if (beanContainer != null) { + BeanContainer.Factory ds = beanContainer.instanceFactory(DataSource.class); + if (ds != null) { + DataSource dataSource = ds.get(); + for (ParsedPersistenceXmlDescriptor i : parsedPersistenceXmlDescriptors) { + if (!i.getProperties().containsKey(CONNECTION_URL)) { + i.setJtaDataSource(dataSource); + } + } + } + } PersistenceUnitsHolder.initializeJpa(parsedPersistenceXmlDescriptors, scanner); } diff --git a/test-framework/junit/src/main/java/org/jboss/shamrock/junit/ShamrockTest.java b/test-framework/junit/src/main/java/org/jboss/shamrock/junit/ShamrockTest.java index 06f846b70409cf..bb29d49e3cf24c 100644 --- a/test-framework/junit/src/main/java/org/jboss/shamrock/junit/ShamrockTest.java +++ b/test-framework/junit/src/main/java/org/jboss/shamrock/junit/ShamrockTest.java @@ -11,6 +11,7 @@ import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; public class ShamrockTest extends BlockJUnit4ClassRunner { @@ -31,11 +32,21 @@ public ShamrockTest(Class klass) throws InitializationError { @Override public void run(final RunNotifier notifier) { - runInternal(notifier); super.run(notifier); } + + + @Override + protected void runChild(final FrameworkMethod method, RunNotifier notifier) { + if(!failed) { + super.runChild(method, notifier); + } else { + notifier.fireTestIgnored(describeChild(method)); + } + } + private void runInternal(RunNotifier notifier) { if (first) { first = false; @@ -46,10 +57,6 @@ private void runInternal(RunNotifier notifier) { @Override public void testStarted(Description description) { - if (failed) { - notifier.fireTestFailure(new Failure(description, new AssertionError("Startup failed"))); - return; - } if (!started) { started = true; //TODO: so much hacks...