Log4J Error: “log4j:WARN No appenders could be found for logger”

I recently got these errors when working on a Java web app:

[ERROR] log4j:WARN No appenders could be found for logger (org.apache.cxf.common.logging.LogUtils).
[ERROR] log4j:WARN Please initialize the log4j system properly.

My issue was that my project utilized Log4J2 and a dependency in my pom.xml utilized Log4J. To find which dependency is to blame, comb through the output of the mvn dependency:tree command.

There are a few solutions that could be utilized including changing the dependency to Log4J2, adding a log4j.properties file to the project outputting error messages, or adding a log4j.properties file to the dependency. Adding a log4j.properties file to the dependency made most sense in my case; I didn’t want every project that refers to the dependency to have to define and populate a log4j.properties file. We will go over adding a log4j.properties file to the dependency itself.

Navigate to the resources directory of the offending dependency and create an empty file named log4j.properties. Populating this file with any valid configuration should get rid of the appender error. Remember, this artifact must be published and then referred to the original project.

That’s it! Your error should be fixed!

tl;dr
Navigate to dependency that utilizes log4j and define and populate a log4j.properties file in the resources directory.

SLF4J Error: SLF4J: Class path contains multiple SLF4J bindings.

Recently, I received these errors when working on a Java web app:

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
[ERROR] SLF4J: Found binding in [jar:file:{userDirectory}/WEB-INF/lib/log4j-slf4j-impl-2.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
[ERROR] SLF4J: Found binding in [jar:file:{userDirectory}/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.2/log4j-slf4j-impl-2.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
[ERROR] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
[ERROR] SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]

The offending dependency is the log4j-slf4j-impl dependency. Here’s what this dependency looks like in my pom.xml:

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j-impl</artifactId>
	<version>{my_version_number}</version>
</dependency>

This error simply means that there are two jars that are binding to SLF4J. The solution is trivial. You must make it so that only one jar can bind with SLF4J.

To fix this, change the scope tag in your pom.xml to provided. This will require that the server that this app runs on provide this dependency. Here’s how we do this:

<dependency>
	<groupId>org.apache.logging.log4j</groupId>
	<artifactId>log4j-slf4j-impl</artifactId>
	<version>{my_version_number}</version>
	<!-- This scope tag prevents multiple bindings. It requires the server to provide the dependency at runtime. -->
	<scope>provided</scope>
</dependency>

Now, rerun your app and you shouldn’t see those errors anymore.

This isn’t necessarily the ideal solution because now we have a dependency that isn’t managed Maven. In some cases, changing the scope tag to provided is the only solution that works.

Another solution is to use the mvn dependency:tree command to comb through your dependencies to see if a dependency is pulling in a log4j-slf4j-impl jar. If so, utilize maven’s excludes tag to exclude the log4j-slf4j-impl from the associated dependency. I personally didn’t use this solution so I am not going to go into more detail but googling “maven exclude tags” should give you a place to start; I don’t want to give out information that I haven’t personally tested.

So, remember, the problem is you have two log4j-slf4j-impl jars on your classpath. You need to make it so that only one log4j-slf4j-impl jar is on your classpath.

Spring Boot: Configuration Transforms

Coming from a .NET background, I was looking to emulate configuration transforms. I found some tutorials online but they weren’t totally complete. In this tutorial, we will be creating configuration files for a development tier and a production tier.

First create a new Spring Boot project. You will notice that an application.properties file was automatically created. For learning purposes, append the following:

test.constant=development_constant

Now create a new file in the same directory as your application.properties file named application-production.properties. Append the same key with the “production” value:

test.constant=production_constant

The next step is to create a way to inject these constants into our app. First create the interface:

public interface MyAppConfiguration {
      String getTestConstant();
}

Then create the implementation:

@Component
public class MyAppConfigurationImpl implements MyAppConfiguration {
    @Value("${test.constant}")
    private String testConstant;

    @Override
    public String getTestConstant() {
        return testConstant;
    }
}

We have everything setup to run the app in different configuration modes. After generating a fat jar, we can start the Spring Boot app in different configurations via the command line:

java -jar {jar_file_name}.jar # Run jar in development mode.
java -jar -Dspring.config.name=application-production {jar_file_name}.jar # Run jar in production mode. 
nohup java -jar -Dspring.config.name=application-production {jar_file_name}.jar & # Run jar in production mode in background. Requires linux. 

I am an Intellij user. Sometimes I want to start the application in a different configuration mode in Intellij. The easiest way to do this is to go to “Run > Edit Configurations > Override parameters”. In the “Name” column, enter “spring.config.name” and then enter the chosen configuration file name in the “Value” column. Here is a sample image which demonstrates this concept:

Intellij Spring Boot Configuration Example

Evidently, it is incredibly easy to create different configurations per tier. This is not exactly how .NET configuration transforms work but it is close enough.

Spring Boot: Sending Emails

The ability to send emails is an integral part of any web application. Sometimes emails need to be sent for order confirmation. Another use case is to notify a development team when certain error conditions are met. Either way, sending emails are important.

To do this with Spring Boot, we must first have the correct dependencies. We will use Maven for this tutorial. Navigate to your pom.xml and add these dependencies:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>

With Linux, we could install sendmail but we will use gmail’s SMTP server for simplicity. We must first append the following info to our application.properties file:

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username={gmail_user_name}
spring.mail.password={gmail_password}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

Now we must create our interface for dependency injection:

public interface EmailService {
    void send(String from, String to, String title, String body);
}

The next step is to create the implementation:

@Service
public class EmailServiceImpl implements EmailService {
    private JavaMailSender javaMailSender;

    @Autowired
    public EmailServiceImpl(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    @Override
    public void send(String from, String to, String title, String body) {
        MimeMessage message = this.javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message);
        try {
            if (from != null) {
                mimeMessageHelper.setFrom(from);
            }
            mimeMessageHelper.setSubject(title);
            mimeMessageHelper.setText(body);
            mimeMessageHelper.setTo(to);
            this.javaMailSender.send(message);
        } catch (MessagingException messageException) {
            // You could also 'throw' this exception. I am not a fan of checked exceptions. 
            // If you want to go that route, then just update this method and the interface. 
            throw new RuntimeException(messageException);
        }
    }
}

Finally, we are setup for emailing. Now you can use this service to send emails!

How to Call a Stored Procedure with Spring Boot Using JPA/Hibernate

Working with legacy data is hard. Using an ORM with legacy data is even harder. I was recently creating a REST API in the context of a legacy database. I originally tried to generate Hibernate entities but came to the conclusion that the legacy data was too messy for the ORM to be effective. Many other tutorials demonstrate on how to call stored procedures. The main issue I ran into is that these tutorials show you how to call stored procedures and “auto-map” them to Hibernate entities. Automatically mapping them to hibernate objects didn’t work for my application. This may have been because my database schema was very old.

First create your repository interface:

public interface LegacyDataAccessRepository {
	List<MyObject> getSomeLegacyData(String firstParameter);
}

Now create the implementation of the repository:

@Repository
public class LegacyDataAccessRepositoryImpl implements LegacyDataAccessRepository {
	@PersistenceContext
	private EntityManager entityManager;

	@Override
	pubilc List<MyObject> getSomeLegacyData(String firstParameter){
	   StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery("StoredProcName");
	   
	   // Set the parameters of the stored procedure.
	   String firstParam = "firstParam";
	   storedProcedure.registerStoredProcedureParameter(firstParam, String.class, ParameterMode.IN);
	   storedProcedure.setParameter(firstParam, firstParameter);

	   // Call the stored procedure. 
	   List<Object[]> storedProcedureResults = storedProcedure.getResultList();

	   // Use Java 8's cool new functional programming paradigm to map the objects from the stored procedure results
	   return storedProcedureResults.stream().map(result -> new MyObject(
	         (Integer) result[0],
	         (String) result[1]
	   )).collect(Collectors.toList());

	}
}

As we can see, calling stored procedures in Spring Boot is easy. This implementation is not specific to Spring Boot or Hibernate. This will work with any framework which implements the JPA specification. The only thing that would change would be obtaining the EntityManager object.

Spring Boot: Forwarding Port 8080 to 80 and LetsEncrypt SSL

I have seen many articles on utilizing Spring Boot with port forwarding and SSL certificates. None of these articles seem complete. Recently, I have had to deploy a Spring Boot app into production. I could not find good reference material for what I was trying to accomplish. I needed the app to be usable on port 80 with SSL enabled using LetsEncrypt as the certificate authority. In Linux, any port under 1024 has special privileges. There are two main options. The first is to use iptables to redirect port 80 traffic to the port that the Java web app is running on, usually port 8080. This option lacks SSL capabilities. The second option is to use a proxy, usually Apache or Nginx.

Iptables

If you don’t need SSL capabilities, iptables is the easiest and most simple option:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 # Port 80 traffic will be directed to port 8080

The main drawback of this approach is that iptables cannot redirect to HTTPS only sites. If you need to remove this, then just enter these simple commands in your terminal:

iptables -t nat --line-numbers -L # List rules
iptables -t nat -D PREROUTING {num} # Remove rule. Replace {num} with the number from the command above.

Apache

Using Apache or Nginx is the most flexible option. Configuration is much more onerous than using iptables. In this tutorial, we will be using Apache on Ubuntu.

  1. First install Apache and enable modules:
             sudo apt-get install apache2
             sudo a2enmod proxy
             sudo a2enmod proxy_http

2. Navigate to configuration directory:

cd /etc/apache2/sites-available

3. Now you will need to modify the 000-default.conf file adding these lines under the "VirtualHost" brackets:

ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

4. Restart Apache:

sudo service apache2 restart

Now port 80 should be serving traffic through port 8080. If the app doesn’t use SSL, feel free to stop reading here. Make sure everything is working before continuing. The next step is enabling SSL.

To create the LetsEncrypt SSL certificate, we must first ensure that we are inside the terminal on the production server. This will not work on your local machine. Here are the steps to produce the certificate:

wget https://dl.eff.org/certbot-auto # Download client to server
chmod a+x certbot-auto # Make executable
./certbot-auto # Install dependencies to server
./cerbot-auto certonly -a standalone -d {domainName} -d {secondDomainName} # Create certificate (on Debian derivatives it will create the certificates at "/etc/letsencrypt/live/{domainName}"

Now we must navigate into the directory that LetsEncrypt generated:

sudo su # Need root to see files
cd /etc/letsencrypt/live/{domainName}

Finally, we can see the contents that LetsEncrypt created:

cert.pem  chain.pem  fullchain.pem  privkey.pem

Our next step is to create keys that are compatible with Spring Boot. To create a keystore for Spring Boot:

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root

Now move the key somewhere readable to your Spring Boot application and then append the following attributes to the application-properties:

security.require-ssl=true
server.ssl.key-store={key_store_location}
server.ssl.key-store-password={key_store_password}
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat

Now we need to modify Apache configuration file again. To make all HTTP requests redirect to HTTPS, append this to the top of the config file:

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Next we need to ensure that we can proxy to port 8080 with SSL, we need to add the SSLCertificateKeyFile, SSLCertificateChainFile, and SSLCertificateFile. Your final config file should look something like this:

# Making all web requests HTTPS
 
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}


	ServerAdmin webmaster@localhost # Replace this if you want.
	ServerName {domain}
       
      

	SSLEngine on
	SSLProxyEngine On
	SSLProtocol All -SSLv2 -SSLv3 # Disable SSL versions with POODLE vulnerability

	SSLCertificateKeyFile /etc/letsencrypt/live/{domain}/privkey.pem
	SSLCertificateChainFile /etc/letsencrypt/live/{domain}/chain.pem
	SSLCertificateFile /etc/letsencrypt/live/{domain}/fullchain.pem


	
	ProxyRequests Off
	ProxyPreserveHost On
	ProxyPass / https://localhost:8080/
	ProxyPassReverse / https://localhost:8080/


	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

Now restart Apache:

 sudo service apache2 restart

Finally, we have HTTPS traffic which proxies traffic from port 80 to 8080. I think this process is very onerous just to get SSL running for a Spring Boot app. Hopefully, Spring Boot will have a “no configuration” solution soon.

References:

Is Java Pass By Value or Pass By Reference?

Pass value. This concept in Java is a little confusing because you can modify members of arguments. This example illustrates the pass value behavior:

public class Main {

    public static void doesNotChangeValueAfterFunction(Integer integer){
        integer = 10;
    }
    public static void main(String[] args) {
        Integer twenty = 20;

        doesNotChangeValueAfterFunction(twenty);

        System.out.println(twenty);

    }
}

The output of this program is “20” because “integer” is passed value. This example illustrates a pseudo pass reference behavior:

public class Main {

    static class IntegerWrapper{
        Integer integer;
    }

    public static void valueIsAlteredAfterFunctionCall(IntegerWrapper integerWrapper){
        integerWrapper.integer = 100;
    }
    public static void main(String[] args) {
        IntegerWrapper twentyWrapper = new IntegerWrapper();
        twentyWrapper.integer = 20;

        valueIsAlteredAfterFunctionCall(twentyWrapper);

        System.out.println(twentyWrapper.integer);

    }
}

The output of this program is “100” because we are modifying the
“integer” instance variable and not the actual method argument. This
is still pass value behavior but is confusing. When one hears pass value,
they think that object members are also passed value but that is not the
case.

It is especially important to understand the aforementioned concept when dealing with linked lists and binary trees due to the node pointers.

Recursion to Iteration: Fibonacci Sequence

The Fibonacci sequence consists of these numbers {0, 1, 1, 2, 3, 5, 8, 13, 21, 34…}. Intuitively, one can see that the next number in the sequence will be a summation of the current number and the previous number. The Fibonacci sequence written recursively is:

public static int fibRecursive(int n) {
        if(n < 0){
            throw new IllegalArgumentException("n < 0");
        }
        if (n <= 1)
            return n;
        return fibRecursive(n - 1) + fibRecursive(n - 2);
}

Behind the scenes, each recursive function call gets pushed on the stack as a stack frame therefore we can emulate recursion calls using a stack:

public static int fibUsingStack(int n) {
        if(n < 0){
            throw new IllegalArgumentException("n < 0");
        }
        Stack<Integer> stack = new Stack<>();
        stack.push(n);
        int sum = 0;
        while (!stack.empty()) {
            Integer next = stack.pop();
            if (next == 0 || next == 1) {
                sum += next;
                continue;
            }
            stack.push(next - 2);
            stack.push(next - 1);
        }
        return sum;
}

This is just a fun learning exercise which helps create understanding on how to convert recursive functions to iterative functions. It wouldn’t make sense to use a stack for this use case.

Java: Generating Random Integers Using Math.random()

Math.random() generates a double between 0 inclusive and 1 exclusive. An easier way to think of this is that Math.random() generates a random double between [0, 1) where “[” is inclusive and “)” is exclusive.

I like this notation better because it helps to make a connection between programming classes and math classes. This connection makes it easier to understand how to generate integers with Math.random() because the experience shifting graphs in math will transfer over to generating random numbers.

So to generate an integer between a certain range, we can just shift the decimal generation and then cast it to an integer. It is important to note that an integer cast will always round down.

//Random decimal between [0, 1)

double randomDecimalBetweenZeroAndOne = Math.random();

//Random integer between [0 * 10, 1 * 10) which equals [0, 10)

int randomIntegerBetweenZeroAndNineInclusive = (int) (Math.random() * 10);

//Random integer between [0*6 + 5, 1*6 + 5) which equals [5, 11)

int randomIntegerBetweenFiveAndTenInclusive = (int)(Math.random() * 6 + 5)

Can you figure out how to write an inclusive method to generate random numbers? Comment below!