IntelliJ can't find javax.servlet.* - spring

I am currently facing a strange issue where IntelliJ can't process my code. Something like this:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(authenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
...
}
where authenticationFilter returns an instance of GenericFilterBean. This code compiles using Gradle just fine, but IntelliJ complains that my AuthenticationFilter and UsernamePasswordAuthenticationFilter.class don't match the required parameters javax.servlet.Filter and Class<? extends javax.servlet.Filter>.
Upon further inspection, it seems that the class file that defines GenericFilterBean doesn't see the javax.servlet package so in my file, it doesn't know what it is.
Another interesting thing is that spring-ws-core has a dependency on spring-web:4.0.9.RELEASE and my code depends on spring-web:4.3.2.RELEASE, and when I look at the classes inside the 4.3.2 references, it can see javax.servlet, i.e. GenericFilterBean on 4.0.9 breaks, but on 4.3.2 works.
Also, if I do
if (authenticationFilter() instanceof Filter);
if (new UsernameAuthenticationFilter() instanceof Filter);
IntelliJ says I could replace both with != null.
When I run gradlew dependencies, I can see dependencies like org.springframework:spring-beans:4.0.9.RELEASE -> 4.3.2.RELEASE, but IntelliJ displays both in the Gradle Projects view and in the project references.
My project has a multi-project gradle build and the 4.0.9 dependencies are on the subprojects.
What I tried
refreshing the gradle dependencies (through IntelliJ)
invalidating IntelliJ caches
cleaning the project (gradlew clean)
reopening IntelliJ
reinstalling IntelliJ
restarting my computer
Temporary solution
As suggested by #Jens, I added compile('javax.servlet:javax.servlet-api:3.1.0') to allprojects and now IntelliJ can parse it correcly, although it would be better not to have "hacky" dependencies on the build file.

Related

Spring Boot Gradle build fails with "Execution failed for task 'bootWarMainClassName'

I have a multi-project gradle build with Spring Boot structured per default gradle conventions.
root
-- common
-- src/main/java
-- bootproject
-- src/main/java
My current project is to (A) upgrade gradle from 5.x to 7.3.x and (B) use embedded tomcat with Spring Boot.
This is a project that has existed for many years and is Spring Boot but has always been deployed traditionally as a WAR file in Tomcat.
I have upgraded gradle to 7.3.3 following the gradle migration guide and have "common" building correctly (java-library). I am now trying to make "bootproject" build correctly again. I have migrated my build.gradle, and compilation happens correctly now but upon executing 'gradlew sub-project:build' I get the error:
Execution failed for task ':tx-main:bootWarMainClassName'.
java.lang.IllegalArgumentException (no error message)
My ROOT build.gradle is simple:
plugins {
id "org.springframework.boot" version "2.6.3"
}
subprojects {
apply plugin: 'java'
group = 'com.blah'
version = '2.1.1'
repositories {
mavenCentral()
}
There is a library sub-project (common) that builds fine.
The Spring Boot subproject build.gradle is:
plugins {
id 'org.springframework.boot'
id 'io.spring.dependency-management'
}
dependencies {
implementation project(path:':common', configuration:'default')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation ...
}
The main class was originally set up to make the app conventionally deployed (extends SpringBootServletInitializer), but has been replaced with (taken directly from docs):
package com.blah;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The compilation works, this class appears to be in the build/classpath so I don't understand why Gradle-Spring-Boot is not finding it. I have also tried explicitly identifying the class with the same result.
Unfortunately I find little documentation about multi-project gradle builds so I suspect that is part of the problem. Hopefully someone here can point me in the right direction as to what is wrong.
Thanks
I discovered the issue here. We have custom code in /buildSrc that is apparently causing this.

SpringBoot WAR file deployed into Tomcat running but still returning 404

I want to demonstrate a simple SpringBoot application being deployed into a separately running Tomcat instance. Even though my application appears to have been deployed, I cannot access it in Tomcat.
I have followed the 'Traditional deployment' instructions in the Spring documentation.
I have tried using a different version of Tomcat and running the war file as ROOT.warbut get similar behaviour.
When I run the war standalone e.g. java -jar build/libs/springbootify.war I can successfully access the expected URL http://localhost:8080/doit.
Application.java
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
MyController.java
#RestController
public class MyController {
#GetMapping(value = "/doit")
public String getSomething() {
return "Something";
}
}
build.gradle
plugins {
id 'war'
id 'java'
id 'io.spring.dependency-management' version "1.0.8.RELEASE"
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'com.palantir.docker' version '0.22.1'
id 'com.palantir.docker-run' version '0.22.1'
}
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
compile 'org.springframework.boot:spring-boot-devtools'
}
See the reproducible example on Github.
I can see that the war file has been deployed in the Tomcat logs
29-Jun-2019 17:07:04.434 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/springbootify.war] has finished in [857] ms
However, when I access http://localhost:8080/springbootify/doit I get a 404 response.
I expect this to return the string "something" with a 200 response.
UPDATE - 2019-07-12
I have tried building the war using Maven, and manually deploying to Tomcat via the manager UI and this works correctly
Inspecting the difference between the war files generated by Gradle and Maven I found the following:
1) Maven adds these additional attributes to the META-INF/MANIFEST.MF:
Created-By: Maven Archiver 3.4.0
Build-Jdk-Spec: 12
Implementation-Title: springbootify
Implementation-Version: 0.0.1-SNAPSHOT
2) Maven adds this additional library to the war:
WEB-INF/lib/javax.annotation-api-1.3.2.jar whereas in the Gradle war it is in WEB-INF/lib-provided/javax.annotation-api-1.3.2.jar
I'm going to suppose it's one of these reasons that it's not working with Gradle, but so far I haven't managed to modify the Gradle generated war to include these differences.
The newly added pom.xml can also be viewed on the provided Github link.

Inconsistent build classes package structure with gradle java pugin

I am trying to run a simple gradle build with just one line in build.gradle:
apply plugin: 'java'
Java file is placed under- src/main/java/hello/Hello.java
When I run build.gradle, compiled Hello.class is generated under
build/classes/java/main/hello/Hello.class
What am I expecting is:
build/classes/main/java/hello/Hello.class
Hello.java-
package hello;
class Hello{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
Can someone please explain this? Thanks.
This changed between Gradle 3.x and 4.x.
The reason we went with build/classes/java/main vs build/classes/main/java is that it was less likely to break in strange ways with builds and plugins that hardcoded the path to build/classes/main or snuck outputs into build/classes/main.
from Gradle forum discussion

#ConfigurationProperties Spring Boot Configuration Annotation Processor not found in classpath

I try to make completion for custom properties in Spring Boot.
I tried to create a simple project via IntelliJ IDEA 2016.3:
Created a new Gradle project with Spring Boot Initializer (I haven't checked anything at all).
Created a new class Properties.
When I annotated it with #ConfigurationProperties, the next notification has appeared:
The documentation said that I should add the following to my project:
dependencies {
optional "org.springframework.boot:spring-boot-configuration-processor"
}
compileJava.dependsOn(processResources)
After that, I tried to rebuild the project and enable annotation processors in settings but the notification hasn't gone. Completion doesn't work too (I created a string my).
I had the same problem. I use idea 2017.2 and gradle 4.1,
and some blog said you should add:
dependencies {
optional "org.springframework.boot:spring-boot-configuration-processor"
}
But I changed it to this:
dependencies {
compile "org.springframework.boot:spring-boot-configuration-processor"
}
And the warning is gone.
According to the Spring Boot docs, the correct configuration since Gradle 4.6 is
dependencies {
annotationProcessor group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
// ...
}
IntelliJ IDEA supports annotationProcessor scope since build 193.3382 (2019.3). Don't forget to enable annotation processing in IntelliJ IDEA settings.
For those who are using maven, Intellij was still not happy with the addition of dependency. Seems like adding annotationProcessorPaths via maven-compiler-plugin finally tamed the beast.
Make sure the version matches your spring dependencies. I suspect it would be already present in your effective POM.
Reason: I was using a custom parent-pom which had a mapstruct annotation processor set in annotationProcessorPaths and that actually triggered IntelliJ to ask for all other annotation processors to be specified manually as well.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.4.RELEASE</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
For those using Maven or Gradle, just add the dependency on spring-boot-configuration-processor.
Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Gradle 4.5 and earlier
dependencies {
compileOnly "org.springframework.boot:spring-boot-configuration-processor"
}
Gradle 4.6 and later
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
For more information:
"Generating Your Own Metadata by Using the Annotation Processor"
https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/appendix-configuration-metadata.html#configuration-metadata-annotation-processor
It happens to me for two reasons in IDEA:
Double check if your setting is picked (enabled) in IDEA: Preferences->Annotation Processors->Enable annotation processing.
After update your Idea, check your plugins and update them. It happens that plugins become incompatible with your new IDEA version, so just click to update them.
I forgot to add propdeps-plugin. However, I remember that it didn't work for me even with the plugin on 2016.3, So as #CrazyCoder mentioned, try to downgrade Gradle or download the new 2017.1 version (details).
Also you may receive Re-run Spring Boot Configuration Annotation Processor to update generated metadata when you will solve this issue. For this, click Refresh all Gradle projects (in Gradle side menu).
In maven project helps adding dependency spring-boot-configuration-processor and marking main class with #EnableConfigurationProperties(AppProperties.class).
Maybe somebody helps.
In version 2018.3 of IntelliJ, I solved this problem (as per this documentation) in the following way:
With Gradle 4.5 and earlier, the dependency should be declared in the
compileOnly configuration, as shown in the following example:
dependencies {
compileOnly "org.springframework.boot:spring-boot-configuration-processor"
}
With Gradle 4.6 and later, the dependency should be declared in the
annotationProcessor configuration, as shown in the following example:
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}
For Kotlin projects, the working configuration since Gradle 4.6 is using annotation processor
apply plugin: "kotlin-kapt"
dependencies {
kapt("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
compileOnly("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion")
}
You have to mention in the main class the class you want to use #ConfigurationProperties annotation like below.
#EnableConfigurationProperties(AppProperties.class)
The Property Configuration class with #ConfigurationProperties will be like this
import org.springframework.boot.context.properties.ConfigurationProperties;
#ConfigurationProperties(prefix = "app")
public class AppProperties {
String name;
String id;
}
The Main class will be like this
import com.auth2.demo.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
#SpringBootApplication
#EnableConfigurationProperties(AppProperties.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
I had the same problem with IntelliJ version 2018.1.2. I also had to define the actual version of spring-boot-configuration-processor in order to get it worked:
compile('org.springframework.boot:spring-boot-configuration-processor:2.0.1.RELEASE')
following works for me:
buildscript {
repositories {
jcenter()
maven { url 'https://repo.jenkins-ci.org/public/' }
maven { url 'http://repo.spring.io/plugins-release' }
}
dependencies {
classpath "io.spring.gradle:propdeps-plugin:0.0.9.RELEASE"
}
}
...
apply plugin: 'propdeps'
apply plugin: 'propdeps-eclipse'
apply plugin: 'propdeps-idea'
...
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-starter-parent:2.0.0.RELEASE'
}
}
...
dependencies {
compile "org.springframework.boot:spring-boot-starter"
compile "org.springframework.boot:spring-boot-starter-actuator"
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" // for #ConfigurationProperties, make sure compileJava.dependsOn(processResources)
...
}
compileJava.dependsOn(processResources)
According to the Spring Boot docs, the correct configuration for Gradle 4.5 and earlier is
dependencies {
compileOnly group: 'org.springframework.boot', name: 'spring-boot-configuration-processor'
// ...
}
Spring's website has a tutorial that contains a great explanation how to make it work. Just follow the steps under "Configuration properties" section below.
It has one of the steps which none of other answers mentioned here:
run ./gradlew kaptKotlin manually.
As of Mar 2021, IDEA will still show the warning on top of the Kotlin properties class, but the properties will be recognized and work. You'll be able to navigate from .properties file to the Kotlin properties class, but not the other way around.
https://spring.io/guides/tutorials/spring-boot-kotlin/ scroll down to "Configuration properties" part.
Or the same page on GitHub:
https://github.com/spring-guides/tut-spring-boot-kotlin/blob/master/README.adoc#configuration-properties

Compiling error on gradle custom plugin using external plugin (groovy files)

We are trying to create a custom plugin. In this plugin we pretend to use gradleFx plugin internally to extends some classes.
When we try to build the plugin, it fails because gradlefx classes cannot be found:
we tried to define dependencies in different ways, from the build.gradle when we apply groovy plugin, and also we tried from groovy classes like this:
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.dependencies {
compile 'org.gradlefx:gradlefx:1.3.3'
}
}
}
Anyway none of this works when we try to extends a gradleFx class:
import org.gradlefx.tasks.adt.AdtTask
MyTask implements AdtTask {
}
because AdtTask doesn't exists, the error we see is unable to resolve class org.gradlefx.tasks.adt.AdtTask
How's the right way to declare dependencies and extend from them in my groovy files?

Resources