3

I am using Spring Boot 2.7.2 to create a rest API that communicate with Filenet Content Engine using Filenet APIs and my pom file as follows :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.test</groupId>
    <artifactId>storage</artifactId>
    <version>0.0.1</version>
    <name>storage</name>
    <description>Storage API</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.6.9</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Filenet Jars -->

        <dependency>
            <groupId>Jace</groupId>
            <artifactId>Jace</artifactId>
            <version>5.2.1</version>
        </dependency>

        <dependency>
            <groupId>stax-api</groupId>
            <artifactId>stax-api</artifactId>
            <version>5.2.1</version>
        </dependency>

        <dependency>
            <groupId>xlxpScanner</groupId>
            <artifactId>xlxpScanner</artifactId>
            <version>5.2.1</version>
        </dependency>

        <dependency>
            <groupId>xlxpScannerUtils</groupId>
            <artifactId>xlxpScannerUtils</artifactId>
            <version>5.2.1</version>
        </dependency>

        <!-- End Of Filenet Jars -->

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

        <!--
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        -->

    </dependencies>

    <build>

        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>

        <repository>
            <id>MCI-maven</id>
            <url>http://myhost/repository/maven-public/</url>
        </repository>

    </repositories>

</project>

The project compiles and starts up fine, but when trying to execute any filenet API I get a log4j error:

ClassNotFoundException: org.apache.log4j.Priority

That is because filenet APIs is using log4j1 classes.

The class is : com.filenet.apiimpl.util.BaseLogger.

The class imports are:

import com.filenet.api.exception.EngineRuntimeException;
import com.filenet.api.exception.ErrorLoggingLevel;
import com.filenet.api.util.UserContext;
import com.filenet.apiimpl.exception.ExceptionContext;
import java.util.Enumeration;
import org.apache.log4j.Category;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

The current solution is to add log4j 1.2.17 in pom file

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

When adding this the runtime exception disappears and everything works fine. But I only get the following warning on first time invoking filenet API:

log4j:WARN No appenders could be found for logger (filenet_error.api.com.filenet.apiimpl.util.ConfigValueLookup).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
[Perf Log] perflog.dir=null not found, auditor disabled 
[Perf Log] No interval found. Auditor disabled.

Is there any better solution to this scenario rather than adding old log4j dependency ?

halfer
  • 19,824
  • 17
  • 99
  • 186
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498
  • Well the fact that you include log4j but try to configure Logback, should be an indication on **why**., You are using framework X while you cofigure framework Y... – M. Deinum May 23 '22 at 09:32
  • @M. Deinum , I have an old 3rd party library that requires log4j to be present on classpath – Mahmoud Saleh May 23 '22 at 10:09
  • No you don't... You only need the log4j to slf4j bridge... You don't need log4j. – M. Deinum May 23 '22 at 10:57
  • @M. Deinum If i remove log4j jars and only use log4j-to-slf4j my 3rd party library throw runtime exception class not found : org.apache.log4j.Priority which exists in log4j api jar – Mahmoud Saleh May 24 '22 at 07:52
  • The dependencies you included are for log4j2 which isn't log4j... Also you shouldn't need to add dependencies as all the bridges are included by default by Spring Boot (afaik). So your dependency management ism aking things worse (as you are trying to outsmart, log4j, log4j2 and logback and spring dependency management). Nonetheless what is your 3rd party using Log4j (probably as it is old) or Log4j2, then include the proper bridge (or just ditch all those dependencies and just use the normal ones already provided. – M. Deinum May 24 '22 at 07:56
  • @M. Deinum Can you please advise what library I should use instead of the above that will contain : org.apache.log4j.Priority class and compatible with logback ? – Mahmoud Saleh May 31 '22 at 10:08
  • I already gave you the answer... The problem is your dependencies and the fact that you are trying to mix log4j, log4j2 and logback. Spring Boot by default routes **everything** to logback. SO as answered before remove all the dependencies and use the defaults. – M. Deinum May 31 '22 at 10:12
  • I edited my question so that you can better understand my issue, I need a class on runtime which only exists in log4j jar so If I removed the dependencies I get runtime exception class not found ! – Mahmoud Saleh May 31 '22 at 10:17
  • I understand your issue quite well. And the answer still stands you are trying to outsmart the dependency management of Spring Boot which already provides that. Basically there should be no logging related dependencies in your `pom.xml`. – M. Deinum May 31 '22 at 10:19
  • Ok I followed your suggestion and removed all the above dependencies and I got runtime exception class not found (org.apache.log4j.Priority) when using the filenet jar so spring itself didn't help here ! how to make this exception goes away in this case ? – Mahmoud Saleh May 31 '22 at 10:22
  • You have not specified *what* jar needs logback. This might help. Also you are using 2 different log4j versions while also using logback, this can't be intended – SirHawrk May 31 '22 at 10:54
  • The filenet jar requires (org.apache.log4j.Priority) from log4j not logback and I am using log4j1 bridge that route to log4j2 to avoid security issues in log4j1, I guess it's better that I remove logback and go with log4j only – Mahmoud Saleh May 31 '22 at 10:57
  • You should not have anything logging related in there, you clearly state in each comment that, while using logback, you are trying to route log4j logging through log4j2. So you ahve those dependencies... You should have no, nothing, zero dependencies for logging. If that doesn't work something else is pulling in those dependencies and you need to add some exclusions. – M. Deinum May 31 '22 at 11:44
  • M. Deinum I just rewrote the question content to make the issue more clear – Mahmoud Saleh Aug 18 '22 at 12:40
  • @MahmoudSaleh can you check this page for configuration. https://www.ibm.com/support/pages/updates-log4j-1x-ibm-content-navigator-deployments – muhammed ozbilici Aug 24 '22 at 20:31

2 Answers2

2

According to your actual pom.xml file, following the transitive dependencies spring-boot-starter-web and spring-boot-starter, you will end using spring-boot-starter-logging and its different dependent libraries, mainly based on logback and slf4j.

As you indicated, the Filenet APIs use Log4j 1.x.

The support for that version of Log4j was removed with the release of Spring Boot 2.x.

As a consequence, by default, the library will not give you support for that logging library.

That is the reason why you are facing the ClassNotFoundException: org.apache.log4j.Priority error.

In my opinion the solution you applied based on the inclusion of the log4j dependency itself is not a bad solution. A word of caution though:

As an alternative, you could use the Log4j 1.x bridge provided by Slf4j:

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
</dependency>

You can use the version 1.7.36 although it is managed by Spring Boot Starter Parent as well, so you don't need to provide a specific version for it.

Maybe there can be some caveats, some functionally used by the Filenet logger not implemented, but at first glance it seems to provide all the required stuff used by com.filenet.apiimpl.util.BaseLogger.

If that's the case, it will give you a better solution than using the log4j library, for the reasons explained, especially because it will allow you to integrate the Filenet loggers with your existing Spring Boot logging configuration and infrastructure.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
1

Adding the following dependencies fixed my problem:

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-logging', version: '2.7.1'
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.1'
implementation group: 'org.slf4j', name: 'log4j-over-slf4j', version: '1.7.36'
DJC
  • 11
  • 1