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

Keycloak fails to start when uninstalling custom provider #24459

Closed
2 tasks done
PIPOGit opened this issue Nov 1, 2023 · 22 comments · Fixed by #27214
Closed
2 tasks done

Keycloak fails to start when uninstalling custom provider #24459

PIPOGit opened this issue Nov 1, 2023 · 22 comments · Fixed by #27214
Assignees
Milestone

Comments

@PIPOGit
Copy link

PIPOGit commented Nov 1, 2023

Before reporting an issue

Area

core

Describe the bug

Hi.

I'm working with KeyCloak (both, with a Docker image and a locally downloaded v22.0.5) and a custom mapper for OIDC Tokens.

Basically, I've used the code in this URL:
https://betterjavacode.com/programming/custom-protocol-mapper-keycloak

I've generated a JAR and put it into the /opt/keycloak/providers folder. Let's call it: "provider-cpm_1.0.0.jar".

Later, I've used it (I can see it as a mapper) in a custom scope within a own Realm's client. It works.
( KeyCloak in a docker container from: keycloak/keycloak:latest )

But, if I want to "uninstall" the mapper from KeyCloak, I just delete the file, as par:
https://www.keycloak.org/server/configuration-provider#_installing_and_uninstalling_a_provider

The problem is that, if I stop the container and start it again, then a nice "NoSuchFileException" error message comes:

2023-11-01 11:50:37 The DelayedHandler was closed before any children handlers were configured. Messages will be written to stderr.
2023-11-01 11:50:37 2023-11-01 10:50:37,162 DEBUG [org.jboss.logging] (main) Logging Provider: org.jboss.logging.JBossLogManagerProvider
2023-11-01 11:50:37 
2023-11-01 11:50:37 Exception in thread "main" java.lang.reflect.InvocationTargetException
2023-11-01 11:50:37     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2023-11-01 11:50:37     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
2023-11-01 11:50:37     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2023-11-01 11:50:37     at java.base/java.lang.reflect.Method.invoke(Method.java:568)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:61)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)
2023-11-01 11:50:37 Caused by: java.lang.RuntimeException: Failed to open /opt/keycloak/lib/../providers/provider-cpm_1.0.0.jar
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:172)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.JarResource.readLockAcquireAndGetJarReference(JarResource.java:153)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.JarResource.getResourceURL(JarResource.java:101)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.RunnerClassLoader.findResources(RunnerClassLoader.java:214)
2023-11-01 11:50:37     at java.base/java.lang.ClassLoader.getResources(ClassLoader.java:1473)
2023-11-01 11:50:37     at io.smallrye.common.classloader.ClassPathUtils.consumeAsPaths(ClassPathUtils.java:84)
2023-11-01 11:50:37     at io.smallrye.config.AbstractLocationConfigSourceLoader.tryClassPath(AbstractLocationConfigSourceLoader.java:139)
2023-11-01 11:50:37     at io.smallrye.config.AbstractLocationConfigSourceLoader.loadConfigSources(AbstractLocationConfigSourceLoader.java:102)
2023-11-01 11:50:37     at io.smallrye.config.AbstractLocationConfigSourceLoader.loadConfigSources(AbstractLocationConfigSourceLoader.java:85)
2023-11-01 11:50:37     at io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader$InClassPath.getConfigSources(ApplicationPropertiesConfigSourceLoader.java:30)
2023-11-01 11:50:37     at io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader$InClassPath.getConfigSources(ApplicationPropertiesConfigSourceLoader.java:27)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfig$ConfigSources.buildSources(SmallRyeConfig.java:581)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfig$ConfigSources.<init>(SmallRyeConfig.java:537)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:69)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:629)
2023-11-01 11:50:37     at io.quarkus.runtime.configuration.QuarkusConfigFactory.getConfigFor(QuarkusConfigFactory.java:29)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:76)
2023-11-01 11:50:37     at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:64)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.configuration.Configuration.getConfig(Configuration.java:51)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.cli.Picocli.hasConfigChanges(Picocli.java:239)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.cli.Picocli.requiresReAugmentation(Picocli.java:141)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.cli.Picocli.runReAugmentationIfNeeded(Picocli.java:126)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:95)
2023-11-01 11:50:37     at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:88)
2023-11-01 11:50:37     ... 6 more
2023-11-01 11:50:37 Caused by: java.nio.file.NoSuchFileException: /opt/keycloak/lib/../providers/provider-cpm_1.0.0.jar
2023-11-01 11:50:37     at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
2023-11-01 11:50:37     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
2023-11-01 11:50:37     at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
2023-11-01 11:50:37     at java.base/sun.nio.fs.UnixFileAttributeViews$Basic.readAttributes(UnixFileAttributeViews.java:55)
2023-11-01 11:50:37     at java.base/sun.nio.fs.UnixFileSystemProvider.readAttributes(UnixFileSystemProvider.java:148)
2023-11-01 11:50:37     at java.base/sun.nio.fs.LinuxFileSystemProvider.readAttributes(LinuxFileSystemProvider.java:99)
2023-11-01 11:50:37     at java.base/java.nio.file.Files.readAttributes(Files.java:1851)
2023-11-01 11:50:37     at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1394)
2023-11-01 11:50:37     at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:716)
2023-11-01 11:50:37     at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:250)
2023-11-01 11:50:37     at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:179)
2023-11-01 11:50:37     at java.base/java.util.jar.JarFile.<init>(JarFile.java:346)
2023-11-01 11:50:37     at io.smallrye.common.io.jar.JarFiles.create(JarFiles.java:33)
2023-11-01 11:50:37     at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:170)
2023-11-01 11:50:37     ... 29 more

Any idea of how to avoid this situation?

Many thanks in advance.

Version

22.0.5

Expected behavior

The "build" step, just before "start | start-dev" should take care of "non-existing" providers and do not stop server to initiate.
Maybe, throwing an error message in the log file, but not stop it; or providing an alternate way to start or instructions on how to remediate the bug.

Actual behavior

Breaks the startup process, and the eserver is not starting

How to Reproduce?

  1. Put a JAR file for a mapper in the "/providers" folder.
  2. Start the server
  3. Remove the file
  4. Stop the server
  5. Restart again

Anything else?

No response

@PIPOGit PIPOGit added kind/bug Categorizes a PR related to a bug status/triage labels Nov 1, 2023
@PIPOGit
Copy link
Author

PIPOGit commented Nov 2, 2023

Maybe, it should be a good idea to include a kind of management page for these things...

@sschu
Copy link
Contributor

sschu commented Nov 3, 2023

Have you executed the build step as mentioned in the documentation? Like: 4. Stop the server 5. run build 6. Start server?

@PIPOGit
Copy link
Author

PIPOGit commented Nov 3, 2023

Yeah.

Both cases: Executing it and without executing it. No one worked.

@sschu
Copy link
Contributor

sschu commented Nov 6, 2023

And you are not doing a rolling restart where another pod is still present but you completely shut down all running instances of Keycloak?

@PIPOGit
Copy link
Author

PIPOGit commented Nov 6, 2023

No more pods present.
That's what I'm struggled.

@dpulrichth
Copy link

I'm facing the same issue. Removing any Provider jar from the providers directory will cause Keycloak to fail at next startup, regardless of running the build command. It seems to be related to the lib\quarkus\quarkus-application.dat file. When I replace this file with the original from the downloaded Keycloak zip, Keycloak starts.

Removing Providers from the providers directory used to work in previous versions of keycloak. It broke somewhere around Keycloak 20.

@pedroigor
Copy link
Contributor

Is it happening in the latest version? Wasn't able to reproduce in 22.0.5, 23.0.3, and nightly. I've seen a similar issue before and I think we have an open issue for it.

@vmuzikar Wdyt?

@dpulrichth
Copy link

I just tested this again on 23.0.3. I removed a provider jar file from the providers directory and started Keycloak with start-dev, triggering a rebuild. It started with an Exception (see below) but did finish successfully and Keycloak remained online afterwards. So that is an improvement. It would be nice if the exception was handled gracefully, e.g. by logging something like "Provider xxx no longer present, removing it."

java.lang.RuntimeException: Failed to open REDACTED_PATH_TO_JAR
        at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:172)
        at io.quarkus.bootstrap.runner.JarResource.readLockAcquireAndGetJarReference(JarResource.java:153)
        at io.quarkus.bootstrap.runner.JarResource.getResourceURL(JarResource.java:101)
        at io.quarkus.bootstrap.runner.RunnerClassLoader.findResource(RunnerClassLoader.java:162)
        at java.base/java.lang.ClassLoader.getResource(ClassLoader.java:1408)
        at java.base/java.lang.ClassLoader.getResourceAsStream(ClassLoader.java:1738)
        at org.codehaus.groovy.reflection.GeneratedMetaMethod$DgmMethodRecord.loadDgmInfo(GeneratedMetaMethod.java:191)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerMethods(MetaClassRegistryImpl.java:207)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:116)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:94)
        at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:37)
        at org.codehaus.groovy.runtime.InvokerHelper.<clinit>(InvokerHelper.java:71)
        at groovy.lang.GroovyObjectSupport.getDefaultMetaClass(GroovyObjectSupport.java:46)
        at groovy.lang.GroovyObjectSupport.<init>(GroovyObjectSupport.java:32)
        at groovy.lang.Closure.<init>(Closure.java:215)
        at groovy.lang.Closure.<init>(Closure.java:232)
        at groovy.lang.Closure$1.<init>(Closure.java:197)
        at groovy.lang.Closure.<clinit>(Closure.java:197)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:375)
        at picocli.CommandLine$DefaultFactory.loadClosureClass(CommandLine.java:5619)
        at picocli.CommandLine$DefaultFactory.<clinit>(CommandLine.java:5613)
        at picocli.CommandLine$Model$CommandUserObject.getInstance(CommandLine.java:12263)
        at picocli.CommandLine$Model$CommandUserObject.get(CommandLine.java:12288)
        at picocli.CommandLine$Model$FieldBinding.set(CommandLine.java:12107)
        at picocli.CommandLine$Model$CommandReflection.initFromAnnotatedTypedMembers(CommandLine.java:11975)
        at picocli.CommandLine$Model$CommandReflection.initFromAnnotatedMembers(CommandLine.java:11909)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11842)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6388)
        at picocli.CommandLine.<init>(CommandLine.java:230)
        at picocli.CommandLine.toCommandLine(CommandLine.java:3631)
        at picocli.CommandLine.access$16700(CommandLine.java:148)
        at picocli.CommandLine$Model$CommandReflection.initSubcommands(CommandLine.java:11874)
        at picocli.CommandLine$Model$CommandReflection.extractCommandSpec(CommandLine.java:11840)
        at picocli.CommandLine$Model$CommandSpec.forAnnotatedObject(CommandLine.java:6388)
        at org.keycloak.quarkus.runtime.cli.Picocli.createCommandLine(Picocli.java:448)
        at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:97)
        at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:107)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:61)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)
Caused by: java.nio.file.NoSuchFileException: REDACTED_PATH_TO_JAR
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:53)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:199)
        at java.base/java.nio.file.Files.readAttributes(Files.java:1851)
        at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1428)
        at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:718)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:252)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:181)
        at java.base/java.util.jar.JarFile.<init>(JarFile.java:346)
        at io.smallrye.common.io.jar.JarFiles.create(JarFiles.java:33)
        at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:170)
        ... 43 more

@vmuzikar
Copy link
Contributor

vmuzikar commented Jan 8, 2024

Wasn't able to reproduce in 22.0.5, 23.0.3, and nightly.

@pedroigor Seems to be affecting only some providers?

@PIPOGit
Copy link
Author

PIPOGit commented Jan 8, 2024

As a test to check this behaviour, let me suggestto create a mapper, create the Jar file, put it in the "providers" folder, edit the project (changing anything) and put the new created Jar file into the folder and try to start-up Keycloak again and check.

@shawkins
Copy link
Contributor

@PIPOGit @dpulrichth I saw similar behavior to @pedroigor with 23.0.4 - build, start, or state-dev all appropriately detected the provider jar removal. However on linux at least there was no logging of the exception shown by @dpulrichth - not to the console by default, nor at the debug level. This was with both the rest example provider and the mapper provider referenced by @PIPOGit above.

@PIPOGit can you retry your scenario on a later release to confirm if this is still an issue for you?

@PIPOGit
Copy link
Author

PIPOGit commented Feb 15, 2024

Hi, @shawkins.

I hope You can "read" this PowerShell script... and it works! (adapt it as you wish)
Attached, I add the source code I've been using: "Custom Mappers.zip"
Custom Mappers.zip

I have TWO questions:

  • Why removing the custom provider's JAR file stops the server startup?, and
  • Why the server admits two (or more) custom providers, with the same [package.class] at a time?

The script with my steps.

# ================================================================
# Launch a PowerShell console
# CONSOLE["Test KeyCloak Console"]

# Configure console.
Clear-Host;

# Console's title
$Host.UI.RawUI.WindowTitle = "Test KeyCloak Console";

# Some variables
$ROOT_FOLDER = "C:\Temp\Test KeyCloak";
$KEYCLOAK_VERSION = "23.0.6";
$KEYCLOAK_HOME = "keycloak-$($KEYCLOAK_VERSION)";

# Operations
Set-Location "${ROOT_FOLDER}"


# Download KeyCloak "latest" version
# Check: https://github.com/keycloak/keycloak/releases/

# if ( !( Test-Path ${ROOT_FOLDER} -PathType Container ) ) {
#     New-Item -ItemType Directory -Force -Path ${ROOT_FOLDER} | Out-Null;
# }


# Download file
Set-Location "${ROOT_FOLDER}"
$ProgressPreference = 'SilentlyContinue'    # Subsequent calls do not display UI.
IWR "https://github.com/keycloak/keycloak/releases/download/$($KEYCLOAK_VERSION)/$($KEYCLOAK_HOME).zip" -OutFile "$($KEYCLOAK_HOME).zip"
$ProgressPreference = 'Continue'            # Subsequent calls do display UI.
# FILE: [${ROOT_FOLDER}\$($KEYCLOAK_HOME).zip] (164.677.937 bytes)

# Unzip downloaded file
$ProgressPreference = 'SilentlyContinue'    # Subsequent calls do not display UI.
Expand-Archive -Path "${ROOT_FOLDER}\$($KEYCLOAK_HOME).zip" -DestinationPath "${ROOT_FOLDER}\KeyCloak"
$ProgressPreference = 'Continue'            # Subsequent calls do display UI.
# FOLDER: [${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)]


# ================================================================
# Start KeyCloak
# Launch a new PowerShell console
# CONSOLE["Test KeyCloak Server"]
Clear-Host;

# Console's title
$Host.UI.RawUI.WindowTitle = "Test KeyCloak Server";

# Some variables
$ROOT_FOLDER = "C:\Temp\Test KeyCloak";
$KEYCLOAK_VERSION = "23.0.6";
$KEYCLOAK_HOME = "keycloak-$($KEYCLOAK_VERSION)";

# Operations
Set-Location "${ROOT_FOLDER}"

# Start server
Set-Location "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\bin"
& .\kc.bat start-dev

# Stop server with ^C.
# (will run after ^C)
Set-Location "${ROOT_FOLDER}"
# ================================================================


# ================================================================
# Open Admin console at: http://localhost:8080/
# CONSOLE["Test KeyCloak Console"]
Clear-Host;
Start-Process "http://localhost:8080/";

# CHECK it works.
# CREATE [admin/admin] account
# LOGIN
# CHECK it works.
# STOP the server in server's console
# ================================================================


# ================================================================
# Create mapper: "Mapper 01"
# CONSOLE["Test KeyCloak Console"]
# Use: https://betterjavacode.com/programming/custom-protocol-mapper-keycloak

# Mapper 01
Set-Location "${ROOT_FOLDER}\Custom Mappers\mapper-01"
Clear-Host;

# Maven: Create custom mapper file
mvn clean package;

# Copy custom mapper file
Copy-Item -Path "${ROOT_FOLDER}\Custom Mappers\mapper-01\target\pipogit-cpm-01.jar" -Destination "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers";

# List custom mappers
Get-ChildItem "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers\*.jar";

# CHECK "pipogit-cpm-01.jar" is listed.

# Back to HOME
Set-Location "${ROOT_FOLDER}"
# ================================================================


# ================================================================
# Launch KeyCloak Server again
# CONSOLE["Test KeyCloak Server"]
# Repeat previous steps
Clear-Host;

# Operations
Set-Location "${ROOT_FOLDER}"

# Start server
Set-Location "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\bin"
& .\kc.bat start-dev

# Stop server with ^C.
# (will run after ^C)
Set-Location "${ROOT_FOLDER}"
# ================================================================


# ================================================================
# Open Admin console at: http://localhost:8080/
# CONSOLE["Test KeyCloak Console"]
Clear-Host;
Start-Process "http://localhost:8080/";
# Login
# GOTO: Client Scopes
# Select one (i.e.: "address")
# GOTO: "Mappers"
# Select: "Add mapper" > "By configuration"
# CHECK that "PipoGIT Custom Mapper 01" exists.
# STOP the server in server's console
# ================================================================



# ================================================================
# Create mapper: "Mapper 02"
# CONSOLE["Test KeyCloak Console"]
# Use: https://betterjavacode.com/programming/custom-protocol-mapper-keycloak

# Mapper 02
Set-Location "${ROOT_FOLDER}\Custom Mappers\mapper-02"
Clear-Host;

# Maven: Create custom mapper file
mvn clean package;

# Copy custom mapper file
Copy-Item -Path "${ROOT_FOLDER}\Custom Mappers\mapper-02\target\pipogit-cpm-02.jar" -Destination "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers";

# List custom mappers
Get-ChildItem "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers\*.jar";

# CHECK "pipogit-cpm-01.jar" AND "pipogit-cpm-02.jar" are listed.

# Back to HOME
Set-Location "${ROOT_FOLDER}"
# ================================================================


# ================================================================
# Launch KeyCloak Server again
# CONSOLE["Test KeyCloak Server"]
# Repeat previous steps
Clear-Host;

# Operations
Set-Location "${ROOT_FOLDER}"

# Start server
Set-Location "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\bin"
& .\kc.bat start-dev

# Stop server with ^C.
Set-Location "${ROOT_FOLDER}"
# ================================================================


# ================================================================
# Open Admin console at: http://localhost:8080/
# CONSOLE["Test KeyCloak Console"]
Clear-Host;
Start-Process "http://localhost:8080/";
# Login
# GOTO: Client Scopes
# Select one (i.e.: "address")
# GOTO: "Mappers"
# Select: "Add mapper" > "By configuration"
# CHECK that "PipoGIT Custom Mapper 01" exists.
# CHECK that "PipoGIT Custom Mapper 02" DOES NOT exists.
# STOP the server in server's console
# ================================================================


# ================================================================
#
# *** FINAL TEST ***
#
# CONSOLE["Test KeyCloak Console"]
Clear-Host;

# List custom mappers
Get-ChildItem "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers\*.jar";

# Delete "Custom Mapper 02" from "pipogit-cpm-02.jar"
Remove-Item "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers\pipogit-cpm-02.jar";

# List custom mappers
Get-ChildItem "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\providers\*.jar";
# ================================================================


# ================================================================
# Launch KeyCloak Server again
# CONSOLE["Test KeyCloak Server"]
# Repeat previous steps
Clear-Host;

# Operations
Set-Location "${ROOT_FOLDER}"

# Start server
Set-Location "${ROOT_FOLDER}\KeyCloak\$($KEYCLOAK_HOME)\bin"
& .\kc.bat start-dev

# CHECK Error Log Messages:
<#
The DelayedHandler was closed before any children handlers were configured. Messages will be written to stderr.
2024-02-15 08:44:36,341 DEBUG [org.jboss.logging] (main) Logging Provider: org.jboss.logging.JBossLogManagerProvider

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:61)
        at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:32)
Caused by: java.lang.RuntimeException: Failed to open C:\Temp\Test KeyCloak\KeyCloak\keycloak-23.0.6\lib\..\providers\pipogit-cpm-02.jar
        at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:172)
        at io.quarkus.bootstrap.runner.JarResource.readLockAcquireAndGetJarReference(JarResource.java:153)
        at io.quarkus.bootstrap.runner.JarResource.getResourceURL(JarResource.java:101)
        at io.quarkus.bootstrap.runner.RunnerClassLoader.findResources(RunnerClassLoader.java:214)
        at java.base/java.lang.ClassLoader.getResources(ClassLoader.java:1469)
        at io.smallrye.common.classloader.ClassPathUtils.consumeAsPaths(ClassPathUtils.java:84)
        at io.smallrye.config.AbstractLocationConfigSourceLoader.tryClassPath(AbstractLocationConfigSourceLoader.java:139)
        at io.smallrye.config.AbstractLocationConfigSourceLoader.loadConfigSources(AbstractLocationConfigSourceLoader.java:102)
        at io.smallrye.config.AbstractLocationConfigSourceLoader.loadConfigSources(AbstractLocationConfigSourceLoader.java:85)
        at io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader$InClassPath.getConfigSources(ApplicationPropertiesConfigSourceLoader.java:30)
        at io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader$InClassPath.getConfigSources(ApplicationPropertiesConfigSourceLoader.java:27)
        at io.smallrye.config.SmallRyeConfig$ConfigSources.buildSources(SmallRyeConfig.java:581)
        at io.smallrye.config.SmallRyeConfig$ConfigSources.<init>(SmallRyeConfig.java:537)
        at io.smallrye.config.SmallRyeConfig.<init>(SmallRyeConfig.java:69)
        at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:629)
        at io.quarkus.runtime.configuration.QuarkusConfigFactory.getConfigFor(QuarkusConfigFactory.java:29)
        at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:76)
        at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:64)
        at org.keycloak.quarkus.runtime.configuration.Configuration.getConfig(Configuration.java:51)
        at org.keycloak.quarkus.runtime.cli.Picocli.hasConfigChanges(Picocli.java:335)
        at org.keycloak.quarkus.runtime.cli.Picocli.requiresReAugmentation(Picocli.java:169)
        at org.keycloak.quarkus.runtime.cli.Picocli.runReAugmentationIfNeeded(Picocli.java:153)
        at org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun(Picocli.java:105)
        at org.keycloak.quarkus.runtime.KeycloakMain.main(KeycloakMain.java:107)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        ... 3 more
Caused by: java.nio.file.NoSuchFileException: C:\Temp\Test KeyCloak\KeyCloak\keycloak-23.0.6\lib\..\providers\pipogit-cpm-02.jar
        at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
        at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:53)
        at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
        at java.base/sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:197)
        at java.base/java.nio.file.Files.readAttributes(Files.java:1848)
        at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1414)
        at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:723)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:250)
        at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:179)
        at java.base/java.util.jar.JarFile.<init>(JarFile.java:339)
        at io.smallrye.common.io.jar.JarFiles.create(JarFiles.java:33)
        at io.quarkus.bootstrap.runner.JarResource.ensureJarFileIsOpen(JarResource.java:170)
        ... 27 more
#>
# ================================================================

@shawkins
Copy link
Contributor

Why removing the custom provider's JAR file stops the server startup?, and

The issue is with including the application.properties file in your provider jar. We are first checking for config changes, then for provider changes. To resolve the config, we try to load all of the known application.properties files - thus the exception here. If you omit that file, then things will work as expected.

Why the server admits two (or more) custom providers, with the same [package.class] at a time?

I see a split package warning on the cli related to this. What behavior would you like to see?

@dpulrichth stack also seems related to, and potentially resolved by #19285

@vmuzikar @Pepo48 based upon the above this isn't a windows issue. I think it's something we could avoid by switching the order of the checks in requiresReAugmentation. However we may also not want to encourage / allow application.properties files to appear in the provider jars.

@PIPOGit
Copy link
Author

PIPOGit commented Feb 15, 2024

1.- What if the provider needs an application.properties file? And what about if it does not change? I suggest something like package definition, hash the class... Other solution, indeed.

2.- Just a warning and allow only the first/latest one, by deployment date?

And a suggestion: Why not to include a kind-of "custom providers" interface, like "Client scopes"? "Custom Mappers" menu item, for global management...

@shawkins
Copy link
Contributor

shawkins commented Feb 15, 2024

1.- What if the provider needs an application.properties file?

The issue is that quarkus uses a flat classloader and keycloak already includes an application.properties file at the root of the classpath. Only one of the application.properties files will eventually be used. We do not document and would not support trying to override the default configuration supplied by the keycloak application.properties file in this way.

So if you need a specific configuration file for you provider jar, it should be named in such a way as to not conflict with other keycloak or provider classpath entries.

2.- Just a warning and allow only the first/latest one, by deployment date?

Please separate that into an enhancement request.

And a suggestion: Why not to include a kind-of "custom providers" interface, like "Client scopes"? "Custom Mappers" menu item, for global management...

Please separate that into an enhancement request.

@PIPOGit
Copy link
Author

PIPOGit commented Feb 15, 2024

Done! 😉

#27056

( close this issue if you want! )

@shawkins
Copy link
Contributor

Thank you @PIPOGit

@Pepo48 @vmuzikar do you want to use this issue to add a note in the provider development guide about potential classpath conflicts, or just close it out?

@Pepo48
Copy link
Contributor

Pepo48 commented Feb 15, 2024

Thanks @shawkins for further investigation. Since you already did the hard work, I would mention it in the guide. Feel free to reassign it to yourself if you want.

@shawkins shawkins added this to the Backlog milestone Feb 15, 2024
@shawkins
Copy link
Contributor

@Pepo48 ok, let's move this to be a documentation issue in the backlog for now.

@shawkins shawkins added the missing/docs Documentation is missing label Feb 15, 2024
@vmuzikar
Copy link
Contributor

vmuzikar commented Feb 19, 2024

@Pepo48 @shawkins Would it make sense to fix it (add a note to docs) in 24? It's not the first time we've seen this issue – #26396 looks related.

@vmuzikar vmuzikar modified the milestones: Backlog, 24.0.0 Feb 19, 2024
@shawkins
Copy link
Contributor

@vmuzikar @Pepo48 we have two separate issues here.

This is an issue due to a resource conflict with an internal dependency,

#26396 is due to the order in which we're preforming the checks, as mentioned above. If we first check if the provider jars have changed, before checking the configuration, then #26396 mostly goes away.

On the internal resource conflict if my undestanding is correct we won't be making things better by simply reversing the checks - we don't really want the user to shadow anything that's built-in via the provider jars correct? In the case of a class we should see a split package warning. But there is currently no warning for something like application.properties. I don't know if we want to spend any effort towards this, or just stick to the documetnation plan.

@vmuzikar
Copy link
Contributor

#26396 is due to the order in which we're preforming the checks, as mentioned above.

Ah, right. I'll reopen #26396. Thanks for pointing that out.

we don't really want the user to shadow anything that's built-in via the provider jars correct?

Yeah, from my perspective users should use the built-in versions. We don't have a separate classpath for extensions.

I don't know if we want to spend any effort towards this, or just stick to the documetnation plan.

IMHO, documentation will do for now...

@shawkins shawkins self-assigned this Feb 21, 2024
shawkins added a commit to shawkins/keycloak that referenced this issue Feb 21, 2024
closes: keycloak#24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
shawkins added a commit to shawkins/keycloak that referenced this issue Feb 21, 2024
closes: keycloak#24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
shawkins added a commit to shawkins/keycloak that referenced this issue Feb 21, 2024
closes: keycloak#24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
shawkins added a commit to shawkins/keycloak that referenced this issue Feb 26, 2024
closes: keycloak#24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
shawkins added a commit to shawkins/keycloak that referenced this issue Feb 26, 2024
closes: keycloak#24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
@keycloak-github-bot keycloak-github-bot bot added priority/important Must be worked on very soon and removed action/priority-important labels Feb 29, 2024
@vmuzikar vmuzikar added priority/normal and removed priority/important Must be worked on very soon labels Feb 29, 2024
vmuzikar pushed a commit that referenced this issue Mar 1, 2024
closes: #24459

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
ahus1 pushed a commit to ahus1/keycloak that referenced this issue Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants