Spring-webflux application startup failures - java

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!!

Related

Vaadin 23 not resolving URL's, instead showing errorpage

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.

Possible to ignore configuration classes on the classpath?

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.

Components index generated by spring-context-indexer seems to do nothing

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?

WFLYEE0040: A component named '...' is already defined in this module

I get this error in a Java maven project. The weird thing is, it doesn't appear on every machine so I assume it has something to do with a configuration issue.
The class RoleKeyCacheImpl is a #Startup #Singleton:
#Startup
#Singleton
public class RoleKeyCacheImpl implements RoleKeyCache { ... }
That's the error Wildfly triggers when deploying the service.
Caused by: java.lang.IllegalArgumentException: WFLYEE0040: A component
named 'RoleKeyCacheImpl' is already defined in this module at
org.jboss.as.ee.component.EEModuleDescription.addComponent(EEModuleDescription.java:167)
at
org.jboss.as.ejb3.deployment.processors.EJBComponentDescriptionFactory.addComponent(EJBComponentDescriptionFactory.java:58)
I've tried:
installing a new Wildfly (V10, V13) on the same machine -> doesn't help
installing a completely new Eclipse on this machine -> doesn't help
cleaning & rebuilding all related projects
making sure the deployments-folder is empty and doesn't contain old versions of the same WAR
read the related question here which also didn't help (they use Spring): A component named 'XXX' is already defined in this module in JBoss 7.1.1
read and tried this q&a: Wrong dependencies with EJB in JBoss Wildfly (server-clean) -> doesn't help
deleted and rebuilt the local maven rep (".m2") -> no effect
checking out the same source on another computer -> does work on one machine, on another it gives the same error
I have absolutely no clue what the issue is or even could be. On one machine, we check it out and it runs without errors. On others, the exact same error happens.
Does anybody have an idea?
I had this same issue multiple times with EAP 7.1 and now again with WildFly 21.0.0. I know by experience this is an issue caused by Eclipse who tries to deploy automatically to a configured WildFly instance. During the deployment (or undeployment) some concurrent file issue arises and files who should be removed, are still on the filesystem, causing this error that a component is already defined.
In fact it is not already defined, it is just WildFly that is confused because it finds in his temporary directories some old files which shouldn't be there and reference your exact same component.
Solution: remove in the WildFly standalone directory the content in the 'deployments' directory and the 'tmp' directory. Rest assured, all what is there is okay to remove safely. Reboot and the error message will be gone ;-)
You should pay attention to not have two #Stateless EJB annotations on top of two classes with the same name - in the same module.
You may differentiate them by using the name attribute in the annotation and put different values in each class
Looks like the class already exists. Check if it does...you may have to rewrite that part of EEModuleDescription to use its own private methods (which would be what you would write) rather than overriding methods in RoleKeyCacheImpl. If the class actually does not exist then right-click on the project -> Maven 2 Tools -> Generate Eclipse Artifacts (Check for Updates). That will regenerate all of the dependencies that the project uses. Also please be sure that you have not added any new projects to the classpath by mistake as that may also cause this error.
I just ran into this today when a colleague added a maven dependency.
Turns out this dependency was a jar with a nasty classpath entry or "../" in the manifest.
I edited the jar's manifest.mf that was cached in my local maven repository using 7-zip and removed the "../" classpath entry.
Then re-packaged my war file (maven clean install) and bingo, it works!
In my case it was caused by org.libreoffice jurt version 5.4.2 (but other versions I checked also have the classpath nastiness).
Unfortunately I was lucky we pinpointed it to a dependency, YMMV!

Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: org/springframework/core/convert/TypeDescriptor.NULL

I have upgraded spring jars from 3.0.x to 3.2.x version in my web application. Target environment is Websphere Application Server.
I am getting the following error when I try to hit the welcome page of the webapp in the browser.
Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0':
Initialization of bean failed; nested exception is java.lang.NoSuchFieldError:
org/springframework/core/convert/TypeDescriptor.NULL
It looks like some jar/jars in the build path are dependent on spring 3.0.x. I am not sure though. Will be helpful if anyone could out point the same.
I would also like to know how do I exclude dependency of other jars on spring 3.0.x in dispatcher-servlet.xml. Or should I upgrade any jar?
I am also trying to look for the culprit of the problem.
try this command on windows (if you are using maven)
mvn dependency:tree | find "springframework:" | find ":3.0"
or on *ix
mvn dependency:tree | grep "springframework:" | grep ":3.0"
that should be the culprit.
or manually issue
mvn dependency:tree > dep.txt
and view/edit dep.txt and search for ":3.0" (this will find other, non-spring, libraries as well.
I happened to have find solution of my own problem.
I solved my original problem by removing old spring 3.0.x jars which were still there in
WEB-INF/lib directory (but not in class path).
Second thing and answer to my second problem is that, In a Spring 3.2.x jar or above environment, Ajax call with content-type application/json do not support calls to url with .htm/.html extensions as web-app server throws 406 error. I had to change url extensions to anything else (.json I used for clarity).
Though there could be a different solution as well, but after searching a lot this is what proved to be a quick fix for me. Thanks for all the help.

Categories