Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make slf4j optional with fallback on JUL #1178

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
gotson marked this conversation as resolved.
Show resolved Hide resolved
// 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
Loading