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

ClassLoader can't find resource since 2.7.0 #23511

Closed
camboui opened this issue Feb 8, 2022 · 7 comments · Fixed by #23512
Closed

ClassLoader can't find resource since 2.7.0 #23511

camboui opened this issue Feb 8, 2022 · 7 comments · Fixed by #23512
Assignees
Labels
area/bootstrap kind/bug Something isn't working
Milestone

Comments

@camboui
Copy link

camboui commented Feb 8, 2022

Describe the bug

Hi,

After updating from 2.6.3-Final to 2.7.0-FInal, I've been trying to load a certificate file with property:
quarkus.http.ssl.certificate.file=META-INF/certs/server.pem (I know it's deprecated)
but it ended with a "FileNotFoundException".

After digging a bit, using this property then calls Thread.currentThread().getContextClassLoader().getResourceAsStream(path); in VertxHttpRecorder.java

I used this same code in a simple OnStart and observed the same behaviour.

I tried to dig further using debgger but only found that getResourceAsStream() from QuarkusClassLoader.java behaviour differs :
- 2.6.3 : 'elements' property contains [MemoryClassPathElement, DirectoryClassPathElement]
- 2.7.0 : 'elements' property contains [MemoryClassPathElement, PathTreeClassPathElement]

Expected behavior

File's loaded

Actual behavior

File's not found, FileNotFoundException

How to Reproduce?

1 - Download default zip from https://code.quarkus.io/

2 - Add class

@ApplicationScoped
public class AppLifecycleBean {

    void onStart(@Observes StartupEvent ev) {
        // Method invoked by VertxHttpRecorder to initialize property "quarkus.http.ssl.certificate.file"
        // Works in 2.6.3 but null in 2.7.0
        var pathValue = "META-INF/certs/server.pem";
        var path = Path.of(pathValue);
        var inputStreamNullResult = Thread.currentThread().getContextClassLoader().getResourceAsStream(path.toString());

        // Works with any version using String directly
        // Maybe something to do with Windows path somewhere ?
        var inputStreamOkResult = Thread.currentThread().getContextClassLoader().getResourceAsStream(pathValue);

        /* Note that might help digging: using debugger during getResourceAsStream() in QuarkusClassLoader.java:
         - 2.6.3 : 'elements' property contains [MemoryClassPathElement, DirectoryClassPathElement]
         - 2.7.0 : 'elements' property contains [MemoryClassPathElement, PathTreeClassPathElement]
         */
    }

}

3 - Add any file in resources directory, "META-INF/certs/server.pem"

4 - Switch from version 2.6.3-Final and 2.7.0-Final to observe that inputStream is null in 2.7.0-Final.

Output of uname -a or ver

Windows 10

Output of java -version

openjdk 11.0.10 2021-01-19

GraalVM version (if different from Java)

No response

Quarkus version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.4

Additional information

No response

@camboui camboui added the kind/bug Something isn't working label Feb 8, 2022
@quarkus-bot quarkus-bot bot added env/windows Impacts Windows machines triage/needs-triage labels Feb 8, 2022
@geoand
Copy link
Contributor

geoand commented Feb 8, 2022

cc @aloubyansky

@geoand geoand added area/bootstrap and removed triage/needs-triage env/windows Impacts Windows machines labels Feb 8, 2022
@aloubyansky aloubyansky self-assigned this Feb 8, 2022
@aloubyansky
Copy link
Member

Sure, if the path argument uses \ as a separator, it's not expected to work. If you read the javadoc for java.lang.ClassLoader.getResource(String):

The name of a resource is a '/'-separated path name that identifies the resource.

@gsmet
Copy link
Member

gsmet commented Feb 8, 2022

@aloubyansky I'm a bit confused, I see / in the report?

@aloubyansky
Copy link
Member

The property, right. The config option is mapped to java.nio.file.Path. I'll fix it. My comment was about the code in the class.

@aloubyansky
Copy link
Member

Thanks for reporting the issue @camboui

@camboui
Copy link
Author

camboui commented Feb 8, 2022

You're welcome :)

I still can't figure out what changed between 2.6.3 and 2.7.0 to break this, even after some source diving and diff matching. I can't sleep with it ! Do you have a any clue ? (If you don't have time, don't bother 😉 )

@aloubyansky
Copy link
Member

As you noticed we have a new ClassPathElement implementation in 2.7 which pretty much replaces Jar- and Directory- ClassPathElement impl. And now we appear to be more strict when it comes to the resource names. So it's a bug in the VertxHttpRecorder that is calling Path.toString() expecting it always be a valid resource name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/bootstrap kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants