The spring.components file in not generated.
The problem is described in-depth in https://github.com/spring-projects/spring-framework/issues/22338.
As turns out, in Gradle 4.6+ (that includes Gradle 5.x - I have verified in Gradle 5.1.1 and 5.2), the correct declaration is annotationProcessor 'org.springframework:spring-context-indexer:5.1.4.RELEASE'.
More questions for the good folks from Spring Boot - should the spring.components file be created in ./BOOT-INF/classes/META-INF/spring.components? That's where is shows up for me, but I would expect it in ./META-INF/spring.components.
Also, how can I see that the file is indeed produced & used? Any flags to toggle? Any specific packages to turn verbose logging for? Any Actuator endpoint to look at?
Related
Problem summary: we've upgraded our Java 17 monolith application with multiple modules from Vaadin 21.0.1 to 23.3.5 and now our application routes don't resolve anymore, instead resulting in 404 Whitelabel errorpages.
This not being our first Vaadin rodeo (originating from Vaadin 7), we followed the Vaadin upgrade guide generator and expanded accordingly upon that.
Steps we took, each having been validated seperately:
Upgraded our backend to use Spring 5.3.18 (coming from 5.3.10). No issue there
Upgraded our frontend to use Spring Boot 2.6.7 (coming from 2.5.4). No issue there
this step was project-specific and not in the guide Removed Vaadin-addons from pom.xml. Also removed those imports from our package.json. Naturally removed all addons-code from application (EnhancedDialog and MultiselectComboBox -> using v23's regular Dialog and MultiSelectComboBox)
Removed webpack.config.js, package-lock.json and the node_modules folder
Raised global (-g) npm version to 9.4.0 (coming from 8.3.3)
Cleared npm with commandline npm cache clear --force
Upgraded the Vaadin flow version to 23.3.5 (coming from 21.0.1)
added the following dependency and reloaded the pom.xml:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-maven-plugin</artifactId>
<version>23.3.3</version>
</dependency>
Invalidated and restarted IntelliJ
ran clean-install Maven command through IntelliJ (with Production flag on/off makes no difference)
-> This results in a 404 whitelabel errorpage.
Next, I made sure that all our views annotated with com.vaadin.flow.router.#Route contained at least the javax.annotation.security.#PermitAll annotation.
I added spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration to our application.properties trying to get a more descriptive message.
-> This results in the Apache Tomcat errorpage with description: "The origin server did not find a current representation for the target resource or is not willing to disclose that one exists."
In both cases, the F12 DevTools are empty and showing nothing more than a 404 for the given URL.
So I continued debugging and validated that our custom security roles were validated correctly, a bit like this answer hinted at.
I'm getting into the breakpoints placed in the configure(HttpSecurity http) method from the WebSecurityConfigurerAdapter, but I'm unable to enter the serviceInit(ServiceInitEvent event) from the VaadinServiceInitListener.
I'm not a pro concerning servletRequests, but when hitting the isFrameworkInternalRequest(HttpServletRequest request) (called during the adapter's configuration), it seems only logical that for REQUEST_TYPE_PARAMETER a value of null is returned.
I was intrigued by these upgrade steps for an even higher Vaadin version, but nothing in there changed a bit for me.
When asked, I'd say that Spring isn't picking up on my views. Even the older #EnableVaadin() annotation did nothing. At this point I can't think straight anymore, even looking into the change of why Vaadin now uses vite.config.ts instead of webpack.config.js. Any pointers to where the issue might lay are immensely appreciated.
all credit to #Knoobie whose concise answer contained the correct solution.
Vaadin 23.3.x requires at least 2.7.x in order to work.
The Vaadin upgrade guide generator, when looking at the steps to migrate from v21 to v23, mistakenly referenced the minimum version of SpringBoot as 2.6.6. They will fix this in the immediate future.
I have a Spring Boot application that works as expected when ran with embedded tomcat, but I noticed that if I try to run it from an existing tomcat instance that I'm using with a previous project then it fails with a NoClassDefFoundError for a class that I don't use anywhere in my application.
I noticed in the /lib directory I had a single jar that contained a few Spring annotated classes, so as a test I cleaned out the /lib directory which resolved the issue. My assumption is that Spring is seeing some of the configurations/beans/imports on the classpath due to them existing in the /lib directory and either trying to autoconfigure something on its own, or is actually trying to instantiate some of these classes.
So then my question is - assuming I can't always fully control the contents of everything on the classpath, how can I prevent errors like this from occurring?
EDIT
For a little more detail - the class not being found is DefaultCookieSerializer which is part of the spring-session-implementation dependency. It is pulled into one of the classes in the jar located in /lib, but it is not any part of my application.
Check for features provided by #EnableAutoConfiguration. You can explicitly configure set of auto-configuration classes for your application. This tutorial can be a good starting point.
You can remove the #SpringBootApplication annotation from the main class and replace it with an #ComponentScan annotation and an #Import annotation that explicitly lists only the configuration classes you want to load. For example, in a Spring boot MVC app that uses metrics, web client, rest template, Jackson, etc, I was able to replace the #SpringBootApplication annotation with below code and get it working exactly as it was before, with all functional tests passing:
#Import({ MetricsAutoConfiguration.class,
InfluxMetricsExportAutoConfiguration.class,
ServletWebServerFactoryAutoConfiguration.class,
DispatcherServletAutoConfiguration.class,
WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class,
WebClientAutoConfiguration.class,
RestTemplateAutoConfiguration.class,
RefreshAutoConfiguration.class,
ValidationAutoConfiguration.class
})
#ComponentScan
The likely culprit of mentioned exception are incompatible jars on the classpath.
As we don't know with what library you have the issue we cant tell you the exact reason, but the situation looks like that:
One of Spring-Boot autoconfiguration classes is being triggered by the presence of class on the classpath
Trigerred configuration tries to create some bean of class that is not present in the jar you have (but it is in the specific version mentioned in the Spring BOM)
Version incompatibilities may also cause MethodNotFound exceptions.
That's one of the reasons why it is good practice not to run Spring Boot applications inside the container (make jar not war), but as a runnable jar with an embedded container.
Even before Spring Boot it was preferred to take account of libraries being present on runtime classpath and mark them as provided inside your project. Having different versions of the library on a classpath may cause weird ClassCastExceptions where on both ends names match, but the rest doesn't.
You could resolve specific cases by disabling autoconfiguration that causes your issue. You can do that either by adding exclude to your #SpringBootApplication or using a property file.
Edit:
If you don't use very broad package scan (or use package name from outside of your project in package scan) in your Spring Boot application it is unlikely that Spring Boot simply imports configuration from the classpath.
As I have mentioned before it is rather some autoconfiguration that is being triggered by existence of a class in the classpath.
Theoretical solution:
You could use maven shade plugin to relocate all packages into your own package space: see docs.
The problems is you'd have face:
Defining very broad relocation pattern that would exclude JEE classes that need to be used so that container would know how to run your application.
Relocation most likely won't affect package names used as strings in the Spring Boot annotations (like annotations #PackageScan or #ConditionalOnClass). As far as I know it is not implemented yet. You'd have to implement that by yourself - maybe as some kind of shade plugin resource processor.
When relocating classes you'd have to replace package names in all relevant configuration located in the jars. Possibly also merge some of those.
You'd also have to take into account how libraries that you use, or spring uses use package names or files.
This is definitely not a trivial tasks with many traps ahead. But if done right, then it would possibly allow you to disregard what is on the containers classpath. Spring Boot would also look for classes in relocated packages, and you wouldn't have those in ordinary jars.
The application is failing during the startup with this error:
The bean 'requestDataValueProcessor', defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/security/config/annotation/web/reactive/WebFluxSecurityConfiguration.class] and overriding is disabled.
All team members have the same problem and it seems that even if we're checking out an old git tag, the same problem persist. We've checked all the build files and dependencies, and nothing seemed to be changed in the last period of time. What's even more interesting is that the Bamboo seemed to run the build and the IT's pack with success with a day before, but today's morning it seem that the same issue is replicated there.
Not sure exactly why is complaining about WebMvcSecurityConfiguration, since we're using only reactive security in our project. So at this point we don't have any spring-mvc dependencies..
Does anyone have any clue ? Thx
So after we've enabled debug level logs on spring and force spring app to use only the reactive configurations like this:
spring:
main:
web-application-type: reactive
it seemed that the springfox dependencies were failing with:
java.lang.NoSuchMethodError: org.springframework.util.MultiValueMap.addIfAbsent(Ljava/lang/Object;Ljava/lang/Object;)V
at springfox.documentation.spring.web.scanners.ModelSpecificationRegistryBuilder.lambda$add$0(ModelSpecificationRegistryBuilder.java:37)
at java.base/java.util.Optional.ifPresent(Optional.java:183)
at springfox.documentation.spring.web.scanners.ModelSpecificationRegistryBuilder.add(ModelSpecificationRegistryBuilder.java:34)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at
So that error ^^^ point us towards sprinfox dependencies which were:
compile ("io.springfox:springfox-swagger-ui:3.0.0-SNAPSHOT")
compile ("io.springfox:springfox-swagger2:3.0.0-SNAPSHOT")
compile ("io.springfox:springfox-spring-webflux:3.0.0-SNAPSHOT")
After furthermore investigation, it seemed that some of those contains the spring-mvc dependency and that interfere with the spring-webflux one, and the application got confused which beans to inject.
We've downgrade those dependencies to 2.10.0, and everything seems to work now. My guess is that they've made some releases with that snapshot version and that include spring mvc, but until now it was absent. Lesson learned, never use some external libraries snapshots versions, otherwise you could end up in a very bad situation.
X.X.X-SNAPSHOT Dependencies are not the stable ones.
we were using <springfox.version>3.0.0-SNAPSHOT</springfox.version> which suddenly stopped working.
So below solution worked for us.
<springfox.version>2.10.5</springfox.version>
Cheers!!
I'm working with a 3rd party library implemented in Clojure which logs messages using clojure.tools.logging.
I want to suppress these messages in Eclipse and have tried the following suggestion to no avail.
Any (hacky) solutions greatly appreciated.
It sounds like your clojure.tools.logging is using a different underlying logging implementation than the rest of your application?
For example if your application is using java.util.logging, but you have a stray log4j library in your classpath, then clojure.tools.logging would detect log4j and would therefore not react to the logging config changes you were making.
The logic for detecting the underlying logging implementation is here:
https://github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging/impl.clj
Specifically:
(defn find-factory
"Returns the first non-nil value from slf4j-factory, cl-factory,
log4j-factory, and jul-factory."
[]
(or (slf4j-factory)
(cl-factory)
(log4j-factory)
(jul-factory)
(throw ; this should never happen in 1.5+
(RuntimeException.
"Valid logging implementation could not be found."))))
It would be helpful to run mvn dependency:tree or lein deps :tree to see what logging dependencies are on your classpath.
I have updated our projects (Java EE based running on Websphere 8.5) to use a new release of a company internal framework (and Ejb 3.x deployment descriptors rather than the 2.x ones). Since then my integration Tests fail with the following exception:
[java.lang.ClassNotFoundException: com.ibm.xml.xlxp2.jaxb.JAXBContextFactory]
I can build the application with the previous framework release and everything works fine.
While debugging i noticed that within the ContextFinder (javax.xml.bind) there are two different behaviours:
Previous Version (Everything works just fine): None of the different places brings up a factory class so the default factory class gets loaded which is com.sun.xml.internal.bind.v2.ContextFactory (defined as String constant within the class).
Upgraded Version (ClassNotFound): There is a resource "META-INF/services/javax.xml.bind.JAXBContext" beeing loaded successfully and the first line read makes the ContextFinder attempt to load "com.ibm.xml.xlxp2.jaxb.JAXBContextFactory" which causes the error.
I now have two questions:
What sort is that resource? Because inside our EAR there is two WARs and none of those two contains a folder services in its
META-INF directory.
Where could that value be from otherwise? Because a filediff showed me no new or changed properties files.
No need to say i am going to read all about the JAXB configuration possibilities but if you have first insights on what could have gone wrong or help me out with that resource (is it a real file i have to look for?) id appreciate a lot. Many Thanks!
EDIT (according to comments Input/Questions):
Out of curiosity, does your framework include JAXB JARs? Did the old version of your framework include jaxb.properties?
Indeed (i am a bit surprised) the framework has a customized eclipselink-2.4.1-.jar inside the EAR that includes both a JAXB implementation and a jaxb.properties file that shows the following entry in both versions (the one that finds the factory as well as in the one that throws the exception):
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
I think this is has nothing to do with the current issue since the jar stayed exactly the same in both EARs (the one that runs/ the one with the expection)
It's also not clear to me why the old version of the framework was ever selecting the com.sun implementation
There is a class javax.xml.bind.ContextFinder which is responsible for initializing the JAXBContextFactory. This class searches various placess for the existance of a jaxb.properties file or a "javax.xml.bind.JAXBContext" resource. If ALL of those places dont show up which Context Factory to use there is a deault factory loaded which is hardcoded in the class itself:
private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";
Now back to my problem:
Building with the previous version of the framework (and EJB 2.x deployment descriptors) everything works fine). While debugging i can see that there is no configuration found and thatfore above mentioned default factory is loaded.
Building with the new version of the framework (and EJB 3.x deployment descriptors so i can deploy) ONLY A TESTCASE fails but the rest of the functionality works (like i can send requests to our webservice and they dont trigger any errors). While debugging i can see that there is a configuration found. This resource is named "META-INF/services/javax.xml.bind.JAXBContext". Here are the most important lines of how this resource leads to the attempt to load 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory' which then throws the ClassNotFoundException. This is simplified source of the mentioned javax.xml.bind.ContextFinder class:
URL resourceURL = ClassLoader.getSystemResource("META-INF/services/javax.xml.bind.JAXBContext");
BufferedReader r = new BufferedReader(new InputStreamReader(resourceURL.openStream(), "UTF-8"));
String factoryClassName = r.readLine().trim();
The field factoryClassName now has the value 'com.ibm.xml.xlxp2.jaxb.JAXBContextFactory'
Because this has become a super lager question i will also add a bounty :)
I will work the entire day on this and let you know if there is any news.
Update/ Solution
This question has been solved. The original problem has occured because misconfiguration of complexly build multi model maven projects which one dependency used a updated version of a customized eclipse link jar that contained a definition for a JAXBFactory not available in the component where the error occured. Setting the JAXB context factory in most cases is configured with a jaxb.propertie file or JAXBContext file that contains the same definition. Detailed loading process of the appropriate JAXBContextFactory happens in javax.xml.bind.ContextFinder.
The error has not yet been solved (during the fact over 4 major EE/SE Applications lead to the error) and there is no general answer but that defined JAXBContextFactorys must exist in your classpath (wow what a wonder...) so you either have a that ClassNotFound Error because youre missing resources (well thats the acctual cause) or because you have a wrong JAXBContextFactory defined in any of the above mentioned propertie files which contain a definition according to the below answer.
Very many thanks for your great comments and support, i realy appreciate!
You can include a jaxb.properties file in the same package as your domain model to specify the JAXB (JSR-222) implementation you wish to use. For example it would look like the following to specify EclipseLink MOXy as your JAXB provider.
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
For More Information
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
Another quick and dirty solution (a workaround, really) that worked for me is to explicitly include a JAXB implementation to the maven build. For example
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.7</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.2.7</version>
</dependency>
Note that this adds a somehow unnecessary dependency to your build, as JAXB obviously already is part of each JRE >= version 6.
Most likely this will only work when the WAS classloader is set to parent last.