0

So I am trying to build a web application when a common jar needs to be shared between all web apps. So I built the pom.xml and put the JAR in the Tomcat/lib folder. Its dependency section looks like this (the artifact ID of this is web-common):

<dependencies>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-application-configuration-files</artifactId>
        <version>${project.version}</version>
        <type>jar</type>
    </dependency>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-exceptions</artifactId>
        <version>${project.version}</version>
        <type>jar</type>
    </dependency>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-schema-files-jaxb</artifactId>
        <version>${project.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/sshtools/j2ssh-core -->
    <dependency>
        <groupId>sshtools</groupId>
        <artifactId>j2ssh-core</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jasypt/jasypt -->
    <dependency>
        <groupId>org.jasypt</groupId>
        <artifactId>jasypt</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax/javaee-api -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.opengis.cite.saxon/saxon9 -->
    <dependency>
        <groupId>org.opengis.cite.saxon</groupId>
        <artifactId>saxon9</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.oracle/ucp -->
    <dependency>
        <groupId>com.oracle.jdbc</groupId>
        <artifactId>ucp</artifactId>
    </dependency>

</dependencies>

Now the dependency section of my WAR file (artifact ID: access-controller) is something like this:

<dependencies>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-common</artifactId>
        <version>${project.version}</version>
        <type>jar</type>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-application-configuration-files</artifactId>
        <version>${project.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-exceptions</artifactId>
        <version>${project.version}</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.web.myapp</groupId>
        <artifactId>web-schema-files-jaxb</artifactId>
        <version>${project.version}</version>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
    <dependency>
        <groupId>commons-net</groupId>
        <artifactId>commons-net</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jasypt/jasypt -->
    <dependency>
        <groupId>org.jasypt</groupId>
        <artifactId>jasypt</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax/javaee-api -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.python/jython -->
    <dependency>
        <groupId>org.python</groupId>
        <artifactId>jython</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.oracle/ojdbc6 -->
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.oracle/ucp -->
    <dependency>
        <groupId>com.oracle.jdbc</groupId>
        <artifactId>ucp</artifactId>
        <scope>provided</scope>
    </dependency>

</dependencies>

Both of these are linked via a parent project.

Now when I deploy the WAR on Tomcat. While running the application, it starts throwing all sorts of errors NoClassDefFoundError, ClassNotFoundError to LinkageError, and everything under the sun of classes going haywire. Mostly it complains that it was not able to find classes from the dependencies I included. I can see all of them in the WAR's lib folder and entries in the MANIFEST file as well. First I started with the default scope (compile), but since it starts throwing exceptions I had to make all the dependencies provided and put them in the Tomcat/lib folder as well just to get it to work.

I think I must be doing something wrong, or is it the right way to go about it and is normal? I thought I read Maven well and good but it looks like there is a gap in my understanding somewhere.

Yash Rathod
  • 141
  • 1
  • 7
hell_storm2004
  • 1,401
  • 2
  • 33
  • 66
  • The reason you are tripping up is because what you are doing is going against Maven's framework for including dependencies. Maven wants you to include dependencies via your `pom.xml` file, but you are doing something else. One possible fix here would be to publish your local JAR to your Maven repo, and then include it via `pom.xml`. See [How to add local jar files to a Maven project?](https://stackoverflow.com/questions/4955635/how-to-add-local-jar-files-to-a-maven-project) for more information. – Tim Biegeleisen Nov 27 '19 at 12:44
  • Why would you have two pom files? Just one for your app and the provided dependcies on classpath (of the server if you like) – jediz Nov 27 '19 at 12:49
  • @TimBiegeleisen I know how to install the JAR to my local repo (learned it while dealing with oracle jars :) ). But not sure how that will help. But just wanted to know doesn't `mvn clean install` do something similar? – hell_storm2004 Nov 27 '19 at 12:56
  • `and put the JAR in the Tomcat/lib folder`... do you realize that this is _not_ the same as installing the JAR to your local repo? – Tim Biegeleisen Nov 27 '19 at 12:57
  • @TimBiegeleisen Okay, so let me get this straight: 1. I install the web-common artifact JAR using `mvn install:install-file`. 2. Put the JAR in the Tomcat/lib. 3. Keep the web-common dependency in the WAR's pom with scope `provided`. 4. And change the scope of all other dependencies. – hell_storm2004 Nov 27 '19 at 13:05
  • **NO**. Do not put the JAR anywhere. Just install the JAR locally via Maven and then include that dependency in your `pom.xml` as you would any other dependency. – Tim Biegeleisen Nov 27 '19 at 13:06
  • Okay. I am giving this a try. But I am a little on the ropes, if all WAR use the web-common as dependency from its own classpath, wont objects created by one WAR file be different from objects created by another WAR and not necessarily reflect the changes in variable values at runtime? – hell_storm2004 Nov 27 '19 at 13:48
  • @hell_storm2004 Do you have many web-apps deployed on one tomcat setver and one common jar for all of them? And you want to share some static java objects or singletons, defined in common jar, between all web applications on server, correct? – user1516873 Nov 27 '19 at 14:01
  • @user1516873 Yes, that is the idea! – hell_storm2004 Nov 27 '19 at 14:11
  • in general it is not recommended practice, it makes your application not scalable at all, and you will be unable to use hot deploy. Consider to create one big application instead, with one classloader and all classes in WEB-INF/classes and WEB-INF/lib and do not put any common jar in Tomcat/lib – user1516873 Nov 27 '19 at 14:36
  • @user1516873 It would have been great if we could do it that way. You see the application was on WebSphere earlier where it was deployed as an EAR. Now that migration is to Tomcat, there is no other option other than breaking them down to individual WAR files and deploying, unless time is provided to break down the application and restructure is totally. Alas, that is not the case. I argued for WildFly. But no one listened. I can see myself this is getting out of hand. But I have to stick with it. – hell_storm2004 Nov 28 '19 at 13:44
  • I see, in that case try to set up delegate=true in Loader https://tomcat.apache.org/tomcat-8.0-doc/config/loader.html it will change class loading order. Also always restart tomcat when you make any changes and try to avoid different versions of classes and libs in dependencies. But i do not recomend this approach if there is any chance to avoid it. – user1516873 Nov 29 '19 at 07:31

0 Answers0