Hello I'm working with a Spring boot App connecting to a mongo db, my problem is that my endpoint are not working it seems that they are not found by Component scan. I'm have been crazy because I'm blocked to continue developing and I'm not able to identify the issue. All seems to be ok. I suppose that maybe is something related with the versions, but not pretty sure.
This is my controller:
package com.mercadolibre.mutants.controllers;
import com.mercadolibre.mutants.entities.Product;
import java.util.concurrent.CompletableFuture;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProductController {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductController.class);
public static final String SHORTEN_URL_PATH = "/shorten";
public static final String URL_PATH = "/{id}";
#RequestMapping(value = SHORTEN_URL_PATH, method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public CompletableFuture<String> shortenUrl(#RequestBody #Valid final Product shortenUrlDto, HttpServletRequest request) throws Exception {
LOGGER.info("Url to shorten: " );
CompletableFuture<String> shortenedUrl = null;
String localURL = request.getRequestURL().toString();
//shortenedUrl = shortUrlService.shortenURL(localURL, shortenUrlDto.getUrl());
LOGGER.info("Shortened url to: " + shortenedUrl);
return shortenedUrl;
}
#GetMapping(URL_PATH)
public CompletableFuture<String> retrieveOriginalUrl(#PathVariable String id) throws Exception {
LOGGER.info("short url to redirect: " + id);
//CompletableFuture<String> redirectUrlString = shortUrlService.getLongURLFromID(id);
// LOGGER.info("Original URL: " + redirectUrlString);
return null;
}
}
This is my Application class:
package com.mercadolibre.mutants;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication()
public class MutantsApplication {
public static void main(String[] args) {
SpringApplication.run(MutantsApplication.class, args);
}
}
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 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.1.16.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mercadolibre</groupId>
<artifactId>mutants</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mutants</name>
<description>Project for Java Challengue</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Lovelace-SR9</version>
<type>pom</type>
</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>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
From the comments, I would say you have a problem with the docker configuration where you are deploying your api, I would do the next validations:
Check your api is being served in the 8080 inside your docker container.
Check if you have correctly configured your docker container so the 8080 port (or the one used by your api) is open.
Check if (for some strange reason) you don't have another api running in 8080 in the docker container.
Finally, get into the SSH of your container and then (if you are running some UNIX SO) make a CURL request to the url and check the answer.
Hopes this helps.
Related
I made two apps with similar code on Spring Boot.
Reactive Netty spring boot webflux r2dbc.
Nonreactive Tomcat spring boot postgres.
I expect reactive one is faster or has the same speed. But it is slower 6th time.
I don't see any blocks there. In my opinion it is fully nonblocking app. Why so slowly?
For testing I have been using J-METER.
200 threads 200 times
getAll 400 strings
Latency of response nonreactive app - 190-240 ms.
Latency of response reactive app - 1290-1350 ms.
reactive 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.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>reactive</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>reactive</name>
<description>reactive</description>
<properties>
<java.version>1.8</java.version>
<mapstruct.version>1.4.2.Final</mapstruct.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</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>
Spring boot entry point
#SpringBootApplication(exclude = {ReactiveSecurityAutoConfiguration.class})
#Configuration
#EnableR2dbcRepositories
public class ReactiveApplication {
public static void main(String[] args) {
SpringApplication.run(ReactiveApplication.class, args);
}
}
application.yml
server:
port : 8083
spring:
data:
r2dbc:
repositories:
enabled: true
r2dbc:
url: r2dbc:postgresql://localhost:5432/reactive
username: postgres
password: 12345
properties:
schema: bookshop
logging:
level:
org:
springframework:
r2dbc: DEBUG
Controller
package com.example.reactive.controller;
import com.example.reactive.entity.Book;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
#RequestMapping("/book")
public interface BookController {
#ResponseStatus(code = HttpStatus.OK)
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
Mono<Book> saveBook(#RequestBody Book book);
#ResponseStatus(code = HttpStatus.OK)
#GetMapping("/{id}")
Mono<Book> getBookById(#PathVariable Long id);
#ResponseStatus(code = HttpStatus.OK)
#GetMapping("/all")
Flux<Book> getAllBooks();
}
ControllerImpl
package com.example.reactive.controller.impl;
import com.example.reactive.controller.BookController;
import com.example.reactive.entity.Book;
import com.example.reactive.repository.BookRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
#RestController
#RequiredArgsConstructor
public class BookControllerImpl implements BookController {
private final BookRepository bookRepository;
#Override
public Mono<Book> saveBook(Book book) {
return bookRepository.save(book);
}
#Override
public Mono<Book> getBookById(Long id) {
return bookRepository.findById(id);
}
#Override
public Flux<Book> getAllBooks() {
return bookRepository.findAll();
}
}
Entity
package com.example.reactive.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class Book {
#Id
private Long id;
private String name;
private String author;
private String text;
}
Repository
package com.example.reactive.repository;
import com.example.reactive.entity.Book;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
public interface BookRepository extends ReactiveCrudRepository<Book, Long> {
}
If you need more information, feel free to write comments.
EDITED
After adding thread-pool parameters of min value 50 and max value 100, reactive app become faster.
I don't use get All property to compare apps.
For testing I have been using J-METER.200 threads 200 times
get 1 different string
Latency of response nonreactive app - middle 6 ms.
Latency of response reactive app - middle 10 ms.
post 1 string
Latency of response nonreactive app - middle 37 ms.
Latency of response reactive app - middle 6 ms!!!!!!!!
Computer parameters
Processor Intel® Core™ i 5-10400 CPU # 2.90 GHz × 12.
RAM 16,0 GB.
First, to answer in a more general sense, the reactive stack is - unfortunately - not a one-size-fits-all shortcut to make applications perform better. One of the main benefits of using WebFlux is its ability to handle more concurrent requests when compared to servlet.
Now to the problem at hand. I will assume that the latency values you have given are averages obtained from a fairly heavy load test.
One thing that comes to mind is that the first couple of requests served by a reactive application after its startup always take extra time - this can be attributed to Netty initialization. For this reason, in busy production environments, we have always had some form of automated warmup in place. Although I assume your load tests send so many requests that this should not be a factor.
For the above reason, I am inclined to believe that the cause of this slowdown could be simply down to excessive logging - setting the package org.springframework.r2dbc to DEBUG level logs every single SQL statement executed - and in the context of a load test, excessive logging wreaks havoc on performance and pollutes results.
Edit
For reference, I have built two similar apps with postgres based on your post. One servlet with JPA, and one reactive with R2DBC.
I have executed a 30-second Gatling load test on both, simulating 200 constant concurrent users. The actual request sent was either an insert or a get operation, both had equal weight when it came to choosing.
The load test in question:
public class ReactiveApplicationLoadTest extends Simulation {
private static final String BASE_URL = "http://localhost:8083";
private static final String BOOK_URI = "/book";
HttpProtocolBuilder httpProtocol = http
.baseUrl(BASE_URL);
ScenarioBuilder scenario = scenario("Get All Books").randomSwitch()
.on(
Choice.withWeight(1, exec(
http("GET_ONE")
.get(BOOK_URI + "/1")
)),
Choice.withWeight(1, exec(
http("INSERT")
.post(BOOK_URI)
.header("Content-Type", "application/json")
.body(StringBody("{\"name\": \"book\", \"author\": \"author\", \"text\": \"text\"}"))
))
);
{
setUp(
scenario.injectClosed(constantConcurrentUsers(200).during(30)).protocols(httpProtocol)
);
}
}
My computer's relevant specifications:
CPU: intel i7 11700K
RAM: 32GB DDR4 # 3600MHz
The source code of the two apps:
GitHub
The results:
Reactive
Servlet
My results lean heavily in the favor of the reactive application, both in response times and the number of KO'd requests.
You might notice that I did not include a "get all" request in the load test. The reason for this is that the sheer amount of items created in the load test don't mix well with this broad query, especially in a reactive context - this might be the source of the results you are seeing.
Takeaway
Consider adding some form of pagination to your "get all" endpoints in both apps OR omit these calls from your load test, and then try again.
This issue was solved by adding properties of thread-pool to
application.yml
spring:
r2dbc:
pool:
initial-size: 10
max-size: 20
Also There is was used non-blocking subscription to repository
Mono.defer(()-> Mono.from(bookRepository.findAllBookWithDelayById(id)
.subscribeOn(Schedulers.boundedElastic())));
Application became 1.8 times faster then non-reactive.
I want to create a simple hello world app with SpringBoot where localhost:8080/welcome.html will show us Hello World.
I think I did all good but I can't see HelloWorld, just Whitelabel error page.
This is the link to my repo. If someone could check what is wrong I will be very happy!
https://github.com/BElluu/ElenXHello
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.springbelluu</groupId>
<artifactId>springboot-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-helloworld</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.BUILD-SNAPSHOT</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>10</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.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</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>
SpringbootHelloworldApplication.java
package com.springbelluu.springboothelloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringbootHelloworldApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootHelloworldApplication.class, args);
}
}
TestController.java
package com.javainuse.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class TestController {
#RequestMapping("/welcome.html")
public ModelAndView firstPage() {
return new ModelAndView("welcome");
}
}
application.properties
spring.mvc.view.prefix:/WEB-INF/jsp/
spring.mvc.view.suffix:.jsp
For starters if you want to get starter with Spring Boot I strongly suggest NOT to use JSP. There are quite some limitations when using JSP, one of them is it doesn't work with jar packaging. Secondly it is a dated technology and doesn't receive much attention/updates anymore apart from keeping if functional in newer JEE versions. It is better to use something like Thymeleaf.
Next you are using snapshots versions for a version of Spring Boot that already is at 2.1.3.RELEASE (at the moment of writing).
That being said change your pom.xml to the following (fix version, remove JSP stuff and replace with Thymeleaf).
<?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.springbelluu</groupId>
<artifactId>springboot-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-helloworld</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>10</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-thymeleaf</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>
NOTE: Because you now use a final version you don't need all the repositories in your pom.xml anymore!.
Now delete your JSP and create a welcome.html in src/main/resources/templates/. (You can actually remove your webapp directory in full.
<html>
<body>
<h1>Welcome! Spring Boot for ElenX</h1>
</body>
</html>
The setup you now have is more modern and easier to work with then JSP.
In your application.properties remove the spring.mvc.view properties as Spring Boot will automatically configure Thymeleaf with correct settings.
#BElluu ... your main application and Controller class are in different packages so componentscan is not working ...just check package level
package com.springbelluu.springboothelloworld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringbootHelloworldApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootHelloworldApplication.class, args);
}
}
package com.javainuse.controllers;
// use this package package com.springbelluu.springboothelloworld;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class TestController {
#RequestMapping("/welcome.html")
public ModelAndView firstPage() {
return new ModelAndView("welcome");
}
}
Go to below link by Spring Framework to create brand new Springboot Project:
https://start.spring.io/
or
1.Create a simple web application
Now you can create a web controller for a simple web application.
src/main/java/hello/HelloController.java
package hello;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
#RestController
public class HelloController {
#RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
Create an Application class
Here you create an Application class with the components:
src/main/java/hello/Application.java
package hello;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
}
Here is SpringBoot Main class file Noting Changed Here.
-----------------------------------------
package com.Encee.SpringBoot_HelloWorld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SpringBootHelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootHelloWorldApplication.class, args);
}
}
Here is controller package class
-----------------------------------------
package com.Encee.SpringBoot_HelloWorld.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class Controller {
#RequestMapping("/hello.html")
public String hello() {
return "Hello World";
}
}
-----------------------------------------
Now Main file run as Java Application will get your output.
SCREEN SHOT
Your issue has been fixed you can view the changes at my commit.
https://github.com/farooqrahu/ElenXHello/commits/master
I'm building a simple Spring application with the goal of returning "Hello world" as a foundation to build upon. I set up a clean project last night following this guide which worked and now I'm trying to bring an already existing project to the same functionality.
I have two files called ApplicationConfig.java and Controller.java tasked with returning a string when a certain URL is hit. When I visit localhost:8080 it renders my index.html with a link to the URL I wish to return a string at. When I visit the URL localhost:8080/home/greet it returns a 404.
My ApplicationConfig.java:
package application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ApplicationConfig {
public static void main(String[] args) {
SpringApplication.run (ApplicationConfig.class, args);
}
}
and my Controller.java
package controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/home")
public class Controller {
#RequestMapping("/greet")
public String greeting() {
return "Hello";
}
}
As far as I see /home/greet/ should produce a page that just reads "Hello" but this isn't the case. What is the issue?
Here is my pom.xml and what my project structure looks like, should they be relevant.
<?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-rest-service</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
<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>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
Your entrypoint class ApplicationConfig.java is in application package and Controller.java is in controller package.
SpringBoot scans for Spring components in the package( and sub-packages) where EntryPoint class is.
So move your controller to application or any nested package under application.
Step 1 : Add your ApplicationConfig.java in package abc.app;
Step 2 : Add your Controller.java in package abc.app.controller;.
Step 3 : add #ComponentScan("abc.app") in ApplicationConfig.java.
For Example :
ApplicationConfig.java:
package abc.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#ComponentScan("abc.app")
public class ApplicationConfig {
public static void main(String[] args) {
SpringApplication.run (ApplicationConfig.class, args);
}
}
Controller.java :
package abc.app.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class Controller {
#RequestMapping("/greet")
public String greeting() {
return "Hello";
}
}
I Hope you Find your Right Solution here.
I'm trying to upgrade a custom plugin for jira, 6.3.15 to 7.1.4 but when I upload the plugin on a jira test environment then fail and catalina.out is:
Plugin only requires permission [] which doesn't include 'execute_java', yet has some java code (classes, libs, spring context, etc), making it un- loadable.
googling I see that: https://docs.atlassian.com/atlassian-plugins-api/4.0.0-m004/atlassian-plugins-api/apidocs/com/atlassian/plugin/Permissions.html#addPermission(com.atlassian.plugin.Plugin,%20java.lang.String,%20com.atlassian.plugin.InstallationMode)
but I dont understand how to solve it, any idea?
Plugin:
import java.util.Date;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.event.type.EventType;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.worklog.Worklog;
import com.atlassian.jira.issue.worklog.WorklogImpl;
import com.atlassian.jira.issue.worklog.WorklogManager;
import com.atlassian.jira.event.issue.IssueEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AsignedListenerWorklog implements IssueEventListener {
private static final Logger logger = LoggerFactory.getLogger(AsignedListenerWorklog.class);
protected WorklogManager worklogManager = ComponentAccessor.getWorklogManager();
public void workflowEvent(IssueEvent event) {
if (event.getEventTypeId() != EventType.ISSUE_DELETED_ID) {
onAssigned(event);
}
}
public boolean isOktoAssign(Issue issue) {
if (issue.getAssignee() != null) {
for (Worklog w : worklogManager.getByIssue(issue)) {
if (w.getUpdateAuthorKey().equals(issue.getAssignee().getName().toLowerCase())) {
return false;
}
}
return true;
}
logger.error("Issue Assigment null");
return false;
}
public void onAssigned(IssueEvent event) {
Issue issue = event.getIssue();
if (isOktoAssign(issue)) {
WorklogImpl worklog = new WorklogImpl(
worklogManager,
issue,
issue.getId(),
issue.getAssignee().getName().toLowerCase(),
issue.getSummary(),
new Date(),
null,
null,
60L
);
logger.info("Add 1m " + worklog.getUpdateAuthor() + " at issue " + issue.getKey());
worklogManager.create(issue.getAssignee(), worklog, 0L, false);
}
}
}
And POM:
<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/maven-v4_0_0.xsd" >
<modelVersion>4.0.0</modelVersion>
<groupId>xxx.xxxx</groupId>
<artifactId>jira-worklog-plugin</artifactId>
<name>Worklog Plugin</name>
<version>3.0</version>
<description>Plugin</description>
<repositories>
<repository>
<id>atlassian</id>
<url>https://maven.atlassian.com/content/repositories/atlassian-public</url>
</repository>
<repository>
<id>antoher</id>
<url>https://maven.atlassian.com/content/groups/public</url>
</repository>
<repository>
<id>public</id>
<url>nexus</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-core</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>releases</id>
<url>nexus</url>
</repository>
</distributionManagement>
</project>
atlassian-plugin.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/maven-v4_0_0.xsd" >
<modelVersion>4.0.0</modelVersion>
<groupId>xxx.xxx</groupId>
<artifactId>jira-worklog-plugin</artifactId>
<name>Worklog Plugin</name>
<version>3.0</version>
<description>Plugin for update workflow on assigned issue</description>
<repositories>
<repository>
<id>atlassian</id>
<url>https://maven.atlassian.com/content/repositories/atlassian-public</url>
</repository>
<repository>
<id>antoher</id>
<url>https://maven.atlassian.com/content/groups/public</url>
</repository>
<repository>
<id>public</id>
<url>nexus</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-core</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>releases</id>
<url>nexus</url>
</repository>
</distributionManagement>
</project>
I changed the Pom:
<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/maven-v4_0_0.xsd" >
<modelVersion>4.0.0</modelVersion>
<groupId>xxx.xxx</groupId>
<artifactId>jira-worklog-plugin</artifactId>
<name>Worklog Plugin</name>
<version>3.0</version>
<description>Plugin for update workflow on assigned issue</description>
<repositories>
<repository>
<id>atlassian</id>
<url>https://maven.atlassian.com/content/repositories/atlassian-public</url>
</repository>
<repository>
<id>antoher</id>
<url>https://maven.atlassian.com/content/groups/public</url>
</repository>
<repository>
<id>public</id>
<url>nexus</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-api</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-core</artifactId>
<version>7.1.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>releases</id>
<url>nexus</url>
</repository>
</distributionManagement>
</project>
and the atlassian-plugin.xml on resources:
<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="jira-xxx-plugin"/>
<!-- add our web resources -->
<web-resource key="jira-xxx-plugin-resources" name="jira-xxx-plugin Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="jira-xxx-plugin.css" location="/css/jira-xxx-plugin.css"/>
<resource type="download" name="jira-xxx-plugin.js" location="/js/jira-xxx-plugin.js"/>
<resource type="download" name="images/" location="/images"/>
<context>jira-xxx-plugin</context>
</web-resource>
</atlassian-plugin>
and it works!
I am currently working on a POC to use Spring Boot with Spring Data JPA.
I want to fetch a record from the db using Spring Data JPA.
I am getting the below error
Error creating bean with name 'bookRepository': Cannot create inner bean '(inner bean)' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
Here are my configration class:
package com.boot.configration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#EnableAutoConfiguration
#ComponentScan
#EnableJpaRepositories
public class ApplicationStarter {
public static void main (String[] args) {
SpringApplication.run(ApplicationStarter.class, args);
}
}
Below is my reposatory
package com.boot.configration;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
#Repository
public interface BookRepository extends JpaRepository<Book, String> {
public Iterable<Book> findBooksByAuthor(#Param("author") String author);
}
And this is my controller
#RestController
public class BookController {
#Autowired
protected BookRepository bookRepository;
#RequestMapping(value = "/isbn")
#ResponseBody
public String book() {
Book book = bookRepository.findOne("2222222");
return "Book Name is = " + book.getTitle()+ " " + "Author is = " + book.getAuthor();
}
}
In the POM.xml i have the following dependencies:
<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>BOOT</groupId>
<artifactId>SpringBootProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.0.0.RC1</version>
</parent>
<repositories>
<repository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
<name>SpringBootProject</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
</project>
Please help me to solve this error
You could try using spring-boot 1.0.2.RELEASE?
I think you are missing database driver dependency.
As if you are using posgress you need to provide the driver jar.
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>