Dear tomcat users
Before starting with a difficult problem, I want to tell about the current system / design. My company's server is a tomcat version 7.0.54. We are using Maven to setup the project and the deployment. The server is set as a 3-node tree, one "Base" and two branches A and B, each providing their own website and functionalities. If A and B shares same functionality on eg customer data, then the code can be found in "Base". By this, code is being reused and has improved maintenance. But A and B shares some functionalities that are almost similar except some additional features/tasks done when visiting a servlet. For that, CDI is introduced. We have enabled CDI by providing the required WELD plugin as a dependency in Base's pom.xml file (and ofc configured Beans.xml with classes that has "@Alternative annotation) <dependency> > <groupId>org.jboss.weld.servlet</groupId> > <artifactId>weld-servlet</artifactId> > </dependency> The CDI works fine if you visit a servlet page, it does the job. It works at the server where A operates and another server where B operates. The authentication of users is developed in Base, in a class that extends from DataSourceRealm (more specifially " org.apache.catalina.realm.DataSourceRealm " ) that returns a Principal instance. Now comes the question: We want to introduce some actions that happens right after the user is being authenticated. So, when an user logs in, a set of login-actions are executed to handle some tasks (a simple example is a login count. But we have more advanced actions) once the user is authenticated. So after authentication, a Principal is returned from the parent. If it's not null (= "user is authenticated"), then execute the actions. Then return the Principal instance. But the problem is ... the actions differs from A and B. So, using CDI is a logical solution here. However, when deploying and restarting to tomcat, we are getting HTTP 500 errors after authenticating users. The message is "javax/enterprise/context/spi/Contextual" (part of CDI implementation) cannot be found. It's from a .jar file, named as cdi-api-1.2. But it could not be found. Here below is the output on localhost java.lang.NoClassDefFoundError: javax/enterprise/context/spi/Contextual > > > com.base.core.security.BoaDataSourceRealm.authenticate(BaseDataSourceRealm.java:56) > > > org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:294) > > > org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:449) To figure out if tomcat is really loading this jar file, we have added "-verbose:class" in the JAVA_OPTS. One of the output is > [Loaded javax.enterprise.context.spi.Contextual from file:/C:/dev/ > bricsys.com/target/bricsys-1.0.01-development/WEB-INF/lib/cdi-api-1.2.jar] that means that the required class file should be found because the required Contextual class is inside the provided jar file. As mentioned, the CDI implementation works fine if you visit a servlet that uses CDI. Yet tomcat couldn't find it in the DataSourceRealm (which is a different container I think). Here below is a part of the Base pom.xml file where a jar file is provided to the datasourcerealm. Before authentication, we are also doing some actions which requires those class files. Both ILoginHandler and IActionHandler are part of the CDI implementation to run some tasks after the login <plugin> > <groupId>org.apache.maven.plugins</groupId> > <artifactId>maven-jar-plugin</artifactId> > <version>2.3.2</version> > <configuration> > <outputDirectory>../jars</outputDirectory> > </configuration> > <executions> > <execution> > <id>datasource</id> > <phase>package</phase> > <goals> > <goal>jar</goal> > </goals> > <configuration> > <archive> > <index>true</index> > <manifest> > > <addDefaultImplementationEntries>true</addDefaultImplementationEntries> > </manifest> > </archive> > <classifier>datasource</classifier> > <includes> > <include>com/base/core/security/*</include> > <include>com/base/core/Contact*</include> > <include>com/base/core/Queries*</include> > <include>com/base/core/conf/*Configuration*</include> > <include>com/base/core/conf/BeanHandler*</include> > <include>com/base/core/net/ServletListener*</include> > <include>com/base/core/contact_sql.properties</include> > <include>**/META-INF/beans.xml</include> > > <include>com/base/core/actionhandlers/handlers/ILoginHandler</include> > > <include>com/base/core/actionhandlers/actions/IAction</include> > </includes> > </configuration> > </execution> > </executions> > </plugin> When checking the datasource jar file, it contains the required files as defined here above. The problem is that the external jars aren't loaded in the DataSourceRealm while it is in tomcat's simple servlet realm. It's only during the authentication process that the CDI fails. What I have tried: Searching for a bottle in google's ocean. (I even read many of Bauke Scholtz's (AKA BalusC) blog posts and SO answers. Making the jar executable (why not?) by adding those two lines in the same pom.xml file <addClasspath>true</addClasspath> > <classpathPrefix>/WEB-INF/lib/</classpathPrefix> dropped the jars in tomcat's /lib folder. So ... does someone have implemented the same feature or even injected a third party library (most examples I've seen are database connectors).. I was just asking this myself when I wrote this mail: Is it possible to use CDI in tomcat's DataSourceRealm? How can I ensure that the external jars are being loaded in so that the CDI works when authenticating an user. Sincerely - KG