Skip to content
Open
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
24 changes: 24 additions & 0 deletions src/main/java/com/databricks/jdbc/log/JulLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,19 @@ private static String getPackagePrefix() {
if (prefix != null && !prefix.isEmpty()) {
return prefix;
}
// Auto-detect the actual package prefix by using the current class
// This handles shaded JARs where the package might be relocated
String actualPackageName = JulLogger.class.getPackage().getName();
// Extract the root prefix (e.g., "jdbc.shaded.v1.0.12.OSS.com.databricks.jdbc"
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment shows an example shaded package path but has an inconsistent format with a period at the start. The example should be: shaded.jdbc.v1.0.12.OSS.com.databricks.jdbc or clarify if 'jdbc.' is intentional as part of the shading prefix.

Suggested change
// Extract the root prefix (e.g., "jdbc.shaded.v1.0.12.OSS.com.databricks.jdbc"
// Extract the root prefix (e.g., "shaded.jdbc.v1.0.12.OSS.com.databricks.jdbc"

Copilot uses AI. Check for mistakes.
// or "com.databricks.jdbc")
if (actualPackageName.contains(DEFAULT_PACKAGE_PREFIX)) {
// Find the actual prefix including any shading prefix
int defaultPrefixIndex = actualPackageName.indexOf(DEFAULT_PACKAGE_PREFIX);
if (defaultPrefixIndex > 0) {
// Include everything up to and including the default prefix
return actualPackageName.substring(0, defaultPrefixIndex + DEFAULT_PACKAGE_PREFIX.length());
}
}
return DEFAULT_PACKAGE_PREFIX;
}

Expand All @@ -241,6 +254,17 @@ private static String getDriverPackagePrefix() {
if (StringUtils.isNotEmpty(prefix)) {
return prefix;
}
// Auto-detect the actual driver package prefix
// Try to determine if the driver package is also shaded
String mainPackagePrefix = getPackagePrefix();
// Check if we have a shaded prefix
if (!mainPackagePrefix.equals(DEFAULT_PACKAGE_PREFIX)
&& mainPackagePrefix.contains(DEFAULT_PACKAGE_PREFIX)) {
// Extract the shading prefix and apply it to the driver package
String shadingPrefix =
mainPackagePrefix.substring(0, mainPackagePrefix.indexOf(DEFAULT_PACKAGE_PREFIX));
return shadingPrefix + DEFAULT_DRIVER_PACKAGE_PREFIX;
}
return DEFAULT_DRIVER_PACKAGE_PREFIX;
}

Expand Down
70 changes: 70 additions & 0 deletions src/test/java/com/databricks/jdbc/log/JulLoggerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,74 @@ private String[] methodCallingLogger() {
private String[] info() {
return JulLogger.getCaller();
}

@Test
void testPackagePrefixDetectionForUnshadedJar() {
// Test that package prefix detection works for unshaded JARs
String packagePrefix = JulLogger.PARENT_CLASS_PREFIX;
// For unshaded JARs, it should be the default prefix
assertTrue(
packagePrefix.endsWith("com.databricks.jdbc"),
"Package prefix should end with com.databricks.jdbc, got: " + packagePrefix);
}

@Test
void testPackagePrefixDetectionForShadedJar() {
// Test that the package prefix includes any shading prefix
// The JulLogger should be able to detect its own package correctly
String actualPackageName = JulLogger.class.getPackage().getName();
String packagePrefix = JulLogger.PARENT_CLASS_PREFIX;

// Verify that the package prefix matches the actual runtime package structure
assertTrue(
actualPackageName.startsWith(packagePrefix),
String.format(
"Actual package '%s' should start with detected prefix '%s'",
actualPackageName, packagePrefix));

// If the jar is shaded, the prefix should include the shading prefix
if (actualPackageName.contains(".") && !actualPackageName.startsWith("com.databricks.jdbc")) {
Copy link

Copilot AI Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition actualPackageName.contains(\".\") is redundant since Java package names always contain periods. This check should be removed, leaving only the !actualPackageName.startsWith(\"com.databricks.jdbc\") condition.

Suggested change
if (actualPackageName.contains(".") && !actualPackageName.startsWith("com.databricks.jdbc")) {
if (!actualPackageName.startsWith("com.databricks.jdbc")) {

Copilot uses AI. Check for mistakes.
// This means we have a shaded jar
assertTrue(
packagePrefix.contains("com.databricks.jdbc"),
"Shaded package prefix should still contain com.databricks.jdbc");
}
}

@Test
void testInitLoggerConfiguresCorrectPackageForShadedJar() throws IOException {
// This test verifies that when initLogger is called, it configures loggers
// for the correct package prefix (whether shaded or unshaded)
JulLogger.initLogger(Level.OFF, JulLogger.STDOUT, 1024, 1);

// Get the configured logger
Logger jdbcLogger = Logger.getLogger(JulLogger.PARENT_CLASS_PREFIX);

// Verify it was configured with the correct level
assertEquals(
Level.OFF,
jdbcLogger.getLevel(),
"Logger should be configured with Level.OFF to suppress all logs");

// Verify that a logger created with the actual package name inherits the settings
String testLoggerName =
JulLogger.class.getPackage().getName() + ".api.impl.ExecutionResultFactory";
Logger testLogger = Logger.getLogger(testLoggerName);

// The effective level should be OFF (inherited from parent)
Level effectiveLevel = testLogger.getLevel();
// If the local level is null, it inherits from parent
if (effectiveLevel == null) {
Logger parent = testLogger.getParent();
while (parent != null && effectiveLevel == null) {
effectiveLevel = parent.getLevel();
parent = parent.getParent();
}
}

assertEquals(
Level.OFF,
effectiveLevel,
"Child loggers should inherit Level.OFF from properly configured parent logger");
}
}
Loading