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>

Moving Uncommitted changes to new branch

If you’ve made changes that you would not like to the current checkout branch, but rather create a new branch for it, you can do so by creating a new branch first, and then committing the changes:

1. Create a new branch (before committing your changes)

git checkout -b <new-branch-name>

2. Add,commit and push your changes

git add src/main/java/somefile.java
git commit -m "my new changes"
git push origin <new-branch-name>

Stack used by popular websites

If you want to know what technology your favorite website uses, you’re often left with guessing or trying to figure it out by looking at website’s source code. And this only helps with learning what front end libraries they might be using.

There are a few resources available now to find what’s powering your favorite websites.

High Scalability is a website that gathers interviews and open information available on technology stack of various websites in one place:

Built With 

 

Amazon and Microsoft allow Google indexing files in Blob Storage

Microsoft and Amazon are giants in the cloud storage business. With Microsoft’s Azure platform, and Amazon’s AWS, they dominate the cloud file storage market. Both of these companies take security and privacy seriously, ensuring customers that the data they upload to cloud is safe. This is why it was such a shock to find that they both allow Google to index the files in the blob storage.

Although this was discovered by a security researcher in 2011, it has recently garnered the attention of security professionals on twitter. Mikko Hypponen of F-Secure pointed his followers to try out the “bug” by searching for content on Azure Blob Store with the words “Confidential” in it:

That search query site:core.windows.net "confidential" yields some very interesting results:

To search for content in Amazon’s AWS storage, use the query:

site:http://s3.amazonaws.com "confidential"

You can also search for specific types of files, for example:
site:http://s3.amazonaws.com filetype:xls password
site:http://s3.amazonaws.com filetype:xls secret
site:http://s3.amazonaws.com "TOP SECRET"

How to Test a Pull Request

When someone creates a pull request, it’s your responsibility to either accept the changes and merge it to your repository, or reject the changes and close the pull request. These days, Continuous Integration Development involves automation engines like Jenkins or TeamCity that monitor your source repository and can trigger builds for pull requests to ensure the resulting merge will run. However, it is a good idea to test the pull request locally.

To test pull request code locally follow these steps:

  1. Open git bash and ensure your working directory is clean by running git status
  2. get a copy of the PR by typing git fetch upstream pull/<id>/head:<branch>. for example you would type git fetch upstream pull/123/head:branch-name if you were testing Pull Request number 123 from branch called branch-name.
  3. Now that you have a copy of the branch, switch to it using git checkout branch-name. Your directory will now be an exact copy of the PR. Be sure to tell the author about any bugs or suggestions, as you cannot add your own changes to a pull request directly.
  4. When you are done checking out their work, use git checkout master to return to your local version of the source code.

Flutter: Google’s new mobile SDK

Google has released a new cross platform Software Development Kit (SDK) for developing iOS and Android apps. With the stated goal of enabling development of “high-performance, high-fidelity, apps for iOS and Android, from a single codebase”, Google has officially entered the cross platform development arena.

Flutter is still in early-stage, and not being recommended for developing production applications at this time. It is also missing a whole set of features offered by any other SDK like accessibility, text input, localization, and more. The pre-release was published in December of 2015, and there has been no new releases on their GitHub since then. It is not clear how well supported this new SDK will be, but it does look promising.

To develop apps in Flutter, you need to learn Google’s Dart programming language. Dart has a very c# like syntax, so it is relatively easy to pick up for people with Java or C# experience. The following code snippet shows how to write a method and call it in Dart


// Define a function.
printNumber(num aNumber) {
  print('The number is $aNumber.'); // Print to console.
}

// This is where the app starts executing.
main() {
  var number = 42; // Declare and initialize a variable.
  printNumber(number); // Call a function.
}

In the coming months, we will be posting tutorials on how to get started with Flutter to build apps.

References

1. Flutter
2. Dart

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