Log levels in SLF4J, LOG4J and Java default logging

As a java developer, you are most likely using one of the following libraries to log messages:
SLF4J
LOG4J
or Default Java Logging

The following table depicts the log levels supported by each framework, ranked from highest to lowest.

SLF4JLOG4JJava Logging API
ERRORFATALSEVERE
WARNERRORWARNING
INFOWARNINFO
DEBUGINFOCONFIG
TRACEDEBUGFINE
TRACEFINER
FINEST

Resolving Multiple SLF4J Binding Warning

If you develop in Java long enough, you will eventually come across the Multiple Binding warning that looks something like the following:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/org/slf4j/slf4j-log4j12/1.7.24/slf4j-log4j12-1.7.24.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/org/apache/hive/hive-jdbc/1.1.0/hive-jdbc-1.1.0-standalone.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

In this specific case, the warning is stating that SLF4J was found in three different packages (logback-classic, slf4j and hive). Then it states which binding it actually picks up.

This is a warning that should have no consequences if left alone. As the SLF4J link mentioned in the warning notes:

The warning emitted by SLF4J is just that, a warning. Even when multiple bindings are present, SLF4J will pick one logging framework/implementation and bind with it. The way SLF4J picks a binding is determined by the JVM and for all practical purposes should be considered random. As of version 1.6.6, SLF4J will name the framework/implementation class it is actually bound to.

Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J’s purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.

However, if you are a perfectionist like me, you don’t like seeing this warning every time you run your program. It’s pretty easy to remove the warning. You go through the packages that have SLF4J bindings, and exclude it from the dependency.

For example, if the binding was found in Hive, you update from dependency declaration to:

<dependency>
  <groupId>org.apache.hive</groupId>
  <artifactId>hive-jdbc</artifactId>
  <version>1.1.0</version>
  <classifier>standalone</classifier>
  <exclusions>
   <exclusion>
    <artifactId>jetty-all</artifactId>
    <groupId>org.eclipse.jetty.aggregate</groupId>
   </exclusion>
   <exclusion>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
   </exclusion>
  <exclusion>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
   </exclusion>
  </exclusions>

 </dependency>

Kotlin is now an officially supported language for Android

The I/O news is starting to turn to developer-centric topics, and one of the more significant things to come out of the keynote is an official declaration that Google is now officially supporting Kotlin as a first-class language for developing Android apps. Starting with Android Studio 3.0, Kotlin is included out-of-the-box, so there are no additional setup steps or add-ons to install.

Kotlin was created by JetBrains and officially released early last year. It gained popularity largely because it runs on the Java Virtual Machine and can be used alongside java to build apps. This means developers can take existing code and easily build new features or replace Java code in pieces. Since Kotlin is dependent on Java, it means both languages will continue to be supported.

Google will now contribute to the further growth of Kotlin and build new tools directly into Android Studio to make it even more useful.

To learn more about Kotlin, check out the sessions titled Intro to Kotlin at 10:30 on Friday and Life is great and everything will be ok, Kotlin is here at 2:30. Also, check out the dedicated Kotlin website.

Source: Kotlin BlogAndroid Dev Blog

Adding Rolling Logs capability to Spring Boot

Introduction

Spring Boot has LoggingSystem abstraction, which means you can use any Logging library you prefer.
Due to this constraint, Spring Boot only provides basic properties that can be written in your application.properties or application.yml files.

Spring Boot allows you to set the logging levels and location of log (file or console) from your configuration file. For example:

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
logging:
  file: log/application.log
  level:
    ROOT: INFO
    org.springframework.web.filter.CommonsRequestLoggingFilter: DEBUG
    com.fullstacktrace.logDemo: DEBUG

Rolling Logs

To configure more advanced or fine-grained settings for logging, you must provide it in native configuration format.
Spring Boot will pick up the native configuration from the default location. For logback that location is classpath: logback.xml . You can also overwrite this location by setting the logging.config property

logging:
  config: classpath:logback-local.xml

To set Rolling Logs, you need to provide the setttings in logback.xml file:

<configuration>
 <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
 <springProperty scope="context" name="springAppName" source="spring.application.name"/>
 <!-- You can override this to have a custom pattern -->
 <property name="CONSOLE_LOG_PATTERN"
 value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 <file>log/application.log</file>
 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
 <!-- daily rollover -->
 <fileNamePattern>application.%d{yyyy-MM-dd}.log</fileNamePattern>

 <!-- keep 90 days' worth of history capped at 3GB total size -->
 <maxHistory>90</maxHistory>
 <totalSizeCap>3GB</totalSizeCap>

 </rollingPolicy>

 <encoder>
 <pattern>${CONSOLE_LOG_PATTERN}}</pattern>
 </encoder>
 </appender>
 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 <encoder>
 <pattern>${CONSOLE_LOG_PATTERN}</pattern>
 </encoder>
 </appender>
 <logger name="org.springframework.web.filter.CommonsRequestLoggingFilter">
 <appender-ref ref="FILE"/>
 </logger>
 <logger name="com.fullstacktrace.net">
 <appender-ref ref="FILE"/>
 </logger>
 <root level="INFO">
 <appender-ref ref="STDOUT"/>
 </root>

</configuration>

You can find more advanced logback setttings here

References

1. Spring Boot Docs
2. LogBack Docs

Jackson ObjectMapper 101

Jackson is a JSON processing library for Java. The code below will create an object mapper outputting JSON in pretty format and have case insensitive fields.

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);

Jackson Wiki containing additional features:

Downloading file using Jersey

Very often, your application requires having a resource that allows users to download a file. This could be an endpoint where a user downloads some Report, their user data, or any other type of file.
To achieve this goal, you use StreamingOutput to copy the content of the file, and then add the stream to your Response object.

@GET
@Path("/download")
public Response download()
{
	String filename = "//someFolder/some-File.pdf"
	File file = new File(filename);
	final String newFileName = file.getName();
	StreamingOutput fileStream = output ->
	{
		try
		{
			java.nio.file.Path path = Paths.get(filename);
			byte[] data = Files.readAllBytes(path);
			output.write(data);
			output.flush();
		}
		catch (Exception e)
		{
			throw new WebApplicationException("File Not Found !!");
		}
	};
	return Response
			.ok(fileStream, MediaType.APPLICATION_OCTET_STREAM)
			.header("content-disposition", "attachment; filename = " + newFileName)
			.build();
}

Using MongoDB with Spring Boot

Spring Boot is a powerful framework for building microservices. It comes ready to work with almost every type of database, including the newer NoSQL variety. This guide shows you how to quickly integrate MongoDB with your Spring Boot Application

Dependency

Spring Boot has hundreds of starter packages that allow you to avoid writing code. They have a starter for mongodb as well. Include the following dependency:

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

Configuration

Add your database connection string in the your configuration file:

spring.data.mongodb.uri= mongodb://localhost:27017/mongodb

Model

Setup your entity model, just like you would for a traditional SQL entity


@Entity
@Data
public class Permit {
    @Id
    public String id;
    public String permitNum;
    public String revisionNum;
    public String permitType;
    public String structureType;
    public String work;
    public String streetNum;
    public String streetName;
    public String streetType;
    public String streetDirection;
    public String postal;
}

Setup Repository


public interface PermitRepository extends MongoRepository {
    List findAll();
}

That’s it! you can start using your Model to GET or POST data from your MongoDB Database

Using H2 Database with Spring Boot

H2 is one of the more popular embedded databases out there today. Although there are 16-20 embedded databases out in the market, there are only 3 that work well with Spring (H2, Derby and HSQL).
Out of the three, H2 is considered the most matured and supported product. Although not recommended to use in production environment, H2 is robust enough to handle small scale production applications.

Using embedded H2 in Spring Boot is pretty simple. First you add the appropriate connection details in your configuration file, and then you can start using it in Spring like any other SQL database.

You need to add H2 as a maven dependency, there is no installs or setups required!

Dependency

<dependency>
     <groupId>com.h2database</groupId>
     <artifactId>h2</artifactId>
     <version>1.4.195</version>
</dependency>

Configuration

spring.datasource:
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:bootexample;MODE=MySQL

Data Model

Once you have your database setup, you can use it the same way you would use any other database in Spring. You create a model for your database entity

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue
    private Long id;
    @NotNull
    @NotEmpty
    private String firstName;
    @NotNull
    @NotEmpty
    private String lastName;
    @NotNull
    @NotEmpty
    private String password;
    @ValidEmail
    private String email;
    @NotNull
    @NotEmpty
    private String phoneNumber;
    private String lastOnline;
    private Boolean enabled;
    public String getLastOnline() {
        return lastOnline;

    }

    public void setLastOnline(String lastOnline) {
        this.lastOnline = lastOnline;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public Long getId() {
        return id;
    }


    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

Repository

Finally, you can use Spring’s JpaRepositoryto manipulate your data

package com.fullstacktrace.domain;

import com.fullstacktrace.domain.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Integer> {
    public User findByEmail(String email);
}

Hibernate Database Creation properties

Hibernate is a powerful open source java persistence framework. One of it’s feature is that it can automatically create your databases for you based on your code.
When you set the hibernate.hbm2dll.auto property, it allows you to either update, create, create-drop or validate your schema.

From the community documentation:

hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.

e.g. validate | update | create | create-drop

The legal options are :

    • validate: validate the schema, makes no changes to the database.
    • update: update the schema.
    • create: creates the schema, destroying previous data.
    • create-drop: drop the schema when the SessionFactory is closed explicitly, typically when the application is stopped.