I am trying to use project lombok to generate a logger like the example here.
When I go to intelliJ, there is no code completion for the log I enter. I get the error below:
Code exerpt:
package com.example.clement.recipeproject.bootstrap;
import com.example.clement.recipeproject.domain.*;
import com.example.clement.recipeproject.repositories.CategoryRepository;
import com.example.clement.recipeproject.repositories.RecipeRepository;
import com.example.clement.recipeproject.repositories.UnitOfMeasureRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
#Slf4j
#Component
public class DevBootstrap implements ApplicationListener<ContextRefreshedEvent> {
private CategoryRepository categoryRepository;
private UnitOfMeasureRepository unitOfMeasureRepository;
private RecipeRepository recipeRepository;
public DevBootstrap(CategoryRepository categoryRepository, UnitOfMeasureRepository unitOfMeasureRepository, RecipeRepository recipeRepository) {
this.categoryRepository = categoryRepository;
this.unitOfMeasureRepository = unitOfMeasureRepository;
this.recipeRepository = recipeRepository;
}
// returns List<Recipe>
private List<Recipe> getRecipes() {
log.debug("I am a debug message");
*** Update:
Added some more photos to show that the slf4j log is coming up, but just no appropriate methods after it.
When I jump into #Slf4j I get this.
Annotation processors turned on, but unsure if the configuration is correct.
Do you add slf4j dependencies to the build.gradle like below
dependencies {
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
}
Are you sure that you imported the correct #Slf4 annotation from package lombok.extern.slf4j.Slf4j?
There is an annotation of the same name in package groovy.util.logging.Slf4j.
Related
My current dependency set-up for demo api:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-graphql:2.7.2-SNAPSHOT'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.7.2-SNAPSHOT'
testImplementation 'org.springframework:spring-webflux'
testImplementation 'org.springframework.graphql:spring-graphql-test:1.0.0'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
Test class:
import com.example.demo.dao.ProfileDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.graphql.test.tester.GraphQlTester;
import static org.springframework.test.util.AssertionErrors.assertNotNull;
#GraphQlTest
//#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {
#Autowired
GraphQlTester graphQlTester;
#MockBean
ProfileDao dao;
#Test
void contextLoads() {
assertNotNull("graphQlTester null", graphQlTester);
}
}
I've tried few approaches from varios advices from internet like using SpringBootTest instead of GraphQlTest but nothing worked.
I am creating a custom annotation NullCheck for method parameter to check value is null or not hello(#NullCheck String text), but I am not able to invoke Aspect around the Annotation.
Main Class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
#SpringBootApplication
#EnableAutoConfiguration
#EnableAspectJAutoProxy
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Controller class, just invoking an aspect for POC, not returning anything
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/")
class HelloController {
#GetMapping
public void hello() {
hello("hi");
}
private void hello(#NullCheck String text) {
System.out.println(text);
}
}
Annotation
package com.example.demo;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
#Documented
#Retention(RUNTIME)
#Target(ElementType.PARAMETER)
public #interface NullCheck { }
Aspect
package com.example.demo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
#Aspect
#Component
public class NullCheckAspect {
this is working
#Before("#annotation(org.springframework.web.bind.annotation.GetMapping)")
but this is not
#Before("#annotation(com.example.demo.NullCheck)")
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Before method:" + joinPoint.getSignature());
}
}
build.gradle
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
idea {
module {
// if you hate browsing Javadoc
downloadJavadoc = true
// and love reading sources :)
downloadSources = true
}
}
bootJar {
launchScript()
}
repositories {
mavenCentral()
jcenter()
}
bootJar {
launchScript()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.springframework.boot:spring-boot-devtools'
}
what am I missing?
As per my understanding and after doing some search on google, you can get method parameter and its value with particular annotation with following code:
package com.example.demo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
#Component
#Aspect
public class NullCheckAspect {
#Around("execution(* com.example.demo.HelloController.nullChecker(String))")
public Object around(ProceedingJoinPoint pJoinPoint) throws Throwable {
Object[] args = pJoinPoint.getArgs();
Method method = MethodSignature.class.cast(pJoinPoint.getSignature()).getMethod();
Annotation[][] parametersAnnotations = method.getParameterAnnotations();
Map<String, Object> annotatedParameters = new HashMap<>();
int i = 0;
for(Annotation[] parameters : parametersAnnotations) {
Object arg = args[i];
String name = method.getParameters()[i++].getDeclaringExecutable().getName();
for(Annotation parameter: parameters) {
if ((parameter instanceof NullCheck)) {
System.out.println("Found the null checker annotation with name: " + name);
System.out.println("Found the null checker annotation with arg: " + arg);
annotatedParameters.put(name, arg);
}
}
}
System.out.println(annotatedParameters);
return pJoinPoint.proceed(args);
}
}
And with the interface annotation:
package com.example.demo;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
#Component
#Retention(RUNTIME)
#Target(ElementType.PARAMETER)
public #interface NullCheck {
}
More details about my code you can check it at my github repository, I have created spring boot demo version and pushed it for you at https://github.com/krishnaiitd/learningJava/blob/master/springBoot/gs-spring-boot/src/main/java/com/example/demo/HelloController.java
This also include other type of aspects like tracking the time of a particular methods.
Hope this will help you to get the basic understanding of #Aspect in Spring boot.
I don't know why it is as it is but I had the same issue. This is can be solved easily by using Pointcuts, for example:
#Before("nulllCheckAnnotation()")
public void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Before method:" + joinPoint.getSignature());
}
}
#Pointcut("#annotation(com.example.demo.NullCheck)")
private void nulllCheckAnnotation() { }
Read more about pointcuts here if you interested: https://www.baeldung.com/spring-aop-pointcut-tutorial
I have this scenario: two maven modules (jdk6) A and B.
In module A I've defined these classes:
MyBeanAnnotation : an annotation for classes defined like this:
package x.y.z;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.TYPE)
public #interface MyBeanAnnotation {
String name();
}
MyAnnProcessor: a class extending AbstractProcessor defined like this:
package x.y.z;
import java.io.File;
import java.util.Date;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
#SupportedAnnotationTypes("x.y.z.MyBeanAnnotation")
#SupportedSourceVersion(SourceVersion.RELEASE_6)
public class MyAnnProcessor extends AbstractProcessor{
#Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
#Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Hello World!");
}
return true;
}
}
I've created a text file in META-INF/services named javax.annotation.processing.Processor
x.y.z.MyAnnProcessor
I can compile it, no problem.
In the module B:
pom.xml : created a dependency to module A
I've created a class MyAnnotatedBean annotated with MyBeanAnnotation
package x.y.z;
import x.y.z.MyBeanAnnotation;
#MyBeanAnnotation(name = "scemochileggee")
public class MyAnnotatedBean {
private String qweq = "qweq";
}
When I compile B from scratch (e.g. mvn clean install), the processor MyAnnProcessror gets correctly called, and I can see the printout in the compiler logs
On the other hand, when I edit it in Netbeans (I've only tried this IDE) and save the MyAnnotatedBean file, nothing happens and the MyAnnProcessor in not invoked.
Do you have any idea if there's a way to make MyProcessor work in incremental compilation as well?
Thanks in advance.
I am new to Cucumber and Spring Boot,I am developeing an Spring Boot application that implements CommandLineRunner and trying to integrate it with Cucumber Framework to run some tests and create corresponding reports.
Now my Cucumber test cases are running fine but before running test cases its runs my Springboot application (Application.java). Is this the expected behaviour or is there someway just to run my tests only.
Main Spring Boot class - Application.java Class:-
/**
* Main Application Class
*/
#SpringBootApplication
public class Application implements CommandLineRunner {
#Override
public void run(String... args) {
#Autowired
private GWMLController gwmlController;
#Autowired
private SmartXmlController mxMLController;
#Autowired
private ReportingController reportingController;
#Autowired
private ComparisionReportController comparisionReportController;
....
...
My busniess logic
}
Now My Cucumber Class are:-
AbstractDefination.java
package cucumberJava.steps;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
#RunWith(SpringRunner.class)
#ActiveProfiles("test")
#SpringBootTest
#AutoConfigureMockMvc
#WebAppConfiguration
public class AbstractDefinitions{
public AbstractDefinitions() {
}
}
TestValidations:-
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
#ContextConfiguration(classes = {CucumberConfiguration.class})
public class TestValidations extends AbstractDefinitions {
#Autowired
private GWMLController gwmlController;
#Autowired
private SmartXmlController mxMLController;
#Autowired
private ComparisionReportController comparisionReportController;
#Given("^GID map is not empty$")
public void guid_map_is_not_null() throws Throwable {
comparisonResultMap =
comparisionReportController.makeComparisionMappingMap
(comparisonResultMap);
assertFalse(comparisonResultMap.isEmpty());
}
CucumberConfiguration .java
#Configuration
#ComponentScan(basePackages = "au.com.nab.mx")
public class CucumberConfiguration {
}
And in my build.gradle i have:-
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-
test', version: '1.5.4.RELEASE'
compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0'
compile group: 'info.cukes', name: 'cucumber-java', version: '1.2.5'
compile group: 'info.cukes', name: 'cucumber-core', version: '1.2.5'
compile group: 'info.cukes', name: 'gherkin', version: '2.12.2'
testCompile group: 'org.slf4j', name: 'slf4j-simple', version: '1.6.1'
testCompile group: 'info.cukes', name: 'cucumber-spring', version: '1.2.5'
testCompile group: 'info.cukes', name: 'cucumber-junit', version: '1.2.5'
}
.Feature
Feature: Validations.feature
Scenario Outline: COMPARE_COLUMNS
Given GID map is not empty
When <smt> not-null and <gwml> not null
Then <smt> validateEqual <gwml>
#Smoke
Examples:
| smt | gwml |
| **SMT_GUID | **GWML_GUID |
| SMT_BUY_SELL | GWML_BUY_SELL |
Now My issue is whenever i run my application, it first runs my Application.java and then its runs my Cucumber test cases.Now i am not sure whether its expected befhaviour or i am missing something.
Regards,
Vikram Pathania
The answer is - yes it is expected behavior, as result of using SpringRunner.class and #SpringBootTest and #ContextConfiguration annotations.
Usage of #ContextConfiguration and #SpringBootTest will load the application context required for testing.
Docs :
http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html
I want to use Robolectric for Unit Testing but I am trying a simple test with robolectric and I am stuck at the beginning. I followed the manual, I did the same with the examples and even other posts couldn't help me. Every time I get the error message: cannot access path. class file for java.nio.file.Path not found.
My build.gradle is:
testCompile "org.robolectric:robolectric:3.3.2"
testCompile "org.robolectric:shadows-support-v4:3.3.2"
testCompile 'junit:junit:4.12'
My Test class is:
package com.dev.mann.chronoly;
import android.support.v7.widget.RecyclerView;
import org.junit.runner.RunWith;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowToast;
import org.robolectric.shadows.support.v4.SupportFragmentTestUtil;
import static
org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class)
public class CrngyMasterFragmentTestClass{
private CrngyMasterFragment mFrag;
RecyclerView mMainRecyclerView;
MainActivity activity;
#Before
public void setup() {
activity = Robolectric.buildActivity(MainActivity.class).create().start().visible().get();
//SupportFragmentTestUtil.startVisibleFragment(mFrag, MainActivity.class, R.id.master_frag_container);
}
#Test
public void checkEmptyFragments() throws Exception {
//SupportFragmentTestUtil.startVisibleFragment(mFrag, AppCompatActivity.class, R.id.master_frag_container);
assertThat(true);
// check the recyclerview items
//RecyclerView recyclerView = (RecyclerView) mFrag.getActivity().findViewById(R.id.mainRecyclerView);
//assertThat(recyclerView.isShown());
}
}
But every settings doesn't work.
Any help is much appreciated, thanks for any help.
From the comments, the solution was to replace the line
import static org.assertj.core.api.Assertions.assertThat;
with
import static org.assertj.core.api.Java6Assertions.assertThat;
as per the AssertJ documentation.