I'm actually not certain if this is actually fixable as long as spring boot doesn't have its own module-info. Note: this results in a stacktrace later on startup, but I think this log is the root cause of that.
Failed to bind properties under 'spring.datasource' to org.springframework.boot.autoconfigure.jdbc.DataSourceProperties:
Reason: java.lang.ClassNotFoundException: javax.sql.DataSource
Caused by: java.lang.ClassNotFoundException: java.sql.SQLException
at spring.boot@3.3.0/org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader.loadClass(TomcatEmbeddedWebappClassLoader.java:72) ~[spring-boot-3.3.0.jar:na]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1144) ~[tomcat-embed-core-10.1.24.jar:10.1.24]
adding this to module-info.java will fix
requires java.sql;
boot 3.3.0 java 17
Comment From: mhalbritter
Hello,
starting it from IntelliJ gives me the stacktrace you've shown, however, ./gradlew bootRun and running the uber jar both works fine.
How do you run such uber JARs with a module info from the commandline?
Comment From: xenoterracide
I don't know why they would but does bootrun and the Uber jar preserve the module path correctly? I can't imagine that the Uber jar preserves the module path... Because then everything is packed as one jar I don't know how that would work.
As far as Boot run goes I don't really know but that does for the module path either. I do know if you run it with IntelliJ but you delete that module info file that it will work just fine which is why I'm convinced that the other two methods are simply not running things using the module path meaning jpms isn't actually active.
Comment From: mhalbritter
Yeah, I suspect that as well. But how would you run this application with a module-info in it on the commandline so that JPMS is active? Or asked the other way around: Why's there a module-info in it, if running the application ignores the whole JPMS anyway?
Comment From: xenoterracide
I mostly use jpms for compile time constraints. Gradles constraints are better than mavens but it still results in transients being available.
Sadly because most things only use automatic modules there aren't really runtime gains. Maybe someday, but it isn't looking like it because we aren't able to get people to buy into full modules... Will get the ability to do things like jlink and strip out unneeded jars, in theory at that point you might also get class bath scanning improvements. I don't really know that because I haven't really tested it. Sounds like a nice theory though that if you can't scan a jar in theory it's going to go faster right if you can only scan the ones you can actually access?
I'm packing it in for the night so I'll get back to you on a command line run tomorrow... The problem that you're having with the command line run though isn't so much that it's difficult to run something on the command line it's that you're going to have to put like a hundred jars together to do it... I think if you tell IntelliJ not to run the app through Gradle that in the runner you will see a command line output that you could use to reproduce this. Anyways I'll look Tomorrow if you don't figure it out tonight or whatever time it is there.
Comment From: mhalbritter
I mostly use jpms for compile time constraints
I see, thanks.
. I think if you tell IntelliJ not to run the app through Gradle that in the runner you will see a command line output that you could use to reproduce this
No worries, I can reproduce it with IntelliJ. I was just curious why you deal with JPMS when you can't run it with JPMS active - which you explained :)
Comment From: xenoterracide
@mhalbritter so, if that is the fix and only that, I think I'd prefer that it isn't fixed. It would have taken me hours to find it without the exception. AFAIK the only way this can happen right now is via JPMS. My personal hope was to find a way to have spring boot add the module. If it can't then I see 2 good options
- do nothing
- leave issue open and add some kind of a jpms tag so that as to come back later
- close and do similar thing to know that you can't fix now, but re-open? if full modules can be supported.
- just close, I understand, although I think breadcrumbs for later is better than just close
- catch the exception and give a better error since this can only happen with JPMS
Comment From: xenoterracide
@mhalbritter
No worries, I can reproduce it with IntelliJ. I was just curious why you deal with JPMS when you can't run it with JPMS active - which you explained :)
I haven't tested this, but the layered docker build might also reproduce this, since it should happen once everything is in it's own respective jars.
Comment From: wilkinsona
It would have taken me hours to find it without the exception.
The condition evaluation report should help with that. It will now report that the auto-configuration backed off because DataSource, a class in the java.sql module, was absent.
AFAIK the only way this can happen right now is via JPMS. My personal hope was to find a way to have spring boot add the module
We wouldn't want to do that as we have no way of knowing if the absence of the java.sql module is intentional. There are also scenarios where the module isn't there at all, for example when using jlink.
catch the exception and give a better error since this can only happen with JPMS
I don't think we should apply special treatment for classes that can only be absent when using the module system. For consistency, we should use conditions to detect their presence or absence and the evaluation of these conditions will be reported as they are with any other class on either the module path or the class path.
Comment From: xenoterracide
Fair enough. If Spring Boot ever gets a full module-info, would it include a requires java.sql?
actually it would have to unless ya'll implement in such a way that it doesn't affect your compile time, although it could be requires static...
I'm curious because it feels weird that I'd add it since my dependency is indirect. Although maybe this is something that should be getting added by spring data jpa... that would probably make sense. long term thought.. maybe autoconfigures should go into their own jars... as modularization makes this messier.