I have spent the last 2 hours trying to figure out just what in gods name is going on with my simple springboot rest app.
NO matter what I do, I simply cannot get the restcontroller to work, every URL I try gives me a 404. Here is my code below.
#RestController
public class PbxPortalRestControllerSet {
#RequestMapping("/testMe")
public String testMe()
{
return "I am alive";
}
}
#SpringBootApplication
public class PbxPortalApplication {
public static void main(String[] args) {
SpringApplication.run(PbxPortalApplication.class, args);
}
}
Application.properties file
server.port = 8088
can anyone tell what the heck is going on? I have done this tons of times before, but I can't for the life of me figure out why this refuses to work.
I try to to go to localhost:8088/testMe, and I get a 404.
If PbxPortalApplication and PbxPortalApplication classes are in different package, you need to tell your application to scan the controller while loading up the app context.
Add the #ComponentScan to your PbxPortalApplication class
#SpringBootApplication
#ComponentScan(basePackageClasses = PbxPortalRestControllerSet.class)
public class PbxPortalApplication
I found the issue. I was using the wrong POM entry. I was using Jersey somehow instead of the built in spring ones. For some reason even though I was using the wrong library, eclipse was telling me that my annotation entries were perfectly fine. Once i deleted the entry for Jersey everything worked
#RestController
public class DemoController {
#GetMapping(value= "/getName")
public String getName(){
return "This is a Spring Boot Application";
}
}
Main Class is simple:
package com.pcftest.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Can you try this once ?? And see if it works..
#RequestMapping(value= "/testMe" , method = RequestMethod.GET)
Basically sometimes when you dont provide the request method type you get such types of errors
It seems that you are you have placed your controller different sub package than spring SpringApplication file. So Controller is not accessible from Spring main()
Please add
#SpringBootApplication
#ComponentScan("ControllersPackege")
CodeSnipet:SpringBootApplication
#SpringBootApplication
#ComponentScan("ControllerPackege")
public class PbxPortalApplication {
public static void main(String[] args) {
SpringApplication.run(PbxPortalApplication.class, args);
}
}
CodeSnipet:Controller
#RestController
public class PbxPortalRestControllerSet {
#RequestMapping("/testMe")
public String testMe()
{
return "I am alive";
}
}
application.properties file
server.port = 8088
NB:
Best way to put in same package or put controller class in sub-package
Related
I would like to define multiple #SpringBootApplication configurations that should load different packages. So that I can only load certain parts of the application, depending on the -Dspring.profiles.active= property.
Eg, the following MyApp1 startup class should only auto load classes under com.myapp.config1 subpackages:
package com.myapp.config1
#SpringBootApplication
#Profile("app1")
public class MyApp1 {
public static void main(String[] args) {
SpringApplication.run(MyApp1.class, args);
}
}
And another package aside:
package com.myapp.config2
#SpringBootApplication
#Profile("app2")
public class MyApp2 {
public static void main(String[] args) {
SpringApplication.run(MyApp2.class, args);
}
}
Problem: I cannot have multiple main() in multiple classes, as I lateron want to run my app with mvn spring-boot:run. How could this be solved?
If you want to load different packages depending on a profile you should instead define different configuration classes that are annotated with different #ComponentScan annotations.
#Configuration
#ComponentScan("bar.foo")
#Profile("app1")
public class loadApp2 {
}
#Configuration
#ComponentScan("foo.bar")
#Profile("app2")
public class loadApp1 {
}
This is actually the recommended way of setting up configuration and is called "slicing" and is documented in the spring boot docs
If I understand your question properly, then you want to run different class based on profiles, then you can have profile like below:
#Configuration
#ComponentScan("abc")
#Profile("app1")
public class MyApp1 {
//
}
#Configuration
#ComponentScan("xyz")
#Profile("app2")
public class MyApp2 {
//
}
Now in your SpringBootapplication:
#SpringBootApplication
public class SpringApp {
#Autowired
Environment env;
public static void main(String[] args) {
if (Arrays.asList(env.getActiveProfiles()).contains("app1"))
SpringApplication.run(MyApp1.class, args);
else
SpringApplication.run(MyApp2.class, args);
}
}
Could solve it as follows.
package com.myapp
#SpringBootApplication(scanBasePackages = "com.myapp.config")
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
Which loads config:
package com.myapp.config
#Configuration
#Profile("app1")
#ComponentScan(basePackages = "com.myapp.app1")
public class App1Config {
//only load classes from app1 package
}
#Configuration
#Profile("app2")
#ComponentScan(basePackages = "com.myapp.app2")
public class App2Config {
//only load classes from app2 package
}
You could specify the main class in the spring boot plugin configuration. I am not sure if you are using gradle or maven... so cant tell you the exact config.
https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/#goals-repackage-parameters-details-mainClass
I have a Spring application with Apache Wicket (Its my first Spring-Application) and its autogenerated. If I run my application and I call it on localhost there is only shown a site with "TestDataManager is running" on it instead of the Site I call in the Main. I figured out that I have in the tests- package a class named ExampleController and its not from me. In this class is witten what is shown on localhost. But in my Main I dont call this Class.
Can Somone say how to fix this.
#SpringBootApplication
#RestController
public class Application extends WebApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public Class<? extends Page> getHomePage() {
return WhatToDoPage.class;
}
}
ExampleController:
#RestController
public class ExampleController {
#Value("TestDataManager is running")
private String message;
#GetMapping("/")
public String indexGet() {
return message;
}
}
Spring Boot scans the classpath, finds ExampleController and registers it as a REST controller bean.
Later when you make a call to / it uses it to return the response. Since you return a String without #GetMapping(produces = ...) it uses text/plain as response content type.
Apache Wicket is not involved in your application. I am not sure why you use/tag it.
Class may be annotated with #WebFilter(urlPatterns="*") but spring does not run it on request. Why? If I add #ServletComponentScan annotation to Application class. It will work fine. Сan somehow make it work in a different way?
#ServletComponentScan
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
#ServletComponentScan will fix the problem
I have project setup using Spring boot that loads individual components on startup. Each individual packages contain its own datasource, processes, etc. I can simply use this and it works fine
#SpringBootApplication(scanBasePackages = {
"com.package1",
"com.package2",
"com.package3"
})
public class Application extends SpringBootServletInitializer{
public static void main(String[] args){
SpringApplication.run(Application.class,args)
}
}
But currently, the number of indiviual projects are getting bigger. Is it possible to put the list of the components / packages to scan in an external properties file or spring vault? I'm not sure how to retrieve it, and is it possible to retrieve the properties before the boot?
Edit:
Currently I tried this:
#Import(AppConfig.class)
public class Application extends SpringBootServletInitializer{
public static void main(String[] args){
SpringApplication.run(Application.class,args)
}
}
#Configuration
#ComponentScan(basePackages = {$app.packages})
#EnableAutoConfiguration
public class AppConfig {
}
//in my properties file
app.packages = ["com.package1","com.package2","com.package3"]
but its not working
You are on right track but couple of minor mistakes, specify the packages by common separated in yml or properties file
app.packages = com.package1,com.package2,com.package3
Then use Spring Expression Language in #ComponentScan annotation
#ComponentScan(basePackages = {"${app.packages}"})
This can be done using a static string constant. I tried following and it is working.
ScanBasePackageTestApplication is in 3rd package other than "test.packageOne, test.packageTwo" packages. Then I tried to autowire single class from each of test.packageOne and test.packageTwo into class from main package and it worked fine.
#Configuration
#SpringBootApplication(scanBasePackages = PackagesScanMetaData.PACKAGES_TO_SCAN)
public class ScanBasePackageTestApplication {
public static void main(String[] args) {
SpringApplication.run(ScanBasePackageTestApplication.class, args);
}
}
public class PackagesScanMetaData {
public static final String PACKAGES_TO_SCAN = "test.packageOne, test.packageTwo";
}
In this case you can manage all the to be scanned package list in PackagesScanMetaData class. Hope this helps.
My Controller class is below.
#Controller
public class app {
#GetMapping(path = "/")
public #ResponseBody
String hello() {
return "Hello app";
}
}
It works fine when I navigate through url. But when this below code is added it says "Could not autowire. No beans of 'NoteRepository' type found".
#Autowired
NoteRepository noteRepository;
// Create a new Note
#PostMapping("/notes")
public Note createNote(#Valid #RequestBody Note note) {
return noteRepository.save(note);
}
App controller class is in the same package where main class(which run the application) is. but when we add above code to a controller in different package it doesn't show error. but it doesn't work when we navigate through url even a simple get method.
My main class is below.
#SpringBootApplication
#EnableJpaAuditing
public class CrudApplication {
public static void main(String[] args) {
SpringApplication.run(CrudApplication.class, args);
}
}
My Repository class is
#Repository
public interface NoteRepository extends JpaRepository<Note, Long> {
}
My project structure
I want to find solution to:
Inject an instance of NoteRepository. I always get the message "Could not autowire. No beans of type found" error. Spring cannot inject it, doesn't matter if the interface is in the same or a different package.
I am not able to run methods in a controller(MyController) that are located in a different package than application entry point.
The main symptom is this:
App controller class is in the same package where main class(which run the application) is. but when we add above code to a controller in different package it doesn't show error. but it doesn't work when we navigate through url even a simple get method.
By default, Spring Boot application will only auto discover beans declared in the same package than the main class. For beans that are in a different package, you need to specify to include them. You can use #ComponentScan for this.
package foo.bar.main;
//import statements....
//this annotation will tell Spring to search for bean definitions
//in "foo.bar" package and subpackages.
#ComponentScan(basePackages = {"foo.bar"})
#SpringBootApplication
#EnableJpaAuditing
public class CrudApplication {
public static void main(String[] args) {
SpringApplication.run(CrudApplication.class, args);
}
}
package foo.bar.controller;
//import statements....
//since #ComponentScan, now this bean will be discovered
#Controller
public class app {
#GetMapping(path = "/")
public #ResponseBody
String hello() {
return "Hello app";
}
}
For Spring Data to recognize which repositories should create, you should add #EnableJpaRepositories annotation to your main class. Also, in order for Spring Data and the JPA implementation to scan the entities, add #EntityScan:
#ComponentScan(basePackages = {"foo.bar"})
#SpringBootApplication
#EnableJpaAuditing
#EnableJpaRepositories("your.repository.packagename")
#EntityScan("your.domain.packagename")
public class CrudApplication {
//code...
}
you should add packages for spring to scan them
#SpringBootApplication(scanBasePackages={"package1", "package2"})