JAX-RS: Testing #Provider annotated Classes - java

When I try to create a new Object from a Class (annotated with #Provider) I get the following error:
java.lang.ExceptionInInitializerError: null
at xx.xxx.xxx.mapper.AExceptionMapper.<clinit>(AExceptionMapper.java:16)
The Provider looks like:
#Provider
public class AExceptionMapper implements ExceptionMapper<Blupp>
Same if trying to get a Mock via Mockito.

Solved, there ware other Errors hidden by this one. After getting Netbeans and Maven back to show them directly and after fixin, the error above disappears

Related

How to fix NullPointerException on Autowired JdbcTemplate

I am re-writing my question to hopefully make more sense and get some help.
I have a Controller, 2 ClassRepository, and 2 Service classes (one of which is not annotated with #Service as I get an error when I annotate it, so instead I just use it as a class)
The class not annotated with #Service I simply pass the rateRepository object from the annotated Service to the unannotated service.
If I execute the following code in my annotated service
String zone = rateRepository.getPurolatorZone(request.getShipToZip().substring(0,3));
it works great.
however in my unannotated class where i instantiate the class
InternationalRateService internationalRateService = new InternationalRateService(this.rateRepository);
UPDATE:
I annotated my InternationalRateService class with #Service and decided to autowire the repository itself, and I still get a null pointer exception on the getPurolatorZone method.. I dont understand why it works in one service but not the other when they are set up the same.
Second Update:
as it turns out, im an idiot because i didn't even think to check that it was possible that the string i pass to the repository was what was actually throwing the error. Turns out I never set the local shiptozip variable so. yea im an idiot .
Spring will inject dependencies only in spring managed beans. If you create an object with new then it's not spring managed bean.
In your case, object of InternationalRateService is not managed, as you created by new operator.
So, inject InternationalRateService in your controller, so that all dependencies are injected

How to Mock Custom Jackson Deserializer Response in Spring Boot 1.5.9

In a Spring Boot 1.5.9 project, I'm currently trying to use #WebMvcTest to run a test against one of my controllers. The entity being operated on has a #JsonDeserializer() annotation on one of its properties pointing to a custom class. I'm attempting to mock the result of the deserialize() call in a test without invoking the body.
However, when trying to do the following, I'm getting a NullPointerException error on a line within the deserialize() method, which suggests the actual method body is being executed:
#Autowired
private MockMvc mvc;
#MockBean
private MyDeserializer myDeserializer
[...]
#Test
public void myTestMethod() {
doReturn(myDeserializedValue)
.when(myDeserializer)
.deserialize(
any(JsonParser.class),
any(DeserializationContext.class)
);
this.mvc.perform([...]) // perform mvc call that would invoke myDeserializer
logger.debug("Call complete"); // never gets to this line
}
I'm assuming the custom deserializer class is being invoked (possibly newed up) outside of the knowledge of Spring's ApplicationContext.
Is there any way to mock a custom deserializer, or do I need to bump this class up to use the full ApplicationContext via #SpringBootTest and let it fully execute?
If you want Jackson to use a specific deserializer object instance you need to register it via a module on the ObjectMapper instance. See the docs for an example with a serializer; you'll have to modify it slightly for your deserializer.
Otherwise, I assume Jackson will just instantiate a new instance of your class every time and never use your mock (or bean?) at all.

Error: Unable to find #SpringBootConfiguration when doing #WebMvcTest for Spring Controller

I am testing my controller given below
#Controller
public class MasterController {
#GetMapping("/")
public String goLoginPage(){
return "index";
}
}
I am following this Spring documentation to test my controller.
Now, I want to test my controller by just instantiating the web layer and not the whole Spring context as given in the documentation. Below is my code for the same.
#RunWith(SpringRunner.class)
#WebMvcTest
public class MasterControllerTestWithWebLayer {
#Autowired
MockMvc mockMvc;
#Autowired
MasterController masterController;
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
public void testLoginHome() throws Exception{
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(view().name("index"));
}
}
When I run this test I get the error Unable to find #SpringBootConfiguration,...etc. But I am confused why it is asking for Spring configuration when we do not want it to instantiate it but want to use only the web layer. Kindly point me to the right direction what is happening here. And also how to fix this. Thanks
So here is the solution:
The documentation on detecting test configuration says:
The search algorithm works up from the package that contains the test until it finds a #SpringBootApplication or #SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
So the #SpringBootApplication class should be higher in the package hierarchy than the test class e.g if test class is in package com.zerosolutions.controller then #SpringBootApplication class should be in a package higher than com.zerosolutions.controller package i.e com.zerosolutions or com.
Problem
But in case the #SpringBootApplication class is at the same level as test class it won't be able to find it i.e com.zerosolutions.general. In this case you'll get the following error:
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
Solution
If you are running an integrated test, you can explicitly mention the #SpringBootApplication class like this
#RunWith(SpringRunner.class)
#SpringBootTest(classes={SpringBootApp.class})
But if you want to do unit testing of a controller you don't need to fire up the whole Spring context. You can rather replace #SpringBootTest with #WebMvcTest(MasterController.class). This will instantiate only the web layer with MasterController and not the whole Spring context.
Problem
But the problem is you will again run into the error we faced earlier:
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...) with your test
And #WebMvtTest does not have a classes attribute like #SpringBootTest to explicitly mention the #SpringBootApplication class.
So there are two solutions to this.
Solution
First: Move your application class to a package higher than the test class i.e com.zerosolutions or com package.
Second: Mention your #SpringBootApplication class explicitly like below
#RunWith(SpringRunner.class)
#WebMvcTest(MasterController.class)
#ContextConfiguration(classes={SpringBootApp.class})
Hope that clears the Spring Test Configuration confusion. Thanks
If your Application.java class (in src/main/java) is located under
com.A.B
Your test class ApplicationTest.java (in src/test/java) need to be under
com.A.B or com.A.B.C or com.A.B.C.D
You will get this error if the test class is located under the following packages
com.A or com.A.C or com.A.D
In Spring boot
THE GENERAL RULE IS TEST CLASS PACKAGE NAME NEED TO START WITH THE PACKAGE NAME OF THE JAVA CLASS PACKAGE THAT IS GOING TO BE TESTED
I had the same error, and found that when I had generated the project my pom.xml showed my groupId as com.example rather than with my actual domain:
<groupId>com.example</groupId>
I corrected the pom.xml to be:
<groupId>com.mydomain</groupId>
Next, I changed the file structure from:
src/test/java/com/example to src/test/java/com/mydomain
Last, I had to update the package declaration inside my
SampleProjectApplicationTest.java
file to match the correct file structure. Once that was all in place, the tests worked fine.
I am not sure how I ended up with com.example where the rest of my project was correct, but the fix was that simple in my case.
Hopefully this helps someone.
check if src/test/java has same package name as the main class package.
src/test/java/com/example/abc is same as src/test/java/com/example/abc
Just replace the Test package name with the main Application class package name.
Example:- package com.kotlin.dealerMainApplication this is my main app package name so, I will put the same name in my Test package
This worked for me !

intellij incorrectly saying no beans of type found for autowired repository

I have created a simple unit test but IntelliJ is incorrectly highlighting it red. marking it as an error
No beans?
As you can see below it passes the test? So it must be Autowired?
I had this same issue when creating a Spring Boot application using their #SpringBootApplication annotation. This annotation represents #Configuration, #EnableAutoConfiguration and #ComponentScan according to the spring reference.
As expected, the new annotation worked properly and my application ran smoothly but, Intellij kept complaining about unfulfilled #Autowire dependencies. As soon as I changed back to using #Configuration, #EnableAutoConfiguration and #ComponentScan separately, the errors ceased. It seems Intellij 14.0.3 (and most likely, earlier versions too) is not yet configured to recognise the #SpringBootApplication annotation.
For now, if the errors disturb you that much, then revert back to those three separate annotations. Otherwise, ignore Intellij...your dependency resolution is correctly configured, since your test passes.
Always remember...
Man is always greater than machine.
Add Spring annotation #Repository over the repository class.
I know it should work without this annotation. But if you add this, IntelliJ will not show error.
#Repository
public interface YourRepository ...
...
If you use Spring Data with extending Repository class it will be conflict packages. Then you must indicate packages directly.
import org.springframework.data.repository.Repository;
...
#org.springframework.stereotype.Repository
public interface YourRepository extends Repository<YourClass, Long> {
...
}
And next you can autowired your repository without errors.
#Autowired
YourRepository yourRepository;
It probably is not a good solution (I guess you are trying to register repository twice). But work for me and don't show errors.
Maybe in the new version of IntelliJ can be fixed: https://youtrack.jetbrains.com/issue/IDEA-137023
My version of IntelliJ IDEA Ultimate (2016.3.4 Build 163) seems to support this. The trick is that you need to have enabled the Spring Data plugin.
Sometimes you are required to indicate where #ComponentScan should scan for components. You can do so by passing the packages as parameter of this annotation, e.g:
#ComponentScan(basePackages={"path.to.my.components","path.to.my.othercomponents"})
However, as already mentioned, #SpringBootApplication annotation replaces #ComponentScan, hence in such cases you must do the same:
#SpringBootApplication(scanBasePackages={"path.to.my.components","path.to.my.othercomponents"})
At least in my case, Intellij stopped complaining.
I always solve this problem doing de following..
Settings>Inspections>Spring Core>Code than you shift from error to warning the severity option
I am using spring-boot 2.0, and intellij 2018.1.1 ultimate edition and I faced the same issue.
I solved by placing #EnableAutoConfiguration in the main application class
#SpringBootApplication
#EnableAutoConfiguration
class App{
/**/
}
Check if you missed #Service annotation in your service class, that was the case for me.
Configure application context and all will be ok.
Have you checked that you have used #Service annotation on top of your service implementation?
It worked for me.
import org.springframework.stereotype.Service;
#Service
public class UserServiceImpl implements UserServices {}
Putting #Component or #configuration in your bean config file seems to work, ie something like:
#Configuration
public class MyApplicationContext {
#Bean
public DirectoryScanner scanner() {
return new WatchServiceDirectoryScanner("/tmp/myDir");
}
}
#Component
public class MyApplicationContext {
#Bean
public DirectoryScanner scanner() {
return new WatchServiceDirectoryScanner("/tmp/myDir");
}
}
Use #EnableAutoConfiguration annotation with #Component at class level. It will resolve this problem.
For example:
#Component
#EnableAutoConfiguration
public class ItemDataInitializer {
#Autowired
private ItemReactiveRepository itemReactiveRepository;
#Autowired
private MongoOperations mongoOperations;
}
simple you have to do 2 steps
add hibernate-core dependency
change #Autowired to #Resource.
==>> change #Autowired to #Resource
If you don't want to make any change to you code just to make your IDE happy. I have solved it by adding all components to the Spring facet.
Create a group with name "Service, Processors and Routers" or any name you like;
Remove and recreate "Spring Application Context" use the group you created previously as a parent.
As long as your tests are passing you are good, hit alt + enter by taking the cursor over the error and inside the submenu of the first item you will find Disable Inspection select that
For me the solution was to place #EnableAutoConfiguration in the Application class under the #SpringBootApplication its going to underline it because its redundant. Delete it and voila all you warnings regarding missing beans are vanished! Silly Spring...
And one last piece of important information - add the ComponentScan so that the app knows about the things it needs to wire. This is not relevant in the case of this question. However if no #autowiring is being performed at all then this is likely your solution.
#Configuration
#ComponentScan(basePackages = {
"some_package",
})
public class someService {
I am using this annotation to hide this error when it appears in IntelliJ v.14:
#SuppressWarnings("SpringJavaAutowiringInspection")
I had similar issue in Spring Boot application. The application utilizes Feign (HTTP client synthetizing requests from annotated interfaces). Having interface SomeClient annotated with #FeignClient, Feign generates runtime proxy class implementing this interface. When some Spring component tries to autowire bean of type SomeClient, Idea complains no bean of type SomeClient found since no real class actually exists in project and Idea is not taught to understand #FeignClient annotation in any way.
Solution: annotate interface SomeClient with #Component. (In our case, we don't use #FeignClient annotation on SomeClient directly, we rather use metaannotation #OurProjectFeignClient which is annotated #FeignClient and adding #Component annotation to it works as well.)
in my Case, the Directory I was trying to #Autowired was not at the same level,
after setting it up at the same structure level, the error disappeared
hope it can helps some one!
As most synchronisation errors between IntelliJ (IDE) and development environments.
Specially if you have automated tests or build that pass green all the way through.
Invalidate Cache and Restart solved my problem.
What you need to do is add
#ComponentScan("package/include/your/annotation/component") in AppConfiguration.java.
Since I think your AppConfiguraion.java's package is deeper than your annotation component (#Service, #Component...)'s package,
such as "package/include/your/annotation/component/deeper/config".
I had a similar problem in my application.
When I added annotations incorrect highliting dissapeared.
#ContextConfiguration(classes = {...})
IntelliJ IDEA Ultimate
Add your main class to IntelliJ Spring Application Context, for example Application.java
File -> Project Structure..
left side:
Project Setting -> Modules
right side: find in your package structure
Spring and add + Application.java
just add below two annotations to your POJO.
#ComponentScan
#Configuration
public class YourClass {
//TODO
}
#Autowired(required = false)
will shut intellij up
My solution to this issue in my spring boot application was to open the spring application context and adding the class for the missing autowired bean manually!
(access via Project Structure menu or spring tool window... edit "Spring Application Context")
So instead of SpringApplicationContext just containing my ExampleApplication spring configuration it also contains the missing Bean:
SpringApplicationContext:
ExampleApplication.java
MissingBeanClass.java
et voilà: The error message disappeared!
This seems to still be a bug in the latest IntelliJ and has to do with a possible caching issue?
If you add the #Repository annotation as mk321 mentioned above, save, then remove the annotation and save again, this fixes the problem.
Sometimes - in my case that is - the reason is a wrong import. I accidentally imported
import org.jvnet.hk2.annotations.Service
instead of
import org.springframework.stereotype.Service
by blindly accepting the first choice in Idea's suggested imports. Took me a few minutes the first time it happend :-)
All you need to do to make this work is the following code:
#ComponentScan
public class PriceWatchTest{
#Autowired
private PriceWatchJpaRepository priceWatchJpaRepository;
...
...
}
I just had to use #EnableAutoConfiguration to address it, however this error had no functional impact.

Java Spring and Groovy app with #Transactional - injection returns "proxy" instead of required type

I have added some groovy files to an existing java + spring project.
The project was working (i.e. past the tests).
I added "#Transactional" to one of the groovy methods and the tests broke.
(In order to add #Transactional, I had to change the Annotation on the class from #Service to #Controller, otherwise the #Transactional was ignored - yuck).
I started getting exceptions
The exceptions varied #Autowired did not find anything - NoSuchBeanDefinitionException
adding #Qualifier("loadTransactions") gave me the same
#Resource gave BeanNotOfRequiredTypeException: Bean named 'loadTransactions' must be of type [net.idt.workflow.LoadTransactions], but was actually of type [$Proxy33]
(I find this a better error message then the #Autowired that I always use :-( )
I changed the type to "Object" and the #Resource injection worked (I am a bit annoyed with #Autowired - so I did not bother trying that with Object :-/ )
I then used the following groovy code: loadTransactions.metaClass.object.process();which I feel "stinks", but WORKS.
My question is: how do I get the nice code that I expected i.e.
loadTransactions.process();
I should not have to know that the #Transactional is using some proxy
Thanks for your help
Shalom Deitch

Categories