Spring Boot in javaFX application (modularity problems) - spring

I am trying to use SpringBoot in javaFX application. I use javafx-weaver-spring-boot-starter, and it works great with java < 9, but there are some problems with java 9+ (modularity).
My project structure:
AppStarter code:
package test;
import javafx.application.Application;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class AppStarter {
public static void main(String[] args) {
Application.launch(JavaFxApplication.class, args);`
}
}
JavaFxApplication Code:
package test;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import net.rgielen.fxweaver.core.FxWeaver;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
public class JavaFxApplication extends Application {
private ConfigurableApplicationContext applicationContext;
#Override
public void init() {
String[] args = getParameters().getRaw().toArray(new String[0]);
this.applicationContext = new SpringApplicationBuilder()
.sources(AppStarter.class)
.run(args);
}
#Override
public void start(Stage stage) {
FxWeaver fxWeaver = applicationContext.getBean(FxWeaver.class);
Parent root = fxWeaver.loadView(MyController.class);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
#Override
public void stop() {
this.applicationContext.close();
Platform.exit();
}
}
MyController code:
package test;
import javafx.event.ActionEvent;
import net.rgielen.fxweaver.core.FxmlView;
import org.springframework.stereotype.Component;
#Component
#FxmlView("hello-view.fxml")
public class MyController {
public void onHelloButtonClick(ActionEvent actionEvent) {
System.out.println("Hello World");
}
}
modules-info.java:
module test {
requires spring.boot.autoconfigure;
requires javafx.graphics;
requires spring.context;
requires net.rgielen.fxweaver.core;
requires spring.boot;
requires javafx.weaver.spring.boot.starter;
requires net.rgielen.fxweaver.spring.boot.autoconfigure;
requires net.rgielen.fxweaver.spring;
exports test;
opens test;
}
pom.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo2</name>
<description>demo2</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.rgielen</groupId>
<artifactId>javafx-weaver-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17-ea+11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17-ea+11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>1
When I try to run the application, I get the following exception:
....
Caused by: java.lang.IllegalAccessError: class test.AppStarter$$EnhancerBySpringCGLIB$$e15856c4 (in module test) cannot access class org.springframework.cglib.core.ReflectUtils (in unnamed module #0x4fb0f9) because module test does not read unnamed module #0x4fb0f9
at test/test.AppStarter$$EnhancerBySpringCGLIB$$e15856c4.CGLIB$STATICHOOK1(<generated>)
at test/test.AppStarter$$EnhancerBySpringCGLIB$$e15856c4.<clinit>(<generated>)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:467)
at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:593)
at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363)
at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:585)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)
at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)
at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
... 21 more
...
module test does not read unnamed module...
how can I fix it?

Spring 5 isn't friendly with the JavaFX Platform Module System
Spring won't really be built for modules until Spring 6/Springboot 3 is released.
Spring Framework 6 is indeed expected to introduce module-info descriptors for all core framework modules, with minimal required dependencies on core Java modules, enabling the JDK's jlink tool to build custom runtime images for Spring setups. There might be constraints with optional third-party libraries and certain configuration strategies, so it is still unclear how popular such explicit module usage will become among Spring users.
For Spring 5-based applications, the framework is not easily compatible with the Java Platform Module System.
So I don't recommend trying to build a modular JavaFX application relying on Spring until:
Spring 6/SpringBoot 3 is released,
AND
the dependent libraries you use are also made to be easily compatible with the Java module system.
For example, when all of your dependencies define a module-info.java.
How to make your project non-modular
However, you can still build a JavaFX 17 application today which relies on Spring 5 by making the JavaFX application non-modular and either providing the JavaFX modules in the base JDK you use or via command-line switches. For more information, see the answer to:
Intellij 2021.3.2, JavaFX Maven project not resolving dependencies correctly
Delete the module-info.java to make the project non-modular. Place only the JavaFX modules on the module path and add them by VM arguments, --module-path and --add-modules. See the openjfx.io for getting started documentation for more information on the settings.
For distribution of your non-modular application, see either:
JPackageScriptFX for Maven-based builds.
badass-runtime-plugin for Gradle-based builds.

Related

Modular #Configuration/#Bean in Spring Boot

I'm making a MicroServices based project so I have more the one Spring Boot projects in my workspace. I need to configure restOperations in some of then but I want to configure once for all the project that needs. So I'm trying to add my #Configuration class to a jar and import in each MS projects.
The problem is, when I execute the MS project in my server, I receive this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field restOperations in com.epavanellio.base.business.controller.BusinessController required a bean of type 'org.springframework.web.client.RestOperations' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.web.client.RestOperations' in your configuration.
Here I have my Rest configuration class:
package com.epavanellio.base.restConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
//#Component
#Configuration
public class SimpleRestConfiguration {
final CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy())
.build();
#Bean
public RestOperations createRestTemplate(final ClientHttpRequestFactory clientHttpRequestFactory){
return new RestTemplate(clientHttpRequestFactory);
}
#Bean
public ClientHttpRequestFactory createHttpRequestFactory (#Value("${rest.connect.timeout}") final int connectTimeout,
#Value("${rest.read.timeout}") final int readTimeout) {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(connectTimeout);
clientHttpRequestFactory.setReadTimeout(readTimeout);
clientHttpRequestFactory.setHttpClient(httpClient);
return clientHttpRequestFactory;
}
}
I imported the .jar (dpdc-rest) with has the SimpleRestConfiguration class in my MS project POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.epavanellio.base</groupId>
<artifactId>ms-manager-business</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ms-manager-business</name>
<description>Validate business logic. A microservice based project. </description>
<packaging>war</packaging>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.epavanellio.base</groupId>
<artifactId>domain</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.epavanellio.base</groupId>
<artifactId>dpdc-rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.epavanellio.base</groupId>
<artifactId>dpdc-custom-exception-handler</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>ms-manager-business</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
and in my MS application class is like this:
package com.epavanellio.base.business;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import com.epavanellio.base.restConfig.SimpleRestConfiguration;
//#SpringBootApplication(scanBasePackages={"com.epavanellio.base", "com.epavanellio.base.restConfig"})
//#Import(SimpleRestConfiguration.class)
//#ComponentScan({"com.epavanellio.base", "com.epavanellio.base.restConfig"})
#ComponentScan("com.epavanellio.base")
#EntityScan("com.epavanellio.base.domain")
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
#SpringBootApplication
public class BusinessApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(BusinessApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(BusinessApplication.class);
}
}
as you can see commented, I already tried to my make my runtime "see" my configuration class in diffrent ways:
First I tried to add (scanBasePackages={"com.epavanellio.base", "com.epavanellio.base.restConfig"}) after my annotation #SpringBootApplication, but the same error occurs. Then I tried to add specifically the SimpleRestConfiguration class package to the #ComponentScan annotation(for this, I uncommented the #Component annotation in SimpleRestConfiguration class), but the same error occurs. At least I tried to use #Import, but in this case I receive the error:
java.io.FileNotFoundException: class path resource [com/epavanellio/base/restConfig/SimpleRestConfiguration.class] cannot be opened because it does not exist
does any one know how can I make my application class to "see" my
#Configuration class?
The problem was Maven, for some reason maven was no recognizing my jar.
so I made a new dependency project, with a new name but same same SimpleRestConfiguration class. I imported the new .Jar to my MS and then works fine.
My application become like this:
#ComponentScan("com.epavanellio.base")
#EntityScan("com.epavanellio.base.domain")
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
#SpringBootApplication
public class UserApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(UserApplication.class);
}
}

What's the difference from Spring boot 2.0.0 to 2.2.1 about javax.servlet.* library dependency

I am doing Spring boot mvc project with JSP.
When I use version 2.0.0.RELEASE, everything is ok!
Here is part of my pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
...
And this is my startup class:
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
#SpringBootApplication
public class TestApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication .class);
}
public static void main(String[] args) {
SpringApplication.run(TestApplication .class, args);
}
}
But when I change my spring-boot-starter-parent to 2.2.1.RELEASE
Eclipse report error in my startup class:
Multiple markers at this line
- The type javax.servlet.ServletContext cannot be resolved. It is indirectly referenced from
required .class files
- The type javax.servlet.ServletException cannot be resolved. It is indirectly referenced from
required .class files
I know that I can add some other dependencies to solve this, but I don't want to.
Could anybody guide me to the difference in spring boot versions? Thanks in advance!

How to access application.yml properties in Spring 1.5.9

I'm spinning my wheels on this.
Here is a simple Spring Boot app. I'm trying to use a yaml properties file, but I can't seem to get it to find the properties file or let me access the values in it. I've tried many variations from advice I've searched for here and elsewhere. Nothing is working.
(For reasons I can't go into, I have to use an older version of Spring. (1.5.9))
In IntelliJ I have the Lombok plugin installed, annotations enabled and the language is set to Java 1.8.
Here is the error I'm getting currently:
[ERROR] demo/src/main/java/com/example/demo/Foo.java:[9,10] cannot find symbol
[ERROR] symbol: method value()
[ERROR] location: #interface lombok.Value
[ERROR] demo/src/main/java/com/example/demo/Foo.java:[9,3] annotation type not applicable to this kind of declaration
[ERROR] demo/src/main/java/com/example/demo/Foo.java:[13,5] cannot find symbol
[ERROR] symbol: variable log
[ERROR] location: class com.example.demo.Foo
Here is the folder structure:
Here is the application.yml file:
project:
thing:
path: resources/foo_files
Here is the main class:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
Foo foo = new Foo();
SpringApplication.run(DemoApplication.class, args);
}
}
Here is class Foo:
package com.example.demo;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
#Slf4j
class Foo {
#Value("${project.thing.path}")
private String projectThingPath;
public Foo() {
log.info("path is: " + projectThingPath);
}
}
Here is the pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
For getting value from application.yml you should be using #Value from the package org.springframework.beans.factory.annotation.Value but you are using lombok's #Value
package com.example.demo;
import org.springframework.beans.factory.annotation.Value; // Changed
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
#Slf4j
#Component // EDIT : Added
class Foo {
#Value("${project.thing.path}")
private String projectThingPath;
public Foo() {
log.info("path is: " + projectThingPath);
}
}
EDIT
So another important point is that, a class should be annotated with stereotype annotation ( To tell Spring to configure the data).
You have compile error because you are using #Slf4j (lombok annotation) but you have not Slf4j lib in your dependencies
In this case you can use #Log or add Slf4j to your dependencies

Spring Tool Suite: Cannot Execute a Simple Demo because of Spring Boot Build Path ERROR

The Error is as follows:
Description Resource Path Location Type The project was not built
since its build path is incomplete. Cannot find the class file for
org.springframework.context.ConfigurableApplicationContext. Fix the
build path then try building this project springbootdemo Unknown Java
Problem
2 ERROR items:
Description Resource Path Location Type The type
org.springframework.context.ConfigurableApplicationContext cannot be
resolved. It is indirectly referenced from required .class
files MainActivity.java /springbootdemo/src/main/java/springbootdemo line
10 Java Problem
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MainActivity {
public MainActivity() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
//this is where the ERROR happens beginning at
// "SpringApplication.run(MainActivity.class, args);"
ApplicationContext ctx = SpringApplication.run(MainActivity.class, args);
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>labs.noogui.springbootquickstart</groupId>
<artifactId>course-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot course-api</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
Project Structure:
**Spring Tool Suite**
Version: 3.9.4.RELEASE
Build Id: 201804120921
Platform: Eclipse Oxygen.3a (4.7.3a)
I'm following the Spring Boot tutorial from Edureka!
How do I fix this build path error? I mean, this is like a spring boot hello world and I'm already running into errors?
Just use below code,
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class MainActivity {
public static void main(String[] args) {
SpringApplication.run(MainActivity.class, args);
}
}
or if you want to use ApplicationContext to start the application then use below line but both are almost same.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
#SpringBootApplication
public class MainActivity {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(MainActivity.class, args);
}
}
You are using ApplicationContext from org.apache.catalina.core.
Import and use this org.springframework.context.ApplicationContext instead.
Your IDE is showing compile errors. Error message should probably lead you to the right direction.
Thanks for the folks who tried to help but I found out that the problem is with maven's 'corrupted' repository (again). So as always, deleting the .m2/repository and updating your maven project resolves the issue.
Related post in this github forum. This is a recurring issue with maven.

org.springframework.web.WebAbblicationInitializer.onStartup won't Override interface method

I am attempting a pure java (no web.xml) Spring WebMVC project and I am running into a peculiar issue with the configuration file. I am using exactly the code from this example, where it says "A 100% code-based approach to configuration." However, eclipse says that I must remove the #Override annotation because onStartup does not "implement a superclass method."
This seems like it might be a problem with the versions of Servlet or Spring that I am using, but I don't really know what I might change either of them to which would fix that.
This is a Maven project. I'd like to solve this by adjusting my maven dependencies, rather than using Eclipse configurations.
Here is the configuration file
package com.peak15.jumpgate;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class MyWebAppInitializer implements WebApplicationInitializer {
#Override // TODO figure out why this doesn't override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context
= new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.peak15.jumpgate");
return context;
}
}
here is pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jumpgate</groupId>
<artifactId>jumpgate2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>JumpGateII</name>
<properties>
<jdk.version>1.8</jdk.version>
<spring.version>3.2.13.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</project>
Check if you have installed jdk 1.8 -> if not, Eclipse is defaulting to Java 1.5 and you have classes implementing interface methods (which in Java 1.6 can be annotated with #Override, but in Java 1.5 can only be applied to methods overriding a superclass method).
You can also add Maven compiler plugin to your pom to make sure it is working with latest Java version:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
Hope that causes an issue.

Resources