Wildfly: How to call my code before deployment of war files

642 views Asked by At

I have 5 wars in my wildfly deployment directory. But before deployment of these war files i want to call some code which will have logic of jndi and database registration for these war files.

I have one approach in which i can create one war file having jndi and database register logic and then setting its deployment priority to 1, but due to some reasons i can not go with this approach.

Please suggest me the way to do it.

2

There are 2 answers

1
0190198 On

If you just want to create a jndi and database registration, you can directly create a jndi in wildfly itself and use that jndi in your application. So that you don't need to create a new WAR file.

To create a JNDI in wildfly, need to edit the standalone.xml file located in wildfly directory C:\wildfly\standalone\configuration\

Example:

<subsystem xmlns="urn:jboss:domain:datasources:2.0">
    <datasources>
        <datasource jndi-name="java:/jdbc/jndi-name" pool-name="jndi-name-Pool" enabled="true">
            <connection-url>jdbc:oracle:thin:@localhost:1521:orcl</connection-url>
            <driver>oracle</driver>
            <pool>
                <min-pool-size>10</min-pool-size>
                <max-pool-size>20</max-pool-size>
                <prefill>true</prefill>
            </pool>
            <security>
                <user-name>username</user-name>
                <password>password</password>
            </security>
        </datasource>
        <drivers>
            <driver name="oracle" module="com.oracle.ojdbc6"/>
        </drivers>
    </datasources>
</subsystem>
0
Marek Gregor On

There are several possibilities/levels depending on what you want to do:

1) Implement Servlet API ServletContextListener interface in your application.

@WebListener
public class AppInitContextListener implements ServletContextListener {

  @Override
  public void contextInitialized(ServletContextEvent event) {
    // Your code here 
  }

  @Override
  public void contextDestroyed(ServletContextEvent event) {
  }
}

2) Implement Servlet API ServletContainerInitializer interface in your application. This alternative allows programmatically adding another servlets, filters, etc. Then add the fully qualified name of your class to the special text file in your war archive:META-INF/services/javax.servlet.ServletContainerInitializer, in order to register your class to be called by container.

public class AppContainerInitializer implements ServletContainerInitializer {

  @Override
  void onStartup(Set<Class<?>> c, ServletContext ctx) {
    // Your code here 
  }      
}

3) Implement Wildfly (Undertow servlet engine) specific ServletExtension interface in your application. This alternative allows you to do 'down to the metal changes' in servlet engine. Then add the fully qualified name of your class to the special text file in your war archive:META-INF/services/io.undertow.servlet.ServletExtension, in order to register your class to be called by Undertow servlet container.

public class AppInitExtension implements ServletExtension {

  @Override
  public void handleDeployment(final DeploymentInfo deploymentInfo, final ServletContextImpl servletContext) {
    // Your code here 
  }      
}

4) For the sake of completeness, if you are using JPA, you could hook before deployment of JPA Entity manager this way (e.g. for performing database upgrade before deployment). Implement Hibernate specific Integrator interface in your application. Then add the fully qualified name of your class to the special text file in your war archive:META-INF/services/org.hibernate.integrator.spi.Integrator, in order to register your class to be called by Hibernate framework.

public class SchemaUpgradeIntegrator implements org.hibernate.integrator.spi.Integrator {

    @Override
    public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {
        // Starting DB migration
        final DataSource dataSource = (DataSource) sessionFactory.getProperties().get("hibernate.connection.datasource");
        // Your code here 
    }

    @Override
    public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) {
    }
}