This question already has answers here:
SpringApplication.run main method
(3 answers)
Closed 1 year ago.
I have a service that has a function that prints a string :
#Service
public class Aservice {
public void write(String test) {
System.out.println(test);
}
}
I'm just trying to call this function in the main function, but it gives me a null pointer exception for the service, what am i doing wrong ?
#SpringBootApplication
public class TestApplication {
#Autowired
private Aservice aservice;
public static void main(String[] args) {
TestApplication test = new TestApplication();
test.start();
}
public void start() {
aservice.write("ddd");
}
}
here's the error:
Exception in thread "main" java.lang.NullPointerException
at com.example.test.TestApplication.start(TestApplication.java:19)
at com.example.test.TestApplication.main(TestApplication.java:15)
and here's my build.gradle:
plugins {
id 'org.springframework.boot' version '2.5.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
The correct way to run a Spring Boot application is to use the SpringApplication run method:
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
This will bootstrap the Spring framework, including component scanning, dependency injection, etc.
Related
Project 1 (annotation project):
build.gradle
plugins {
id 'java'
}
apply plugin: 'java'
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
annotationProcessor 'com.google.auto.service:auto-service:1.0.1'
implementation 'com.google.auto.service:auto-service:1.0.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
test {
useJUnitPlatform()
}
Annotation
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
public #interface Table {
String value();
String[] ignoreColumns() default {};
}
Processor
#AutoService(TableProcessor.class)
#SupportedAnnotationTypes("com.github.ahuangJM.annotations.Table")
#SupportedSourceVersion(SourceVersion.RELEASE_8)
public class TableProcessor extends AbstractProcessor {
#Override
public synchronized void init(ProcessingEnvironment processingEnv) {
System.out.println("init hit!");
super.init(processingEnv);
}
#Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
final Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "Processing...");
return true;
}
}
\resources\META-INF\javax.annotation.processing.Processor
org.example.processors.TableProcessor
Project 2 (annotation project consumer):
Annotation Consumer
#Table("user-info")
public class UserInfo {
}
build.gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation files("REDACTED\\code-generator-annotation.jar")
annotationProcessor files("REDACTED\\code-generator-annotation.jar")
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}
test {
useJUnitPlatform()
}
This should be a very simple annotation processor just printing debugging statements.
This all seems correct to me, but process() is not running when I build/run project 2. I have tried overriding getSupportedVersion() and getSupportedAnnotationTypes() as well. That didn't do anything. Also tried without #AutoService, that didn't change anything as well.
EDIT: why am i can getting the print() and/or printMessage() statement?
#AutoService(TableProcessor.class)
should be
#AutoService(Processor.class)
#Retention(RetentionPolicy.RUNTIME)
should be
#Retention(RetentionPolicy.SOURCE)
#AutoService(TableProcessor.class)
should be
#AutoService(AbstractProcessor.class) or #AutoService(Processor.class)
#autoservice(X) means you implement X, but i see a class or interface Processor in your question, so you have to be sure what implement what but your #autoservice first is wrong.
I have a compilation issue with implementation dependency when compiling with Gradle the following project that contains of 3 modules:
test-impl
test-lib
my-test
My error:
/Users/igor/projects/my-test/src/main/java/MyTest.java:4: error: cannot access TestImpl
lib.foo("");
^
class file for TestImpl not found
It is compiled when I change implemention to api or if I rename any of foo methods in TestLib class.
Gradle 6.0.1, Java 1.8.0_271-b09, OSX
Doesn't it look like a bug? Where to report?
All build.gradle files:
Module test-impl build.gradle:
apply plugin: 'java-library'
Module test-lib build.gradle:
apply plugin: 'java-library'
dependencies {
implementation project(':test-impl')
}
Module my-test build.gradle:
apply plugin: 'java-library'
dependencies {
api project(':test-lib')
}
All source codes:
TestImpl.java in test-impl module:
public class TestImpl {
}
TestLib.java in test-lib module:
public class TestLib {
public void foo(String s) {
}
private void foo(TestImpl impl) {
}
}
MyTest.java in my-test module:
public class MyTest {
public void test() {
TestLib lib = new TestLib();
lib.foo("");
}
}
I am trying to log exception using SpringBoot and AOP. Using gradlew and Java 1.8.
Main.java
#SpringBootApplication
#EnableAutoConfiguration
#EnableAspectJAutoProxy
public class Main implements CommandLineRunner {
#Override
public void run(String... args) {
try{
ThrowingExample();
}catch(Exception e){
System.out.println("This message is printed");
}
}
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
static void ThrowingMethod() throws FileNotFoundException {
throw new FileNotFoundException();
}
}
AfterThrowAspect.java
#Component("AfterThrowAspect")
#Aspect
public class AfterThrowAspect {
#AfterThrowing(pointcut = "execution(* *.*.*(..))", throwing = "exception")
public void logAfterThrowing(Exception exception) {
System.out.println("Not Printed #AfterReturning:"+new Date());
System.out.println("Exception caught:"+ exception.getMessage());**
}
}
My Gradle File is
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'idea'
mainClassName = 'learn.Main'
repositories {
maven {
url "http://repo1.maven.org/maven2"
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
configurations {
aspectjweaver
}
dependencies {
compile "joda-time:joda-time:2.2"
testCompile "junit:junit:4.12"
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile "org.springframework:spring-webmvc:4.+"
compile "org.springframework:spring-aop:4.+"
compile "org.springframework.boot:spring-boot-starter-web:1.+"
compile "org.aspectj:aspectjrt:1.+"
compile "org.slf4j:slf4j-api:1.+"
aspectjweaver "org.aspectj:aspectjweaver:1.+"
runtime configurations.aspectjweaver.dependencies
}
Method logAfterThrowing is never called after exception. I am using Intellj and ide says ThrowingMethod is AdvisedMethod.
I am new to Java. Looking around on web makes me feel this should work but not happening. It compiles and run but logAfterThrowing from AfterThrowAspect.java never called. All files are on same hierarchy and same package.
EDIT
I think I have found the problem with your code. Spring aspect-oriented programming will only work with beans that are maintained by spring container. Since the method throwing the exception is a static method there is no way spring can intercept this.
How to intercept static methods in Spring?
Solution
Define your method in a service or a component and autowire it.
Working example repo https://github.com/mirmdasif/springmvc/tree/master/aopexceptionhandling
Complete Answer
First, define your method in a service bean
#Service
public class ExceptionalService {
public void thorowException() throws Exception {
throw new Exception();
}
}
Second, Instead of #component annotation, you should use #configuration in your AspectJ class. Also, use proper package name in pointcut
#Aspect
#Configuration
public class ErrorInterceptor {
#AfterThrowing(pointcut = "execution(* net.asifhossain.*.*(..))", throwing = "ex")
public void errorInterceptor(Exception ex) {
ex.printStackTrace();
}
}
Third Autowire the service and use it.
#SpringBootApplication
#EnableAspectJAutoProxy
public class AopExampleApp implements CommandLineRunner {
#Autowired
ExceptionalService service;
#Override
public void run(String... args) throws Exception {
try {
service.thorowException();
thorowException();
} catch (Exception ex) {
// Do nothing Since aop will log the answer
}
}
public static void main(String[] args) {
SpringApplication.run(AopExampleApp.class);
}
public static void thorowException() throws Exception {
throw new Exception();
}
}
I have created a blog post with complete step by step procedure of how we can handle exception using Spring's Aspect Oriented Programming.
You can access it at the following link
Handling Exception Using Spring AOP
I am trying to setup Dagger 2.12 and I'm getting this error:
error: #dagger.android.ContributesAndroidInjector was used, but dagger.android.processor.AndroidProcessor was not found on the processor path
Here's how I've configured Dagger:
My Application class:
public final class App extends android.app.Application implements HasActivityInjector {
#Inject
DispatchingAndroidInjector<Activity> activityInjector;
#Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().build().inject(this);
}
#Override
public AndroidInjector<Activity> activityInjector() {
return activityInjector;
}
}
ActivityBindingModule:
#Module
public abstract class ActivityBindingModule {
#ContributesAndroidInjector(modules = SearchActivityModule.class)
abstract SearchActivity searchActivity();
}
SearchActivityModule:
#Module
public class SearchActivityModule {
#Provides
public SearchActivityDelegate getDelegate(SearchActivity searchActivity) {
return searchActivity;
}
#Provides
public SearchActivityPresenter providePresenter(SearchActivity searchActivity) {
return new SearchActivityPresenter(new OtherDependency(), searchActivity);
}
}
AppModule:
#Module(includes = { AndroidInjectionModule.class, ActivityBindingModule.class })
public abstract class AppModule {
}
Does anyone know what could be causing this error?
Go to your module level build.gradle, under
annotationProcessor 'com.google.dagger:dagger-android-processor:[YOUR VERSION NUMBER]',
add:
kapt 'com.google.dagger:dagger-android-processor:[YOUR VERSION NUMBER]'.
the only solution for me was using old version of dagger (2.16)
kotlin version : 1.2.71
// dagger
implementation 'com.google.dagger:dagger-android:2.16'
implementation 'com.google.dagger:dagger-android-support:2.16'
kapt "com.google.dagger:dagger-compiler:2.16"
kapt "com.google.dagger:dagger-android-processor:2.16"
Probably you would have missed the following dependency.
annotationProcessor 'com.google.dagger:dagger-android-processor:' + yourDaggerVersion
For Java
Add this to your build.gradle
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"
For Kotlin
Add this to your build.gradle
apply plugin: 'kotlin-kapt'
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
I think i am missing something basic, i can't get aspectJ to work.
(i am new to aspectj)
here is my aspect file
#Aspect
public class AspectAPILogger {
#Pointcut("execution(* *(..))")
public void atExecution(){
System.out.println("AspectAPILogger.atExecution------------");
}
#Around("atExecution()")
public void aroundX1(JoinPoint joinPoint) {
System.out.println("AspectAPILogger.aroundX1------------");
}
#Before("execution(* *(..))")
public void beforeX(JoinPoint joinPoint) {
System.out.println("AspectAPILogger.beforeX------------");
}
}
my gradle.build
repositories {
mavenCentral()
}
//https://plugins.gradle.org/plugin/aspectj.gradle
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.aspectj:gradle-aspectj:0.1.6"
}
}
apply plugin: "aspectj.gradle"
plugins {
id "aspectj.gradle" version "0.1.6"
}
....
ext.versionAspectJ = '1.8.10';
...
dependencies {
.....
//AOP
compile group: 'org.aspectj' , name: 'aspectjrt' , version: "$versionAspectJ"
compile group: 'org.aspectj' , name: 'aspectjweaver' , version: "$versionAspectJ"
.....
}
some small main
public class TestMain {
public static void main(String[] args) {
Utils.md5("---");
Utils.timerStart();
Utils.timerStop("Some log message ");
}
}
can you help me figure out what i am missing, i guess its something basic... i also tries this plugin 'https://github.com/NikitaKozlov/WeaverLite' but i can't get a simple aspect to work, please help...
my project is a simple gradle java project
thank you !!!