How to connect mysql database in eclipse using maven and jpa? - java

I want to connect to mysql database from eclipse. I want to create a Rest Api and insert data in mysql database.
I am using sqlyog to connect to mysql and I have installed a xammp server, turned on the mysql and my project is located at tihs path C:\xampp\tomcat\webapps\
I have connected sql yog by giving the port on which mysql is running from xammp server.
Now I have created one maven project, which includes jpa dependency and properties.
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>
<groupId>com.creditone</groupId>
<artifactId>creditone</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>creditone</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RC1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
application.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.name=test
spring.datasource.username=root
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect \u2013
Main controller
package com.creditone.creditone;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.creditone.creditone.User;
import com.creditone.creditone.UserRepository;
#Controller // This means that this class is a Controller
#RequestMapping(path="/demo") // This means URL's start with /demo (after Application path)
public class MainController {
#Autowired // This means to get the bean called userRepository
// Which is auto-generated by Spring, we will use it to handle the data
private UserRepository userRepository;
#GetMapping(path="/add") // Map ONLY GET Requests
public #ResponseBody String addNewUser (#RequestParam String name
, #RequestParam String email) {
// #ResponseBody means the returned String is the response, not a view name
// #RequestParam means it is a parameter from the GET or POST request
User n = new User();
n.setName(name);
n.setEmail(email);
userRepository.save(n);
return "Saved";
}
#GetMapping(path="/all")
public #ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return userRepository.findAll();
}
}
UserRepository
package com.creditone.creditone;
import org.springframework.data.repository.CrudRepository;
import com.creditone.creditone.User;
// This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository
// CRUD refers Create, Read, Update, Delete
public interface UserRepository extends CrudRepository<User, Long> {
}
User
package com.creditone.creditone;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity // This tells Hibernate to make a table out of this class
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Trying to use this code to check if database getting connect and able to perform CRUD operations.
But as I run this I am getting error as :
main] c.c.creditone.CreditoneApplication : Starting CreditoneApplication on Siddhi with PID 18728 (C:\xampp\tomcat\webapps\creditone\target\classes started by siddhi in C:\xampp\tomcat\webapps\creditone)
2018-02-20 12:31:45.726 INFO 18728 --- [ main] c.c.creditone.CreditoneApplication : No active profile set, falling back to default profiles: default
2018-02-20 12:31:45.756 INFO 18728 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#6328d34a: startup date [Tue Feb 20 12:31:45 IST 2018]; root of context hierarchy
2018-02-20 12:31:46.881 INFO 18728 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$99fd5bbe] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-02-20 12:31:47.169 INFO 18728 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-02-20 12:31:47.176 INFO 18728 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-02-20 12:31:47.176 INFO 18728 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-02-20 12:31:47.181 INFO 18728 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jre1.8.0_161\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre1.8.0_161/bin/server;C:/Program Files/Java/jre1.8.0_161/bin;C:/Program Files/Java/jre1.8.0_161/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files\Git\bin;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Users\Intel\AppData\Local\Microsoft\WindowsApps;;C:\Windows\System32;;.]
2018-02-20 12:31:47.236 INFO 18728 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-02-20 12:31:47.236 INFO 18728 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1483 ms
2018-02-20 12:31:47.339 INFO 18728 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-02-20 12:31:47.342 INFO 18728 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-02-20 12:31:47.342 INFO 18728 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-02-20 12:31:47.342 INFO 18728 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-02-20 12:31:47.342 INFO 18728 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-02-20 12:31:47.389 WARN 18728 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2018-02-20 12:31:47.390 INFO 18728 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-02-20 12:31:47.402 INFO 18728 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-02-20 12:31:47.406 ERROR 18728 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Cannot determine embedded database driver class for database type NONE
Action:
If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
How to resolve this? I am new to eclipse and web development. Please help.
Thank you.

Your application.properties seems to have wrong entries. The only ones you need are the following 4.
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
It is described here: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database
Also where is your application.properties located?
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

This exception is thrown by Spring when it is unable to find the application.properties file or unable to find the datasource.
Check if the application.properties is under src/main/resources. Also, remove \u2013 from the properties file
You have not specified the mysql port, are you sure you are able to connect it from command line directly?
Since you are running from eclipse, make sure you have added the start-up class appropriately and have #SpringBootApplication
<properties>
<start-class>org.xxx.xxx.YourClassName</start-class>
</properties>

Related

How to create RESTful Web Service with Spring Boot and Apache Camel?

I'm learning Apache Camel in Spring Boot project and I try to create a Retful Webservice and the service is starting but the problem is that I get 404 when I call the endpoint.
#Component
#RequiredArgsConstructor
public class RestJavaDsl extends RouteBuilder {
private final WeatherDataProvider weatherDataProvider;
#Override
public void configure() throws Exception {
from("rest:get:javadsl/weather/{city}?produces=application/json")
.outputType(WeatherDto.class)
.process(this::getWeatherData);
}
private void getWeatherData(Exchange exchange) {
String city = exchange.getMessage().getHeader("city", String.class);
WeatherDto currentWeather = weatherDataProvider.getCurrentWeather(city);
Message message = new DefaultMessage(exchange.getContext());
message.setBody(currentWeather);
exchange.setMessage(message);
}
}
I created this class to hardcode some data:
#Component
public class WeatherDataProvider {
private static Map<String, WeatherDto> weatherData = new HashMap<>();
public WeatherDataProvider() {
WeatherDto dto = WeatherDto.builder().city("London").temp("10").unit("C").receivedTime(new Date().toString()).id(1).build();
weatherData.put("LONDON", dto);
}
public WeatherDto getCurrentWeather(String city) {
return weatherData.get(city.toUpperCase());
}
public void setCurrentWeather(WeatherDto dto) {
dto.setReceivedTime(new Date().toString());
weatherData.put(dto.getCity().toUpperCase(), dto);
}
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class WeatherDto implements Serializable {
static int counter = 1;
private int id = counter++;
private String city;
private String temp;
private String unit;
private String receivedTime;
}
application.yml
camel:
component:
servlet:
mapping:
context-path: /services/*
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 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.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dgs</groupId>
<artifactId>camel-rest-springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>camel-rest-springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<camel.version>3.14.0</camel.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<scope>test</scope>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jaxb</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-servlet</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-rest-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The serviceis starting and this is the console log:
2022-01-24 20:01:40.353 INFO 15796 --- [ main] c.d.c.CamelRestSpringbootApplication : Starting CamelRestSpringbootApplication using Java 11.0.5 on pc-PC with PID 15796 (D:\Spring Boot\camel-rest-springboot\target\classes started by pc in D:\Spring Boot\camel-rest-springboot)
2022-01-24 20:01:40.357 INFO 15796 --- [ main] c.d.c.CamelRestSpringbootApplication : No active profile set, falling back to default profiles: default
2022-01-24 20:01:43.583 INFO 15796 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-01-24 20:01:43.604 INFO 15796 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-01-24 20:01:43.604 INFO 15796 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2022-01-24 20:01:43.820 INFO 15796 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-01-24 20:01:43.821 INFO 15796 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3235 ms
2022-01-24 20:01:45.228 INFO 15796 --- [ main] o.a.c.c.s.CamelHttpTransportServlet : Initialized CamelHttpTransportServlet[name=CamelServlet, contextPath=]
2022-01-24 20:01:45.233 INFO 15796 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-01-24 20:01:45.592 INFO 15796 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Message DataType is enabled on CamelContext: camel-1
2022-01-24 20:01:45.607 INFO 15796 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Routes startup (total:1 started:1)
2022-01-24 20:01:45.607 INFO 15796 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Started route1 (rest://get:javadsl/weather/%7Bcity%7D)
2022-01-24 20:01:45.607 INFO 15796 --- [ main] o.a.c.impl.engine.AbstractCamelContext : Apache Camel 3.14.0 (camel-1) started in 370ms (build:83ms init:269ms start:18ms)
2022-01-24 20:01:45.617 INFO 15796 --- [ main] c.d.c.CamelRestSpringbootApplication : Started CamelRestSpringbootApplication in 6.569 seconds (JVM running for 8.087)
But when I try to call the endpoint http://localhost:8080/services/javadsl/weather/london
It looks like this endpoint doesn't exist, the rest isn't created. I used debugger and the method getWeatherData() isn't called.
And I think this log is not ok: Started route1 (rest://get:javadsl/weather/%7Bcity%7D), it should be something like that: route1 started and consuming from servlet:/javadsl/weather/%7Bcity%7D
And the tutorial is from here: https://www.youtube.com/watch?v=spDjbC8mZf0&t=433s
Thank you in advance!
You can start by creating example project using official camel-archetype-spring-boot maven archetype. You can generate project based on the archetype using your IDE or from command-line using following maven command.
mvn archetype:generate -DarchetypeArtifactId="camel-archetype-spring-boot" -DarchetypeGroupId="org.apache.camel.archetypes" -DarchetypeVersion="3.14.0"
Now in the maven project file pom.xml add following block to the dependencies
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jetty-starter</artifactId>
</dependency>
Note that version doesn't need to be specified as it is provided by camel-spring-boot-dependencies BOM (bill of materials) in dependencyManagement section.
After that you can create new file ConfigureCamelContext.java where we can configure our CamelContext and provide it with RestConfiguration. We can do this by implementing CamelContextConfiguration and #Component annotation.
The annotation tells spring-framework that it should create instance of the class and inject it to objects that request it based on its class-type or interface. Camel is configured to automatically ask spring-framework for these RestConfiguration instances which it will proceed to use configure CamelContext.
package com.example;
import org.apache.camel.CamelContext;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.spring.boot.CamelContextConfiguration;
import org.springframework.stereotype.Component;
#Component
public class ConfigureCamelContext implements CamelContextConfiguration {
#Override
public void beforeApplicationStart(CamelContext camelContext) {
RestConfiguration restConfiguration = new RestConfiguration();
restConfiguration.setApiComponent("jetty");
restConfiguration.setApiHost("localhost");
restConfiguration.setPort(8081);
camelContext.setRestConfiguration(restConfiguration);
}
#Override
public void afterApplicationStart(CamelContext camelContext) {
}
}
This should work with RestDSL and rest-component.
Edit MySpringBootRouter.java to something like this:
package com.example;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
#Component
public class MySpringBootRouter extends RouteBuilder {
static final String CONTET_TYPE_TEXT = "text/plain";
#Override
public void configure() {
rest()
.get("/hello/")
.route()
.setHeader(Exchange.CONTENT_TYPE, constant(CONTET_TYPE_TEXT))
.setBody().constant("Hello world")
.end()
.endRest()
.get("/hello/{name}")
.route()
.setHeader(Exchange.CONTENT_TYPE, constant(CONTET_TYPE_TEXT))
.setBody().simple("Hello ${headers.name}")
.end()
.endRest();
from("rest:get:test?produces=plain/text")
.setBody().constant("Hello from JavaDSL");
}
}
Comment out the class under src/test/java/<grouId>/ as the example test provided by the archetype is not applicable for for MySpringBootRouter and will interrupt build.
To run the project you can use command
mvn spring-boot:run
Now you should be able to open up localhost:8081/hello, localhost:8081/hello/<Name> or localhost:8081/test get response in plain text.

spring boot cant connect to cassandra database

i am using a spring boot quick start and want to establish a connection to a cassandra instance that is running on an ubuntu VM on the same machine,
i get this error when running the spring boot app
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.5.RELEASE)
2018-11-08 18:00:10.671 INFO 12076 --- [ main] hello.Application : Starting Application on DESKTOP-OG0KPA1 with PID 12076 (C:\Users\omar_\Downloads\gs-spring-boot-master\gs-spring-boot-master\complete\target\classes started by omar_ in C:\Users\omar_\Downloads\gs-spring-boot-master\gs-spring-boot-master\complete)
2018-11-08 18:00:10.680 INFO 12076 --- [ main] hello.Application : No active profile set, falling back to default profiles: default
2018-11-08 18:00:10.966 INFO 12076 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#60dcc9fe: startup date [Thu Nov 08 18:00:10 EET 2018]; root of context hierarchy
2018-11-08 18:00:12.701 INFO 12076 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'cassandraTemplate' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=cassandraConfig; factoryMethodName=cassandraTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [hello/CassandraConfig.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; factoryMethodName=cassandraTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/data/cassandra/CassandraDataAutoConfiguration.class]]
2018-11-08 18:00:13.020 INFO 12076 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2018-11-08 18:00:13.112 INFO 12076 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2018-11-08 18:00:14.517 INFO 12076 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8087 (http)
2018-11-08 18:00:14.560 INFO 12076 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-11-08 18:00:14.561 INFO 12076 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.34
2018-11-08 18:00:14.570 INFO 12076 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_121\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Dell\DW WLAN Card;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Brackets\command;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\nodejs\;C:\PostgreSQL\pg10\bin;C:\Program Files\PuTTY\;C:\WINDOWS\System32\OpenSSH\;D:\PostgreSQL\pg10\bin;C:\Users\omar_\Downloads\apache-maven-3.5.4-bin\apache-maven-3.5.4\bin;C:\Users\omar_\AppData\Local\atom\bin;C:\Users\omar_\AppData\Local\Microsoft\WindowsApps;C:\Users\omar_\AppData\Roaming\npm;C:\Program Files\Microsoft VS Code\bin;C:\Users\omar_\Downloads\apache-cassandra-3.11.3-bin\apache-cassandra-3.11.3\bin;C:\Python27;;.]
2018-11-08 18:00:14.775 INFO 12076 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-11-08 18:00:14.775 INFO 12076 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3830 ms
2018-11-08 18:00:15.491 ERROR 12076 --- [ost-startStop-1] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'servletEndpointRegistrar' defined in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration$WebMvcServletEndpointManagementContextConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar]: Factory method 'servletEndpointRegistrar' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.health.HealthEndpoint]: Factory method 'healthEndpoint' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.actuate.autoconfigure.cassandra.CassandraHealthIndicatorAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cluster' defined in class path resource [hello/CassandraConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.config.CassandraClusterFactoryBean]: Factory method 'cluster' threw exception; nested exception is java.lang.NumberFormatException: null
2018-11-08 18:00:15.522 INFO 12076 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-11-08 18:00:15.534 WARN 12076 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
2018-11-08 18:00:15.560 INFO 12076 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-11-08 18:00:15.583 ERROR 12076 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:155) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at hello.Application.main(Application.java:15) [classes/:na]
Caused by: java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542) ~[na:1.8.0_121]
at java.lang.Integer.parseInt(Integer.java:615) ~[na:1.8.0_121]
at hello.CassandraConfig.cluster(CassandraConfig.java:32) ~[classes/:na]
at hello.CassandraConfig$$EnhancerBySpringCGLIB$$bf5637d0.CGLIB$cluster$0(<generated>) ~[classes/:na]
at hello.CassandraConfig$$EnhancerBySpringCGLIB$$bf5637d0$$FastClassBySpringCGLIB$$bfd61920.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at hello.CassandraConfig$$EnhancerBySpringCGLIB$$bf5637d0.cluster(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
... 122 common frames omitted
Process finished with exit code 1
here is my 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>
<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- tag::actuator[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- end::actuator[] -->
<!-- tag::tests[] -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-data</artifactId>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-wfs-ng</artifactId>
<version>${gt.version}</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.apache.cassandra</groupId>-->
<!--<artifactId>cassandra-all</artifactId>-->
<!--<version>3.11.3</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>com.datastax.cassandra</groupId>-->
<!--<artifactId>cassandra-driver-core</artifactId>-->
<!--<version>3.6.0</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.data</groupId>-->
<!--<artifactId>spring-data-cassandra</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-core</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>com.datastax.cassandra</groupId>
<artifactId>cassandra-driver-mapping</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.cassandraunit</groupId>-->
<!--<artifactId>cassandra-unit-spring</artifactId>-->
<!--<version>${cassandra-unit-spring.version}</version>-->
<!--<scope>test</scope>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>org.cassandraunit</groupId>-->
<!--<artifactId>cassandra-unit</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.cassandraunit</groupId>-->
<!--<artifactId>cassandra-unit-shaded</artifactId>-->
<!--<version>${cassandra-unit-shaded.version}</version>-->
<!--<scope>test</scope>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.hectorclient</groupId>-->
<!--<artifactId>hector-core</artifactId>-->
<!--<version>${hector-core.version}</version>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<artifactId>commons-logging</artifactId>-->
<!--<groupId>commons-logging</groupId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>com.datastax.cassandra</groupId>-->
<!--<artifactId>cassandra-driver-core</artifactId>-->
<!--<version>${cassandra-driver-core.version}</version>-->
<!--<optional>true</optional>-->
<!--</dependency>-->
<!-- end::tests[] -->
</dependencies>
<properties>
<java.version>1.8</java.version>
<cassandra-driver-core.version>3.6.0</cassandra-driver-core.version>
<cassandra-unit-spring.version>2.1.9.2</cassandra-unit-spring.version>
<cassandra-unit-shaded.version>2.1.9.2</cassandra-unit-shaded.version>
<hector-core.version>2.0-0</hector-core.version>
<guava.version>19.0</guava.version>
<gt.version>18.0</gt.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
i have set up a cassandra.properties file setting the host and port and keyspacename, also there is a cassandra config java class that sets the connection parameters to connect to the cluster
here is the file:
package hello;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.config.CassandraClusterFactoryBean;
import org.springframework.data.cassandra.core.mapping.BasicCassandraMappingContext;
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
#Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {
private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class);
#Autowired
private Environment environment;
#Override
protected String getKeyspaceName() {
return environment.getProperty("spring.data.cassandra.keyspace-name");
}
#Override
#Bean
public CassandraClusterFactoryBean cluster() {
final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
cluster.setContactPoints(environment.getProperty("spring.data.cassandra.contact-points"));
cluster.setPort(Integer.parseInt(environment.getProperty("spring.data.cassandra.port")));
LOGGER.info("Cluster created with contact points [" + environment.getProperty("spring.data.cassandra.contact-points") + "] " + "& port [" + Integer.parseInt(environment.getProperty("spring.data.cassandra.port")) + "].");
return cluster;
}
//
// #Bean
// public CassandraClusterFactoryBean cluster() {
// CassandraClusterFactoryBean cluster =
// new CassandraClusterFactoryBean();
// cluster.setContactPoints("192.168.164.130");
// cluster.setPort(9042);
// return cluster;
// }
#Override
#Bean
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
return new BasicCassandraMappingContext();
}
// #Bean
// public CassandraMappingContext cassandraMapping()
// throws ClassNotFoundException {
// return new BasicCassandraMappingContext();
// }
}
what else am i missing ?
EDIT : it turned out that i had to change the rpc_address in the cassandra.yml file in the vm host from localhost to the vm ip address, so its exposed to external connections
You spring.data.cassandra.port is missing or null. You can change to below code so that if it is not present then the code will use the default
#Value("${spring.data.cassandra.port: <cassandra port/9042>}")
private int port;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.data.cassandra.config.CassandraClusterFactoryBean;
import org.springframework.data.cassandra.config.java.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.mapping.BasicCassandraMappingContext;
import org.springframework.data.cassandra.mapping.CassandraMappingContext;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
/**
* #author dpoddar
*
*/
#Configuration
#EnableCassandraRepositories(basePackages = "com.xxx.abc.reposiroty.cassandra")
#ComponentScan(basePackages = "com.xxx.abc")
#Profile("cassandra")
public class CassandraConfig extends AbstractCassandraConfiguration {
private static final Log LOGGER = LogFactory.getLog(CassandraConfig.class);
#Override
protected String getKeyspaceName() {
return "agenthub";
}
#Override
#Bean
public CassandraClusterFactoryBean cluster() {
final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
cluster.setContactPoints("localhost");
cluster.setPort(9042);
//LOGGER.info("Cluster created with contact points [" + environment.getProperty("cassandra.contactpoints") + "] " + "& port [" + Integer.parseInt(environment.getProperty("cassandra.port")) + "].");
return cluster;
}
#Override
#Bean
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
return new BasicCassandraMappingContext();
}
}
You are adding a lot of boilerplate code that Spring handles for you, as long as your application.yml has the following properties:
spring:
data:
cassandra:
contact-points:
keyspace-name:
username:
password:
port:
and the dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
Spring will configure the connection for you, similar to Spring data for RDBMS.
You can then use the Cassandra Repository to query your tables:
#Repository
public interface YourRepository extends CassandraRepository<Item> {
//
}
And entity:
#Table
public class Item {
#PrimaryKeyColumn(
name = "id"
type = PrimaryKeyType.CLUSTERED)
private UUID id;
#PrimaryKeyColumn(
name = "key", type = PrimaryKeyType.PARTITIONED)
private String key;
#Column
private String data;
//Getter setters
}

Using #ConfigurationProperties in a #Scheduled annotation by referencing the bean name

I'm using #ConfigurationProperties to configure the delay of a background task in Spring boot and I'm trying to use this value from a #Scheduled annotation on another component. However, in order to make it work I must use the full name given to the bean by Spring.
The configuration properties class is as follows:
#ConfigurationProperties("some")
class SomeProperties {
private int millis; //the property is some.millis
public int getMillis() {
return millis;
}
public void setMillis(int millis) {
this.millis = millis;
}
}
And I'm using the value as follows in the scheduled method:
#Component
class BackgroundTasks {
#Scheduled(fixedDelayString = "#{#'some-com.example.demo.SomeProperties'.millis}") //this works.
public void sayHello(){
System.out.println("hello");
}
}
Is it possible to reference the value without having to use the full name of the bean? This answer suggests it is possible but I haven't been able to make it work.
Using #Componenton the properties class allows to access the property as "#{#someProperties.persistence.delay}.
More info in the spring boot documentation.
SomePrperties.java
package com.example.demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
#ConfigurationProperties("some")
#Component("someProperties")
public class SomeProperties {
private int millis; // the property is some.millis
public int getMillis() {
return millis;
}
public void setMillis(int millis) {
this.millis = millis;
}
}
BackgroundTasks.java
package com.example.demo;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
#Component
public class BackgroundTasks {
/**
*
* Approach1: We can inject/access the property some.millis directly in #Value
* fashion even though we have configured it to bind with SomeProperties class
* using #ConfigurationProperties.
*
*
*/
#Scheduled(fixedRateString = "${some.millis}")
public void fromDirectInjection() {
System.out.println("Hi, I'm from DirectInjection method");
}
/**
*
* Approach2: Add #Component on SomeProperties and access the bean bean's
* property millis like below using Spring Expression language
*
*
*/
#Scheduled(fixedRateString = "#{#someProperties.millis}")
public void fromConfigurationProperty() {
System.out.println("Hi, I'm from ConfigurationProperty method");
}
}
DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
#SpringBootApplication
#EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
application.properties
some.millis=2000
Version Used
SpringBoot 2.6.0
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 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.0-SNAPSHOT</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>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
Output:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.0-SNAPSHOT)
2021-10-08 08:38:03.342 INFO 8092 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 14.0.2 on TO-GZ9M403-L with PID 8092 (D:\workspaces\configprop\demo (1)\demo\target\classes started by D1 in D:\workspaces\configprop\demo (1)\demo)
2021-10-08 08:38:03.345 INFO 8092 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2021-10-08 08:38:04.884 INFO 8092 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-10-08 08:38:04.902 INFO 8092 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-10-08 08:38:04.902 INFO 8092 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.53]
2021-10-08 08:38:05.050 INFO 8092 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-10-08 08:38:05.050 INFO 8092 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1631 ms
2021-10-08 08:38:05.644 INFO 8092 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
Hi, I'm from DirectInjection method
Hi, I'm from ConfigurationProperty method
2021-10-08 08:38:05.662 INFO 8092 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 2.995 seconds (JVM running for 3.712)
Hi, I'm from DirectInjection method
Hi, I'm from ConfigurationProperty method
Hi, I'm from DirectInjection method
Hi, I'm from ConfigurationProperty method
Hi, I'm from DirectInjection method
Hi, I'm from ConfigurationProperty method
Following should work fine assuming bean is created with someProperties by default and name is not overridden.
#Scheduled(fixedDelayString = "#{#someProperties.getMillis()}")
from Spring documentation:
When the #ConfigurationProperties bean is registered using configuration property scanning or via #EnableConfigurationProperties, the bean has a conventional name: -, where is the environment key prefix specified in the #ConfigurationProperties annotation and is the fully qualified name of the bean. If the annotation does not provide any prefix, only the fully qualified name of the bean is used.
The bean name in the example above is com.example.app-com.example.app.SomeProperties.
So the answer boils to:
if you use JavaBean style properties you can register bean with #Component or #Bean. Then you can use just the bean name in SPEL expression
if you use #ConstructorBinding to have immutable properties then you have to use fully qualified bean name with the enviroment key prefix like this:
#Scheduled(fixedRateString = "#{#'other-com.example.demo.OtherProperties'.millis}")
Here is sample project - https://github.com/marksutic/scheduler_fixedratestring, forked from Arun Sai

spring boot - #PostConstruct not called on #Component

I am new to spring, and I have created a new spring boot project using https://start.spring.io/ with no further dependencies, unzipped the zip file and opened the project in IntelliJ IDEA. I have not done any further configurations. I am now trying to setup a bean with a #PostConstruct method - however, the method is never invoked by spring.
These are my classes:
SpringTestApplication.java
package com.habichty.test.testspring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
#SpringBootApplication
public class SpringTestApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringTestApplication.class, args);
context.getBean(TestBean.class).testMethod();
}
}
TestBean.java
package com.habichty.test.testspring;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
#Component
public class TestBean {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private int a = 1;
public TestBean()
{
log.debug("Constructor of TestBean called.");
}
#PostConstruct
public void init()
{
log.debug("init()-Method of TestBean called.");
a = 2;
}
public void testMethod()
{
log.debug("Test Method of TestBean called. a=" + a);
}
}
When I start the application, this is my output:
:: Spring Boot :: (v1.5.9.RELEASE)
2018-01-22 13:15:57.960 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Starting SpringTestApplication on pbtp with PID 12035 (/home/pat/prj/testspring/testspring/target/classes started by pat in /home/pat/prj/testspring/testspring)
2018-01-22 13:15:57.962 DEBUG 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Running with Spring Boot v1.5.9.RELEASE, Spring v4.3.13.RELEASE
2018-01-22 13:15:57.962 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : No active profile set, falling back to default profiles: default
2018-01-22 13:15:58.018 INFO 12035 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#2931522b: startup date [Mon Jan 22 13:15:58 CET 2018]; root of context hierarchy
2018-01-22 13:15:58.510 DEBUG 12035 --- [ main] com.habichty.test.testspring.TestBean : Constructor of TestBean called.
2018-01-22 13:15:58.793 INFO 12035 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-01-22 13:15:58.822 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Started SpringTestApplication in 1.073 seconds (JVM running for 2.025)
2018-01-22 13:15:58.822 DEBUG 12035 --- [ main] com.habichty.test.testspring.TestBean : Test Method of TestBean called. a=1
2018-01-22 13:15:58.826 INFO 12035 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#2931522b: startup date [Mon Jan 22 13:15:58 CET 2018]; root of context hierarchy
2018-01-22 13:15:58.828 INFO 12035 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
As you can see, spring initializes the TestBean and also executes the testMethod() - but the init()-Method, annotated with #PostConstruct, is not invoked.
What am I doing wrong?
Any help is very appreciated.
UPDATE 1
In my application.properties, I have configured:
logging.level.com = DEBUG
Changing this to logging.level.root = DEBUG results in a massively bigger log. However, it still does not contain the debug message of my init() method.
UPDATE 2 Added package and import statements.
UPDATE 3 To further clarify that this is not a logging issue, I have added an new int to the code that should be altered by the init()-Method. As far as I understood the concept of the #PostConstruct annotation, it should be executed prior to any other method execution. As a consequence, the output of testMethod() should now contain a=2. In the updated output, you may see that this is not the case.
UPDATE 4 This is my 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.habichty.test.testspring</groupId>
<artifactId>springTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springTest</name>
<description>springTest</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<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-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>
The output of java -version:
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
Due to the new module system in Java9 SpringBoot-1.5.9 fails to process #PostConstruct as the annotation class is not on the classpath. The problem (or similar) is described here and here. There are a few ways to resolve it:
run the application with Java8, or, if still on Java9:
add javax.annotation:javax.annotation-api dependency to the POM, or
upgrade to a newer Spring-Boot of version 2.0.0+ (which is still PRERELEASE as of this writing) which incorporates that dependency;
I know this Problem is already solved, but as it is the first Stackoverflow Question that came up when I googled this problem I will leave this here:
I had the same issue and my error was that I had a typo in my package names. My class which was calling name had a different packagename than my SpringBootApplication class. So my main application was not finding my component.
So always check your package names if you have a similiar problems.
I guess you did not define something like
logging.level.root=debug
in your application.properties?
Without = no logs
With =
2018-01-22 12:34:06.117 DEBUG 8516 --- [main] com.example.demo.TestBean : Constructor of TestBean called.
...
2018-01-22 12:34:06.117 DEBUG 8516 --- [main] com.example.demo.TestBean : init()-Method of TestBean called.
...
2018-01-22 12:34:06.241 DEBUG 8516 --- [main] com.example.demo.TestBean : Test Method of TestBean called.
If you are using Java 9 or higher, then you will encounter an error when using #PostConstruct and #PreDestroy in your code.
Eclipse is unable to import #PostConstruct or #PreDestroy
When using Java 9 and higher, javax.annotation has been removed from its default classpath. That's why Eclipse can't find it.
Solution
Download the javax.annotation-api-1.3.2.jar from
https://search.maven.org/remotecontent?filepath=javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar
Copy the JAR file to the lib folder of your project
Use the following steps to add it to your Java Build Path.
Right-click your project, select Properties
On the left-hand side, click Java Build Path
In the top-center of dialog, click Libraries
Click Classpath and then Click Add JARs ...
Navigate to the JAR file /lib/javax.annotation-api-1.3.2.jar
Click OK then click Apply and Close
Eclipse will perform a rebuild of your project and it will resolve the related build errors.

What's wrong within the usage of BeanFactoryAnnotationUtils?

I'm trying to do simple call to the method
BeanFactoryAnnotationUtils.qualifiedBeanOfType
Here the pom.xml of the project :
<?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>
<groupId>beanfactoryannotationutils.sample</groupId>
<artifactId>BeanFactoryAnnotationUtilsProblem</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
The Application.java class
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
ListableBeanFactory beanFactory = ctx.getBeanFactory();
// This is working ... (#Autowired with #Qualifier(...) too)
Map<String, QualifiedInterface> qualifiedBeans = beanFactory.getBeansOfType(QualifiedInterface.class);
System.out.println("Existing qualified beans ...");
for (QualifiedInterface qualifiedBean : qualifiedBeans.values()) {
System.out.println(" " + qualifiedBean.toString());
for (Annotation annotation : qualifiedBean.getClass().getAnnotations()) {
System.out.println(" - " + annotation.toString());
}
}
// This is working too ...
Map<String, Object> qualifiedBeansFromCtx = ctx.getBeansWithAnnotation(Qualifier.class);
System.out.println("Existing qualified beans from context ...");
for (Object qualifiedBean : qualifiedBeansFromCtx.values()) {
System.out.println(" " + qualifiedBean.toString());
for (Annotation annotation : qualifiedBean.getClass().getAnnotations()) {
System.out.println(" - " + annotation.toString());
}
}
// This is not ...
QualifiedInterface processor = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
beanFactory, QualifiedInterface.class, "QualifierA");
System.out.println("The selected processor should be A " + processor);
}
}
An interface QualifiedInterface.java
public interface QualifiedInterface {
}
Two beans QualifiedA.java
#Component
#Qualifier("QualifierA")
public class QualifiedA implements QualifiedInterface {
#Override
public String toString() {
return "QualifiedA";
}
}
and QualifiedB.java :
#Component
#Qualifier("QualifierB")
public class QualifiedB implements QualifiedInterface {
#Override
public String toString() {
return "QualifiedB";
}
}
The whole in the same package and application, now run it :
2015-12-24 15:08:34.468 INFO 9524 --- [ main] l.p.e.b.Application : Starting Application on DTBE-DEV4 with PID 9524 (D:\Workspace_netbeans\BeanFactoryAnnotationUtilsProblem\target\classes started by eguenichon in D:\Workspace_netbeans\BeanFactoryAnnotationUtilsProblem)
2015-12-24 15:08:34.478 INFO 9524 --- [ main] l.p.e.b.Application : No profiles are active
2015-12-24 15:08:34.618 INFO 9524 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#11e18e8c: startup date [Thu Dec 24 15:08:34 CET 2015]; root of context hierarchy
2015-12-24 15:08:37.516 INFO 9524 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2015-12-24 15:08:37.524 INFO 9524 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2015-12-24 15:08:37.672 INFO 9524 --- [ main] l.p.e.b.Application : Started Application in 3.715 seconds (JVM running for 4.355)
Existing qualified beans ...
QualifiedA
- #org.springframework.stereotype.Component(value=)
- #org.springframework.beans.factory.annotation.Qualifier(value=QualifierA)
QualifiedB
- #org.springframework.stereotype.Component(value=)
- #org.springframework.beans.factory.annotation.Qualifier(value=QualifierB)
Existing qualified beans from context ...
QualifiedA
- #org.springframework.stereotype.Component(value=)
- #org.springframework.beans.factory.annotation.Qualifier(value=QualifierA)
QualifiedB
- #org.springframework.stereotype.Component(value=)
- #org.springframework.beans.factory.annotation.Qualifier(value=QualifierB)
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'QualifierA' is defined: No matching QualifiedInterface bean found for qualifier 'QualifierA' - neither qualifier match nor bean name match!
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:100)
at org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils.qualifiedBeanOfType(BeanFactoryAnnotationUtils.java:56)
at beanfactoryannotation.sample.beanfactoryannotationutilsproblem.Application.main(Application.java:45)
2015-12-24 15:08:37.684 INFO 9524 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#11e18e8c: startup date [Thu Dec 24 15:08:34 CET 2015]; root of context hierarchy
2015-12-24 15:08:37.686 INFO 9524 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2015-12-24 15:08:37.691 INFO 9524 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
The BeanFactoryAnnotationUtils.qualifiedBeanOfType doesn't seems to works as the qualified beans exists in the context but could not be retrieved. Do you have an idea of what's the problem is here ?
Thanks !
This is not provided before Spring 4.3 due to the default specification of the BeanFactoryAnnotationUtils class.
See : https://jira.spring.io/browse/SPR-13819
While looking at the code behind the BeanFactoryAnnotationUtils.qualifiedBeanOfType(...) method, I noticed that the qualifier is checked from an AbstractBeanDefinition object. When I dump this object on our example I can notice that the "qualifiers" map is empty ?!?!?
It looks like a bug in the way Spring loads the bean definition with annotated qualifiers.
There is already an open issue that looks quite similar: https://jira.spring.io/browse/SPR-13452
I guess you could open another one specifically with your test case.

Categories

Resources