diff --git a/cdi-portable-extension/flyway-cdi/pom.xml b/cdi-portable-extension/flyway-cdi/pom.xml
new file mode 100644
index 0000000000..9fb781aaab
--- /dev/null
+++ b/cdi-portable-extension/flyway-cdi/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+ flyway-cdi
+
+
+ com.baeldung
+ cdi-portable-extension
+ 1.0-SNAPSHOT
+
+
+
+
+ javax.enterprise
+ cdi-api
+ 2.0.SP1
+
+
+ org.flywaydb
+ flyway-core
+ 5.1.4
+
+
+ org.apache.tomcat
+ tomcat-jdbc
+ 8.5.33
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+
+
diff --git a/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java
new file mode 100644
index 0000000000..a5019b82c1
--- /dev/null
+++ b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java
@@ -0,0 +1,74 @@
+package com.baeldung.cdi.extension;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.flywaydb.core.Flyway;
+
+import javax.annotation.sql.DataSourceDefinition;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.literal.InjectLiteral;
+import javax.enterprise.inject.spi.*;
+import javax.enterprise.util.AnnotationLiteral;
+
+
+/**
+ * Flyway is now under CDI container like:
+ *
+ * @ApplicationScoped
+ * @FlywayType public class Flyway{
+ * @Inject setDataSource(DataSource dataSource){
+ * //...
+ * }
+ * }
+ */
+
+public class FlywayExtension implements Extension {
+
+ DataSourceDefinition dataSourceDefinition = null;
+
+ public void registerFlywayType(@Observes BeforeBeanDiscovery bbdEvent) {
+ bbdEvent.addAnnotatedType(Flyway.class, Flyway.class.getName());
+ }
+
+ public void detectDataSourceDefinition(@Observes @WithAnnotations(DataSourceDefinition.class) ProcessAnnotatedType> patEvent) {
+ AnnotatedType at = patEvent.getAnnotatedType();
+ dataSourceDefinition = at.getAnnotation(DataSourceDefinition.class);
+ }
+
+ public void processAnnotatedType(@Observes ProcessAnnotatedType patEvent) {
+ patEvent.configureAnnotatedType()
+ //Add Scope
+ .add(ApplicationScoped.Literal.INSTANCE)
+ //Add Qualifier
+ .add(new AnnotationLiteral() {
+ })
+ //Decorate setDataSource(DataSource dataSource){} with @Inject
+ .filterMethods(annotatedMethod -> {
+ return annotatedMethod.getParameters().size() == 1 &&
+ annotatedMethod.getParameters().get(0).getBaseType().equals(javax.sql.DataSource.class);
+ })
+ .findFirst().get().add(InjectLiteral.INSTANCE);
+ }
+
+ void afterBeanDiscovery(@Observes AfterBeanDiscovery abdEvent, BeanManager bm) {
+ abdEvent.addBean()
+ .types(javax.sql.DataSource.class, DataSource.class)
+ .qualifiers(new AnnotationLiteral() {}, new AnnotationLiteral() {})
+ .scope(ApplicationScoped.class)
+ .name(DataSource.class.getName())
+ .beanClass(DataSource.class)
+ .createWith(creationalContext -> {
+ DataSource instance = new DataSource();
+ instance.setUrl(dataSourceDefinition.url());
+ instance.setDriverClassName(dataSourceDefinition.className());
+ return instance;
+ });
+ }
+
+ void runFlywayMigration(@Observes AfterDeploymentValidation adv, BeanManager manager) {
+ Flyway flyway = manager.createInstance().select(Flyway.class, new AnnotationLiteral() {}).get();
+ flyway.migrate();
+ }
+}
diff --git a/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java
new file mode 100644
index 0000000000..7c3a5affa6
--- /dev/null
+++ b/cdi-portable-extension/flyway-cdi/src/main/java/com/baeldung/cdi/extension/FlywayType.java
@@ -0,0 +1,14 @@
+package com.baeldung.cdi.extension;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({FIELD, METHOD, PARAMETER, TYPE})
+@Qualifier
+public @interface FlywayType {
+}
\ No newline at end of file
diff --git a/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000000..44959bfa99
--- /dev/null
+++ b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000000..a82dc47714
--- /dev/null
+++ b/cdi-portable-extension/flyway-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,2 @@
+com.baeldung.cdi.extension.FlywayExtension
+
diff --git a/cdi-portable-extension/main-app/pom.xml b/cdi-portable-extension/main-app/pom.xml
new file mode 100644
index 0000000000..fab9b8bf07
--- /dev/null
+++ b/cdi-portable-extension/main-app/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ main-app
+ jar
+
+
+ com.baeldung
+ cdi-portable-extension
+ 1.0-SNAPSHOT
+
+
+
+
+
+ javax.enterprise
+ cdi-api
+ 2.0.SP1
+
+
+ org.jboss.weld.se
+ weld-se-core
+ 3.0.5.Final
+ runtime
+
+
+
+ com.baeldung
+ flyway-cdi
+ 1.0-SNAPSHOT
+ runtime
+
+
+
+ com.h2database
+ h2
+ 1.4.197
+ runtime
+
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+
+
+
\ No newline at end of file
diff --git a/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java b/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java
new file mode 100644
index 0000000000..1f6c5b43ba
--- /dev/null
+++ b/cdi-portable-extension/main-app/src/main/java/com/baeldung/cdi/extension/MainApp.java
@@ -0,0 +1,16 @@
+package com.baeldung.cdi.extension;
+
+import javax.annotation.sql.DataSourceDefinition;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.se.SeContainer;
+import javax.enterprise.inject.se.SeContainerInitializer;
+
+@ApplicationScoped
+@DataSourceDefinition(name = "ds", className = "org.h2.Driver", url = "jdbc:h2:mem:testdb")
+public class MainApp {
+ public static void main(String[] args) {
+ SeContainerInitializer initializer = SeContainerInitializer.newInstance();
+ try (SeContainer container = initializer.initialize()) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml b/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000000..44959bfa99
--- /dev/null
+++ b/cdi-portable-extension/main-app/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql b/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql
new file mode 100644
index 0000000000..6bddc7689e
--- /dev/null
+++ b/cdi-portable-extension/main-app/src/main/resources/db/migration/V1__Create_person_table.sql
@@ -0,0 +1,4 @@
+create table PERSON (
+ ID int not null,
+ NAME varchar(100) not null
+);
diff --git a/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql b/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql
new file mode 100644
index 0000000000..d8f1d62667
--- /dev/null
+++ b/cdi-portable-extension/main-app/src/main/resources/db/migration/V2__Add_people.sql
@@ -0,0 +1,3 @@
+insert into PERSON (ID, NAME) values (1, 'Axel');
+insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
+insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
diff --git a/cdi-portable-extension/pom.xml b/cdi-portable-extension/pom.xml
new file mode 100644
index 0000000000..66913de84d
--- /dev/null
+++ b/cdi-portable-extension/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ cdi-portable-extension
+ 1.0-SNAPSHOT
+ pom
+
+
+ 1.8
+ 1.8
+
+
+
+ main-app
+ flyway-cdi
+
+
+
+
+ javax.enterprise
+ cdi-api
+ 2.0.SP1
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 8f6ef4e983..0195397d6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -604,6 +604,7 @@
spring-reactive-kotlin
jnosql
spring-boot-angular-ecommerce
+ cdi-portable-extension
jta
java-websocket