Open chineduekwunife opened 5 years ago
Trying to load a resource that isn't on the classpath returns null
so it seems likely that is what is causing the NPE, if you look in your target directory, did the swagger-ui
directory get copied somewhere there when you built your project? Also, when you run, is that somwhere added to the classpath (you can inspect your JVM process classpath with jvisualvm or jinfo
)?
Trying to load a resource that isn't on the classpath returns
null
so it seems likely that is what is causing the NPE, if you look in your target directory, did theswagger-ui
directory get copied somewhere there when you built your project? Also, when you run, is that somwhere added to the classpath (you can inspect your JVM process classpath with jvisualvm orjinfo
)?
@johanandren
I've inspected the jar file and can find swagger-ui files in the classpath
c@c-VirtualBox:~/Projects/java/akka-spring-docker/code/akka-spring-docker-system/target$ jar -tf akka-spring-docker-system-1.0-SNAPSHOT.jar | grep swagger
BOOT-INF/classes/swagger-ui/
BOOT-INF/classes/swagger-ui/lib/
BOOT-INF/classes/swagger-ui/css/
BOOT-INF/classes/swagger-ui/images/
BOOT-INF/classes/swagger-ui/fonts/
BOOT-INF/classes/swagger-ui/lib/highlight.7.3.pack.js
BOOT-INF/classes/swagger-ui/lib/swagger-oauth.js
BOOT-INF/classes/swagger-ui/lib/underscore-min.map
BOOT-INF/classes/swagger-ui/index.html
BOOT-INF/classes/swagger-ui/images/pet_store_api.png
BOOT-INF/classes/swagger-ui/images/logo_small.png
BOOT-INF/classes/swagger-ui/images/favicon.ico
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.woff2
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.svg
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.ttf
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.eot
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.svg
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.woff
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.ttf
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.woff
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.woff2
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.eot
BOOT-INF/classes/swagger-ui/lib/marked.js
BOOT-INF/classes/swagger-ui/lib/underscore-min.js
BOOT-INF/classes/swagger-ui/lib/backbone-min.js
BOOT-INF/classes/swagger-ui/lib/jquery.slideto.min.js
BOOT-INF/classes/swagger-ui/lib/jquery-1.8.0.min.js
BOOT-INF/classes/swagger-ui/lib/handlebars-2.0.0.js
BOOT-INF/classes/swagger-ui/lib/jquery.wiggle.min.js
BOOT-INF/classes/swagger-ui/lib/jquery.ba-bbq.min.js
BOOT-INF/classes/swagger-ui/css/reset.css
BOOT-INF/classes/swagger-ui/css/print.css
BOOT-INF/classes/swagger-ui/css/screen.css
BOOT-INF/classes/swagger-ui/css/typography.css
BOOT-INF/classes/swagger-ui/images/favicon-32x32.png
BOOT-INF/classes/swagger-ui/images/throbber.gif
BOOT-INF/classes/swagger-ui/images/wordnik_api.png
BOOT-INF/classes/swagger-ui/images/explorer_icons.png
BOOT-INF/classes/swagger-ui/images/favicon-16x16.png
BOOT-INF/classes/swagger-ui/o2c.html
BOOT-INF/classes/swagger-ui/swagger-ui.js
BOOT-INF/classes/swagger-ui/swagger-ui.min.js
BOOT-INF/lib/swagger-akka-http_2.12-0.14.0.jar
BOOT-INF/lib/swagger-core-1.5.18.jar
BOOT-INF/lib/swagger-annotations-1.5.18.jar
BOOT-INF/lib/swagger-models-1.5.18.jar
BOOT-INF/lib/swagger-jaxrs-1.5.18.jar
@johanandren
A closer look at the code in FileAndResourceDirectives.scala, seems that null is returned for directories, which might explain the NPE.
case "jar" ⇒
val path = new URI(url.getPath).getPath // remove "file:" prefix and normalize whitespace
val bangIndex = path.indexOf('!')
val filePath = path.substring(0, bangIndex)
val resourcePath = path.substring(bangIndex + 2)
val jar = new java.util.zip.ZipFile(filePath)
try {
val entry = jar.getEntry(resourcePath)
if (entry.isDirectory) None
else Option(jar.getInputStream(entry)) map { is ⇒
is.close()
ResourceFile(url, entry.getSize, entry.getTime)
}
} finally jar.close()
Doc on ZipFile.getEntry
says null
if not found. So I think the entry you expect is missing somehow. We should probably handle that and return a None
if entry is null
rather than fail though.
Doc on
ZipFile.getEntry
saysnull
if not found. So I think the entry you expect is missing somehow. We should probably handle that and return aNone
if entry isnull
rather than fail though.
Probably, it's because the BOOT-INF
part of the resource path is missing?
I guess, before we added the entry.isDirectory
part, Option(jar.getInputStream(entry))
was actually guarding against missing files but now it fails even before and it seems we are missing a test case for the case when getFromResource
points to a missing file.
Btw:
path("swagger", () -> route (
getFromResource("swagger-ui/index.html"),
getFromResourceDirectory("swagger-ui")
)
I wonder why that works at all. Shouldn't getFromResource("swagger-ui/index.html"),
be guarded by pathEndOrSingleSlash
or something else?
@johanandren @jrudolph
The exception is thrown at line 286 of FileAndResourceDirectives.scala if (entry.isDirectory) None
Which suggests that the entry is present, but because it is a directory, None was returned which will cause a NPE.
Also, I added pathEndOrSingleSlash and got the same NPE result as before.
Route createRoute() {
return route(
path(PathMatchers.segment(generator.apiDocsPath()).slash("swagger.yaml"),
() -> get(() -> complete(generator.generateSwaggerYaml()))),
path(PathMatchers.segment(generator.apiDocsPath()).slash("swagger.json"),
() -> get(() -> complete(generator.generateSwaggerJson()))),
path("swagger", () -> route (
pathEndOrSingleSlash(() -> getFromResource("swagger-ui/index.html")),
pathEndOrSingleSlash(() -> getFromResourceDirectory("swagger-ui"))
)
)
);
}
It's not because None
is returned, it is because entry
is null, which causes a NPE when we try to call isDirectory
on it.
OK then, so below comment from @jrudolph could be the fix for jar files
Probably, it's because the BOOT-INF part of the resource path is missing?
Probably, it's because the
BOOT-INF
part of the resource path is missing?
Actually, that statement was a bit sloppy. In fact, it depends how your classloaders are set up. It seems you are using some spring stuff, so it will depend on how your application is deployed exactly (we cannot really help with that).
Regarding your routes, this is still not correct:
path("swagger", () -> route (
pathEndOrSingleSlash(() -> getFromResource("swagger-ui/index.html")),
pathEndOrSingleSlash(() -> getFromResourceDirectory("swagger-ui"))
)
It should be more like this:
pathPrefix("swagger", () -> route ( // everything that's inside `/swagger`
pathEndOrSingleSlash(() -> getFromResource("swagger-ui/index.html")), // `/swagger/` or `/swagger`
getFromResourceDirectory("swagger-ui") // everything else in `/swagger/...`
)
I marked this issue as a bug, because we need to improve the error message and not throw an NPE when a resource cannot be found.
The classloader / spring issue probably isn't a bug so it would make sense to continue those discussions on discuss.akka.io.
@jrudolph Most java applications use Spring, so I think it'll make sense to add support for Spring class loaders. For reference, below is the full content of the files in my jar file
c@c-VirtualBox:~/Projects/java/akka-spring-docker/code/akka-spring-docker-system/target$ jar -tf akka-spring-docker-system-1.0-SNAPSHOT.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/springframework/
org/springframework/boot/
org/springframework/boot/loader/
org/springframework/boot/loader/data/
org/springframework/boot/loader/data/RandomAccessDataFile$1.class
org/springframework/boot/loader/data/RandomAccessDataFile$DataInputStream.class
org/springframework/boot/loader/jar/
org/springframework/boot/loader/jar/JarFileEntries$1.class
org/springframework/boot/loader/jar/JarFileEntries$EntryIterator.class
org/springframework/boot/loader/jar/JarFileEntries.class
org/springframework/boot/loader/jar/CentralDirectoryVisitor.class
org/springframework/boot/loader/jar/JarEntryFilter.class
org/springframework/boot/loader/jar/CentralDirectoryFileHeader.class
org/springframework/boot/loader/jar/CentralDirectoryEndRecord.class
org/springframework/boot/loader/jar/CentralDirectoryParser.class
org/springframework/boot/loader/jar/ZipInflaterInputStream.class
org/springframework/boot/loader/jar/Handler.class
org/springframework/boot/loader/archive/
org/springframework/boot/loader/archive/Archive$Entry.class
org/springframework/boot/loader/archive/Archive$EntryFilter.class
org/springframework/boot/loader/archive/Archive.class
org/springframework/boot/loader/archive/ExplodedArchive$FileEntryIterator$EntryComparator.class
org/springframework/boot/loader/archive/ExplodedArchive$FileEntryIterator.class
org/springframework/boot/loader/archive/ExplodedArchive$FileEntry.class
org/springframework/boot/loader/archive/ExplodedArchive$1.class
org/springframework/boot/loader/archive/ExplodedArchive.class
org/springframework/boot/loader/archive/JarFileArchive$EntryIterator.class
org/springframework/boot/loader/archive/JarFileArchive$JarFileEntry.class
org/springframework/boot/loader/archive/JarFileArchive.class
org/springframework/boot/loader/PropertiesLauncher$PrefixMatchingArchiveFilter.class
org/springframework/boot/loader/PropertiesLauncher$ArchiveEntryFilter.class
org/springframework/boot/loader/PropertiesLauncher$1.class
org/springframework/boot/loader/PropertiesLauncher.class
org/springframework/boot/loader/Launcher.class
org/springframework/boot/loader/MainMethodRunner.class
org/springframework/boot/loader/ExecutableArchiveLauncher.class
org/springframework/boot/loader/WarLauncher.class
org/springframework/boot/loader/JarLauncher.class
org/springframework/boot/loader/util/
org/springframework/boot/loader/util/SystemPropertyUtils.class
org/springframework/boot/loader/LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
org/springframework/boot/loader/LaunchedURLClassLoader.class
org/springframework/boot/loader/data/RandomAccessData.class
org/springframework/boot/loader/jar/AsciiBytes.class
org/springframework/boot/loader/data/RandomAccessDataFile.class
org/springframework/boot/loader/data/RandomAccessDataFile$FileAccess.class
org/springframework/boot/loader/jar/JarURLConnection$1.class
org/springframework/boot/loader/jar/Bytes.class
org/springframework/boot/loader/jar/JarURLConnection$JarEntryName.class
org/springframework/boot/loader/jar/JarURLConnection.class
org/springframework/boot/loader/jar/JarFile$1.class
org/springframework/boot/loader/jar/JarFile$2.class
org/springframework/boot/loader/jar/JarFile$JarFileType.class
org/springframework/boot/loader/jar/JarFile.class
org/springframework/boot/loader/jar/JarEntry.class
org/springframework/boot/loader/jar/FileHeader.class
org/springframework/boot/loader/jar/StringSequence.class
BOOT-INF/
BOOT-INF/classes/
BOOT-INF/classes/com/
BOOT-INF/classes/com/nedu/
BOOT-INF/classes/com/nedu/akkahttp/
BOOT-INF/classes/com/nedu/akkahttp/config/
BOOT-INF/classes/com/nedu/akkahttp/routes/
BOOT-INF/classes/swagger-ui/
BOOT-INF/classes/swagger-ui/lib/
BOOT-INF/classes/swagger-ui/css/
BOOT-INF/classes/swagger-ui/images/
BOOT-INF/classes/swagger-ui/fonts/
META-INF/maven/
META-INF/maven/com.nedu.akka-http/
META-INF/maven/com.nedu.akka-http/akka-spring-docker-system/
BOOT-INF/classes/application.conf
BOOT-INF/classes/com/nedu/akkahttp/config/SpringActorProducer.class
BOOT-INF/classes/com/nedu/akkahttp/config/AkkaSpringConfig.class
BOOT-INF/classes/com/nedu/akkahttp/Application.class
BOOT-INF/classes/com/nedu/akkahttp/SwaggerRunner.class
BOOT-INF/classes/com/nedu/akkahttp/routes/UserRoutes.class
BOOT-INF/classes/com/nedu/akkahttp/routes/AppRoutes.class
BOOT-INF/classes/com/nedu/akkahttp/AppRunner.class
BOOT-INF/classes/com/nedu/akkahttp/SwaggerRunner$1.class
BOOT-INF/classes/application.properties
BOOT-INF/classes/swagger-ui/lib/highlight.7.3.pack.js
BOOT-INF/classes/swagger-ui/lib/swagger-oauth.js
BOOT-INF/classes/swagger-ui/lib/underscore-min.map
BOOT-INF/classes/swagger-ui/lib/marked.js
BOOT-INF/classes/swagger-ui/lib/underscore-min.js
BOOT-INF/classes/swagger-ui/lib/backbone-min.js
BOOT-INF/classes/swagger-ui/lib/jquery.slideto.min.js
BOOT-INF/classes/swagger-ui/lib/jquery-1.8.0.min.js
BOOT-INF/classes/swagger-ui/lib/handlebars-2.0.0.js
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.woff2
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.svg
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.ttf
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.eot
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.svg
BOOT-INF/classes/com/nedu/akkahttp/Supervisor.class
BOOT-INF/classes/swagger-ui/css/reset.css
BOOT-INF/classes/swagger-ui/css/print.css
BOOT-INF/classes/swagger-ui/css/typography.css
BOOT-INF/classes/swagger-ui/index.html
BOOT-INF/classes/swagger-ui/images/throbber.gif
BOOT-INF/classes/swagger-ui/images/favicon.ico
BOOT-INF/classes/swagger-ui/o2c.html
BOOT-INF/classes/swagger-ui/swagger-ui.min.js
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.woff
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.ttf
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.woff
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-regular.woff2
BOOT-INF/classes/swagger-ui/fonts/droid-sans-v6-latin-700.eot
BOOT-INF/classes/git.properties
META-INF/maven/com.nedu.akka-http/akka-spring-docker-system/pom.xml
META-INF/maven/com.nedu.akka-http/akka-spring-docker-system/pom.properties
BOOT-INF/classes/com/nedu/akkahttp/config/SpringExtension.class
BOOT-INF/classes/swagger-ui/lib/jquery.wiggle.min.js
BOOT-INF/classes/swagger-ui/lib/jquery.ba-bbq.min.js
BOOT-INF/classes/swagger-ui/css/screen.css
BOOT-INF/classes/swagger-ui/images/favicon-32x32.png
BOOT-INF/classes/swagger-ui/images/pet_store_api.png
BOOT-INF/classes/swagger-ui/images/logo_small.png
BOOT-INF/classes/swagger-ui/images/wordnik_api.png
BOOT-INF/classes/swagger-ui/images/explorer_icons.png
BOOT-INF/classes/swagger-ui/images/favicon-16x16.png
BOOT-INF/classes/swagger-ui/swagger-ui.js
BOOT-INF/lib/
BOOT-INF/lib/actor-common-1.0-SNAPSHOT.jar
BOOT-INF/lib/event-log-1.0-SNAPSHOT.jar
BOOT-INF/lib/user-registry-1.0-SNAPSHOT.jar
BOOT-INF/lib/swagger-akka-http_2.12-0.14.0.jar
BOOT-INF/lib/scala-library-2.12.4.jar
BOOT-INF/lib/scala-java8-compat_2.12-0.8.0.jar
BOOT-INF/lib/swagger-core-1.5.18.jar
BOOT-INF/lib/commons-lang3-3.7.jar
BOOT-INF/lib/jackson-annotations-2.9.0.jar
BOOT-INF/lib/validation-api-2.0.1.Final.jar
BOOT-INF/lib/swagger-annotations-1.5.18.jar
BOOT-INF/lib/swagger-models-1.5.18.jar
BOOT-INF/lib/slf4j-api-1.7.25.jar
BOOT-INF/lib/jackson-module-scala_2.12-2.9.6.jar
BOOT-INF/lib/scala-reflect-2.12.6.jar
BOOT-INF/lib/jackson-core-2.9.6.jar
BOOT-INF/lib/jackson-module-paranamer-2.9.6.jar
BOOT-INF/lib/paranamer-2.8.jar
BOOT-INF/lib/jackson-dataformat-yaml-2.9.6.jar
BOOT-INF/lib/swagger-jaxrs-1.5.18.jar
BOOT-INF/lib/jackson-databind-2.9.6.jar
BOOT-INF/lib/jsr311-api-1.1.1.jar
BOOT-INF/lib/reflections-0.9.11.jar
BOOT-INF/lib/javassist-3.21.0-GA.jar
BOOT-INF/lib/guava-20.0.jar
BOOT-INF/lib/javax.ws.rs-api-2.1.1.jar
BOOT-INF/lib/akka-http-cors_2.12-0.3.0.jar
BOOT-INF/lib/spring-boot-starter-2.0.5.RELEASE.jar
BOOT-INF/lib/spring-boot-2.0.5.RELEASE.jar
BOOT-INF/lib/spring-boot-autoconfigure-2.0.5.RELEASE.jar
BOOT-INF/lib/spring-boot-starter-logging-2.0.5.RELEASE.jar
BOOT-INF/lib/logback-classic-1.2.3.jar
BOOT-INF/lib/logback-core-1.2.3.jar
BOOT-INF/lib/log4j-to-slf4j-2.10.0.jar
BOOT-INF/lib/log4j-api-2.10.0.jar
BOOT-INF/lib/jul-to-slf4j-1.7.25.jar
BOOT-INF/lib/javax.annotation-api-1.3.2.jar
BOOT-INF/lib/spring-core-5.0.9.RELEASE.jar
BOOT-INF/lib/spring-jcl-5.0.9.RELEASE.jar
BOOT-INF/lib/snakeyaml-1.19.jar
BOOT-INF/lib/spring-boot-starter-jdbc-2.0.5.RELEASE.jar
BOOT-INF/lib/spring-jdbc-5.0.9.RELEASE.jar
BOOT-INF/lib/spring-tx-5.0.9.RELEASE.jar
BOOT-INF/lib/akka-http_2.12-10.1.5.jar
BOOT-INF/lib/akka-http-core_2.12-10.1.5.jar
BOOT-INF/lib/akka-parsing_2.12-10.1.5.jar
BOOT-INF/lib/akka-stream_2.12-2.5.17.jar
BOOT-INF/lib/akka-actor_2.12-2.5.17.jar
BOOT-INF/lib/config-1.3.3.jar
BOOT-INF/lib/akka-protobuf_2.12-2.5.17.jar
BOOT-INF/lib/reactive-streams-1.0.2.jar
BOOT-INF/lib/ssl-config-core_2.12-0.2.4.jar
BOOT-INF/lib/scala-parser-combinators_2.12-1.1.1.jar
BOOT-INF/lib/akka-http-jackson_2.12-10.1.5.jar
BOOT-INF/lib/akka-slf4j_2.12-2.5.17.jar
BOOT-INF/lib/lombok-1.18.2.jar
BOOT-INF/lib/jool-java-8-0.9.13.jar
BOOT-INF/lib/spring-context-5.0.9.RELEASE.jar
BOOT-INF/lib/spring-aop-5.0.9.RELEASE.jar
BOOT-INF/lib/spring-beans-5.0.9.RELEASE.jar
BOOT-INF/lib/spring-expression-5.0.9.RELEASE.jar
BOOT-INF/lib/jooq-3.10.8.jar
BOOT-INF/lib/jooq-meta-extensions-3.10.8.jar
BOOT-INF/lib/h2-1.4.197.jar
BOOT-INF/lib/hibernate-core-5.2.17.Final.jar
BOOT-INF/lib/jboss-logging-3.3.2.Final.jar
BOOT-INF/lib/hibernate-jpa-2.1-api-1.0.2.Final.jar
BOOT-INF/lib/antlr-2.7.7.jar
BOOT-INF/lib/jboss-transaction-api_1.2_spec-1.0.1.Final.jar
BOOT-INF/lib/jandex-2.0.3.Final.jar
BOOT-INF/lib/classmate-1.3.4.jar
BOOT-INF/lib/dom4j-1.6.1.jar
BOOT-INF/lib/hibernate-commons-annotations-5.0.1.Final.jar
BOOT-INF/lib/jooq-meta-3.10.8.jar
BOOT-INF/lib/jooq-codegen-maven-3.10.8.jar
BOOT-INF/lib/jooq-codegen-3.10.8.jar
BOOT-INF/lib/maven-plugin-api-2.2.1.jar
BOOT-INF/lib/maven-project-2.2.1.jar
BOOT-INF/lib/maven-settings-2.2.1.jar
BOOT-INF/lib/maven-profile-2.2.1.jar
BOOT-INF/lib/maven-model-2.2.1.jar
BOOT-INF/lib/maven-artifact-manager-2.2.1.jar
BOOT-INF/lib/maven-repository-metadata-2.2.1.jar
BOOT-INF/lib/wagon-provider-api-1.0-beta-6.jar
BOOT-INF/lib/backport-util-concurrent-3.1.jar
BOOT-INF/lib/maven-plugin-registry-2.2.1.jar
BOOT-INF/lib/plexus-interpolation-1.11.jar
BOOT-INF/lib/plexus-utils-1.5.15.jar
BOOT-INF/lib/maven-artifact-2.2.1.jar
BOOT-INF/lib/plexus-container-default-1.0-alpha-9-stable-1.jar
BOOT-INF/lib/classworlds-1.1-alpha-2.jar
BOOT-INF/lib/postgresql-42.2.5.jar
BOOT-INF/lib/HikariCP-3.2.0.jar
BOOT-INF/lib/junit-4.12.jar
BOOT-INF/lib/hamcrest-core-1.3.jar
It doesn't only depend on the contents of jar files but how the custom classloaders in your environment deal with those jar files. That's something we cannot debug here (but if you find out, it would make sense to add to the documentation).
@jrudolph I got it working by adding BOOT-INF to the path as follows
return route(
path(PathMatchers.segment(generator.apiDocsPath()).slash("swagger.yaml"),
() -> get(() -> complete(generator.generateSwaggerYaml()))),
path(PathMatchers.segment(generator.apiDocsPath()).slash("swagger.json"),
() -> get(() -> complete(generator.generateSwaggerJson()))),
pathPrefix("swagger", () -> route ( // everything that's inside `/swagger`
pathEndOrSingleSlash(() -> getFromResource("BOOT-INF/classes/swagger-ui/index.html")), // `/swagger/` or `/swagger`
getFromResourceDirectory("BOOT-INF/classes/swagger-ui") // everything else in `/swagger/...`
)
));
@chineduekwunife-kcom great!
Ran into the exact same problem. When trying to pull a resource using getFromResource when in a spring boot classloader is in the mix... null reference is throw when it cannot find the resourcePath.
I don't think it's been said... Spring Boot class loader is doing this to the resource url ... BOOT-INF/classes!/swagger/index.html ----notice the ! -----^
I know this is an implementation detail brought to you by Spring Boot & Company (see https://github.com/spring-projects/spring-boot/issues/7096), but can't akka-http team provide a simple directive for handling boot loader implementation rather than guys like us having to write hacks or custom directives for a spring boot class loader? The above direct path to BOOT-INF is kinda hacky and will only work when referring to resource directory from jar.
Maybe, even if it's completely unrelated to akka-http, let's document for the getFromResource*
directives that your resources might have different paths than expected? For getFromResource
we should create a better exception if a resource isn't found.
For
getFromResource
we should create a better exception if a resource isn't found.
I guess it already works correctly for simple class loaders. It seems that the spring class loader delivers an invalid URL for ClassLoader.getResource
even if a resource cannot be found (when it should return null
). Not sure if we can or should do something about this (other than adding documentation).
I'm trying out AKKA-Http in Java for the first time(akka-http_2.12 v 10.1.5, akka-stream_2.12 v 2.5.17), but can't seem to load static content for swagger UI. I've added the routes below and able to reach the json and yaml swagger endpoints via http://localhost:8080/api-docs/swagger.json and http://localhost:8080/api-docs/swagger.yaml However, the swagger UI endpoint i.e http://localhost:8080/swagger returns with 'There was an internal server error.' even though I have swagger-ui directory under src/main/resources folder. I've inspected the logs and don't quite understand what is happening..seems like a bug in getFromResource and getFromResourceDirectory functions. Similar issue was reported earlier