Skip to content

Commit

Permalink
feat: make slf4j optional with fallback on JUL
Browse files Browse the repository at this point in the history
Refs: #1094

Co-authored-by: Gauthier Roebroeck <[email protected]>
  • Loading branch information
headius and gotson authored Sep 23, 2024
1 parent 02bac1a commit b8ea5ca
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 19 deletions.
7 changes: 3 additions & 4 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,18 @@ SQLite JDBC is a library for accessing SQLite databases through the JDBC API. Fo

. <<Download,Download>> `sqlite-jdbc-{project-version}.jar`
then append this jar file into your classpath.
. https://search.maven.org/remotecontent?filepath=org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar[Download] `slf4j-api-1.7.36.jar` then append this jar file into your classpath.
. Open a SQLite database connection from your code. (see the example below)

=== Example usage

Assuming `sqlite-jdbc-{project-version}.jar` and `slf4j-api-1.7.36.jar` are placed in the current directory.
Assuming `sqlite-jdbc-{project-version}.jar` is placed in the current directory.

[source,shell,subs="attributes+"]
----
> javac Sample.java
> java -classpath ".;sqlite-jdbc-{project-version}.jar;slf4j-api-1.7.36.jar" Sample # in Windows
> java -classpath ".;sqlite-jdbc-{project-version}.jar" Sample # in Windows
or
> java -classpath ".:sqlite-jdbc-{project-version}.jar:slf4j-api-1.7.36.jar" Sample # in macOS or Linux
> java -classpath ".:sqlite-jdbc-{project-version}.jar" Sample # in macOS or Linux
name = leo
id = 1
name = yui
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
<optional>true</optional>
</dependency>
<!--
This dependency makes compilation on non-GraalVM versions possible.
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/sqlite/JDBC.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

import java.sql.*;
import java.util.Properties;
import java.util.logging.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.jdbc4.JDBC4Connection;
import org.sqlite.util.Logger;
import org.sqlite.util.LoggerFactory;

public class JDBC implements Driver {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JDBC.class);
private static final Logger logger = LoggerFactory.getLogger(JDBC.class);
public static final String PREFIX = "jdbc:sqlite:";

static {
Expand All @@ -49,7 +49,7 @@ public boolean jdbcCompliant() {
return false;
}

public Logger getParentLogger() throws SQLFeatureNotSupportedException {
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/sqlite/SQLiteJDBCLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
import java.util.Properties;
import java.util.UUID;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.util.LibraryLoaderUtil;
import org.sqlite.util.Logger;
import org.sqlite.util.LoggerFactory;
import org.sqlite.util.OSInfo;
import org.sqlite.util.StringUtils;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/sqlite/core/NativeDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.BusyHandler;
import org.sqlite.Collation;
import org.sqlite.Function;
import org.sqlite.ProgressHandler;
import org.sqlite.SQLiteConfig;
import org.sqlite.SQLiteJDBCLoader;
import org.sqlite.util.Logger;
import org.sqlite.util.LoggerFactory;

/** This class provides a thin JNI layer over the SQLite3 C API. */
public final class NativeDB extends DB {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/sqlite/jdbc3/JDBC3DatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.SQLiteConnection;
import org.sqlite.core.CoreDatabaseMetaData;
import org.sqlite.core.CoreStatement;
import org.sqlite.jdbc3.JDBC3DatabaseMetaData.ImportedKeyFinder.ForeignKey;
import org.sqlite.util.Logger;
import org.sqlite.util.LoggerFactory;
import org.sqlite.util.QueryUtils;
import org.sqlite.util.StringUtils;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/sqlite/jdbc3/JDBC3Statement.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sqlite.ExtendedCommand;
import org.sqlite.ExtendedCommand.SQLExtension;
import org.sqlite.SQLiteConnection;
import org.sqlite.core.CoreStatement;
import org.sqlite.core.DB;
import org.sqlite.core.DB.ProgressObserver;
import org.sqlite.util.Logger;
import org.sqlite.util.LoggerFactory;

public abstract class JDBC3Statement extends CoreStatement {

Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/sqlite/util/Logger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sqlite.util;

/** A simple internal Logger interface. */
public interface Logger {
boolean isTraceEnabled();

void trace(String format, Object o1, Object o2);

void info(String format, Object o1, Object o2);

void warn(String msg);

void error(String message, Throwable t);

void error(String format, Object o1, Throwable t);

void error(String format, Object o1, Object o2, Throwable t);
}
130 changes: 130 additions & 0 deletions src/main/java/org/sqlite/util/LoggerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.sqlite.util;

import java.text.MessageFormat;

/**
* A factory for {@link Logger} instances that uses SLF4J if present, falling back on a
* java.util.logging implementation otherwise.
*/
public class LoggerFactory {
static final boolean USE_SLF4J;

static {
boolean useSLF4J;
try {
Class.forName("org.slf4j.Logger");
useSLF4J = true;
} catch (Exception e) {
useSLF4J = false;
}
USE_SLF4J = useSLF4J;
}

/**
* Get a {@link Logger} instance for the given host class.
*
* @param hostClass the host class from which log messages will be issued
* @return a Logger
*/
public static Logger getLogger(Class<?> hostClass) {
if (USE_SLF4J) {
return new SLF4JLogger(hostClass);
}

return new JDKLogger(hostClass);
}

private static class JDKLogger implements Logger {
final java.util.logging.Logger logger;

public JDKLogger(Class<?> hostClass) {
logger = java.util.logging.Logger.getLogger(hostClass.getCanonicalName());
}

@Override
public boolean isTraceEnabled() {
return logger.isLoggable(java.util.logging.Level.FINEST);
}

@Override
public void trace(String format, Object o1, Object o2) {
if (logger.isLoggable(java.util.logging.Level.FINEST)) {
logger.log(java.util.logging.Level.FINEST, MessageFormat.format(format, o1, o2));
}
}

@Override
public void info(String format, Object o1, Object o2) {
if (logger.isLoggable(java.util.logging.Level.INFO)) {
logger.log(java.util.logging.Level.INFO, MessageFormat.format(format, o1, o2));
}
}

@Override
public void warn(String msg) {
logger.log(java.util.logging.Level.WARNING, msg);
}

@Override
public void error(String message, Throwable t) {
logger.log(java.util.logging.Level.SEVERE, message, t);
}

@Override
public void error(String format, Object o1, Throwable t) {
if (logger.isLoggable(java.util.logging.Level.SEVERE)) {
logger.log(java.util.logging.Level.SEVERE, MessageFormat.format(format, o1), t);
}
}

@Override
public void error(String format, Object o1, Object o2, Throwable t) {
if (logger.isLoggable(java.util.logging.Level.SEVERE)) {
logger.log(java.util.logging.Level.SEVERE, MessageFormat.format(format, o1, o2), t);
}
}
}

private static class SLF4JLogger implements Logger {
final org.slf4j.Logger logger;

SLF4JLogger(Class<?> hostClass) {
logger = org.slf4j.LoggerFactory.getLogger(hostClass);
}

@Override
public boolean isTraceEnabled() {
return logger.isTraceEnabled();
}

@Override
public void trace(String format, Object o1, Object o2) {
logger.trace(format, o1, o2);
}

@Override
public void info(String format, Object o1, Object o2) {
logger.info(format, o1, o2);
}

@Override
public void warn(String msg) {
logger.warn(msg);
}

@Override
public void error(String message, Throwable t) {
logger.error(message, t);
}

@Override
public void error(String format, Object o1, Throwable t) {
logger.error(format, o1, t);
}

@Override
public void error(String format, Object o1, Object o2, Throwable t) {
logger.error(format, o1, o2, t);
}
}
}
2 changes: 0 additions & 2 deletions src/main/java/org/sqlite/util/OSInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Provides OS name and architecture name.
Expand Down
19 changes: 18 additions & 1 deletion src/test/java/org/sqlite/architecture/CodingRulesTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.sqlite.architecture;

import static com.tngtech.archunit.base.DescribedPredicate.not;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.belongToAnyOf;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.equivalentTo;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
Expand All @@ -14,15 +15,26 @@
import com.tngtech.archunit.core.importer.ImportOption;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.conditions.ArchConditions;
import java.sql.DriverManager;
import org.sqlite.util.LoggerFactory;
import org.sqlite.util.OSInfo;

@AnalyzeClasses(
packages = "org.sqlite",
importOptions = {ImportOption.DoNotIncludeTests.class})
class CodingRulesTest {
public static final ArchCondition<JavaClass> USE_SLF4J_LOGGING;

static {
USE_SLF4J_LOGGING =
ArchConditions.dependOnClassesThat(
com.tngtech.archunit.core.domain.JavaClass.Predicates
.resideInAPackage("org.slf4j"))
.as("use SLF4J");
}

@ArchTest
void no_access_to_standard_streams(JavaClasses importedClasses) {
Expand All @@ -35,7 +47,12 @@ void no_access_to_standard_streams(JavaClasses importedClasses) {

@ArchTest private final ArchRule no_jodatime = NO_CLASSES_SHOULD_USE_JODATIME;

@ArchTest private final ArchRule no_java_util_logging = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;
@ArchTest
private final ArchRule no_loggers_except_ours =
noClasses()
.that(not(belongToAnyOf(LoggerFactory.class)))
.should(USE_JAVA_UTIL_LOGGING)
.orShould(USE_SLF4J_LOGGING);

@ArchTest
private final ArchRule no_driver_manager_println =
Expand Down

0 comments on commit b8ea5ca

Please sign in to comment.