From 56d80c8da2d533f97ff890fd15e181a9cf2b0ced Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 11:27:52 +0300 Subject: [PATCH 1/6] ignoring intellij unnecessary files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 14d6028..564deb6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ /.settings .classpath .project +/.idea/ +*.iml From 9db0f14bf698770931a2a0e797a78728135a0d9a Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 12:48:10 +0300 Subject: [PATCH 2/6] Slf4j & lombok dependencies added for better logging experience --- pom.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pom.xml b/pom.xml index a6344ea..ba8e729 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,18 @@ ${findbugs.version} + + org.projectlombok + lombok + 1.18.12 + + + + org.slf4j + slf4j-api + 1.6.6 + + junit junit From 5cff1e83bcc33971bd2d96fac6aa148d9d5c0918 Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 12:51:09 +0300 Subject: [PATCH 3/6] Slf4j loggers adapted on all components --- .../annotation/JavaBuildInAnnotations.java | 5 ++- .../processor/AnnotationProcessor.java | 41 +++++++++---------- .../annotation/services/DummyService.java | 4 +- .../java/annotation/services/LazyService.java | 4 +- .../annotation/services/SimpleService.java | 13 +++--- .../adv/java/reflection/ServiceLoader.java | 26 ++++++------ 6 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/main/java/ua/yet/adv/java/annotation/JavaBuildInAnnotations.java b/src/main/java/ua/yet/adv/java/annotation/JavaBuildInAnnotations.java index 2c02a97..8e1ff31 100644 --- a/src/main/java/ua/yet/adv/java/annotation/JavaBuildInAnnotations.java +++ b/src/main/java/ua/yet/adv/java/annotation/JavaBuildInAnnotations.java @@ -1,10 +1,13 @@ package ua.yet.adv.java.annotation; +import lombok.extern.slf4j.Slf4j; + /** * Sample class to showcase JDK's build-in annotations * * @author Yuriy Tkach */ +@Slf4j public class JavaBuildInAnnotations { @Deprecated @@ -16,7 +19,7 @@ public JavaBuildInAnnotations(@Deprecated int hello) { } public void someMethod(@Deprecated int haha) { - System.out.println(haha + hello); + log.info(String.valueOf(haha + hello)); } @SafeVarargs diff --git a/src/main/java/ua/yet/adv/java/annotation/processor/AnnotationProcessor.java b/src/main/java/ua/yet/adv/java/annotation/processor/AnnotationProcessor.java index 7f67343..aca8ecc 100644 --- a/src/main/java/ua/yet/adv/java/annotation/processor/AnnotationProcessor.java +++ b/src/main/java/ua/yet/adv/java/annotation/processor/AnnotationProcessor.java @@ -2,6 +2,7 @@ import java.lang.reflect.Method; +import lombok.extern.slf4j.Slf4j; import ua.yet.adv.java.annotation.Init; import ua.yet.adv.java.annotation.Note; import ua.yet.adv.java.annotation.Service; @@ -15,17 +16,18 @@ * annotation in them. If found, then it searches for @{@link Note} annotations * to output notes and the it inspects methods of class and search for @ * {@link Init} annotation on the method. - * + * * The result of inspection is output to {@link System#out}. - * + * * @author Yuriy Tkach * */ +@Slf4j public class AnnotationProcessor { /** * Main method that will call inspection on service classes - * + * * @param args * No arguments are expected */ @@ -42,19 +44,17 @@ public static void main(String[] args) { * Inspector method. Checks if @{@link Service} annotation is present. If * found then outputs its params and searches for @{@link Note} annotations. * Then calls method to inspect and output more information about the class. - * + * * @param service * Service class object */ private static void inspectService(Class service) { if (service.isAnnotationPresent(Service.class)) { - System.out.println("Class " + service.getSimpleName() - + " has annotation @Service"); - + log.info("Class " + service.getSimpleName() + " has annotation @Service"); Service annotation = service.getAnnotation(Service.class); - System.out.println(" Name: " + annotation.name()); + log.info(" Name: " + annotation.name()); if (annotation.lazyLoad()) { - System.out.println(" Service should load lazy"); + log.info(" Service should load lazy"); } inspectNotes(service); @@ -62,26 +62,26 @@ private static void inspectService(Class service) { inspectMethodInformation(service); } else { - System.out.println("Class " + service.getSimpleName() + log.info("Class " + service.getSimpleName() + " does not have annotation @Service"); } } /** * Searches for @{@link Note} annotations and outputs their value if found - * + * * @param service * Service class object */ private static void inspectNotes(Class service) { Note[] notes = service.getAnnotationsByType(Note.class); if (notes != null && notes.length > 0) { - System.out.println(" Founds notes:"); + log.info(" Founds notes:"); for (Note note : notes) { - System.out.println(" " + note.value()); + log.info(" " + note.value()); } } else { - System.out.println(" No notes found"); + log.info(" No notes found"); } } @@ -89,7 +89,7 @@ private static void inspectNotes(Class service) { * Inspects declared method of the class and searches @{@link Init} * annotation on them. If found outputs parameters of annotation and checks * if method accepts arguments. - * + * * @param service * Service class object */ @@ -99,27 +99,26 @@ private static void inspectMethodInformation(Class service) { for (Method method : methods) { if (method.isAnnotationPresent(Init.class)) { - System.out.println(" Method " + method.getName() + log.info(" Method " + method.getName() + " has annotation @Init"); Init ann = method.getAnnotation(Init.class); if (ann.suppressException()) { - System.out.println( - " Exceptions of method will be suppressed"); + log.info(" Exceptions of method will be suppressed"); } if (method.getParameterTypes().length != 0) { - System.out.println(" Method expects arguments!"); + log.info(" Method expects arguments!"); } } else { - System.out.println(" Method " + method.getName() + log.info(" Method " + method.getName() + " does not have annotation @Init"); } } } else { - System.out.println(" Service has no methods."); + log.info(" Service has no methods."); } } } diff --git a/src/main/java/ua/yet/adv/java/annotation/services/DummyService.java b/src/main/java/ua/yet/adv/java/annotation/services/DummyService.java index 2716480..7cf8649 100644 --- a/src/main/java/ua/yet/adv/java/annotation/services/DummyService.java +++ b/src/main/java/ua/yet/adv/java/annotation/services/DummyService.java @@ -1,5 +1,6 @@ package ua.yet.adv.java.annotation.services; +import lombok.extern.slf4j.Slf4j; import ua.yet.adv.java.annotation.Service; /** @@ -9,13 +10,14 @@ * @author Yuriy Tkach * */ +@Slf4j public class DummyService { /** * Init method that will never be called by service loader */ public void init() { - System.out.println("I am dumb"); + log.info("I am dumb"); } } diff --git a/src/main/java/ua/yet/adv/java/annotation/services/LazyService.java b/src/main/java/ua/yet/adv/java/annotation/services/LazyService.java index 79b1bd9..b5135ec 100644 --- a/src/main/java/ua/yet/adv/java/annotation/services/LazyService.java +++ b/src/main/java/ua/yet/adv/java/annotation/services/LazyService.java @@ -1,5 +1,6 @@ package ua.yet.adv.java.annotation.services; +import lombok.extern.slf4j.Slf4j; import ua.yet.adv.java.annotation.Init; import ua.yet.adv.java.annotation.Service; @@ -10,6 +11,7 @@ * @author Yuriy Tkach * */ +@Slf4j @Service(name = "Lazy service", lazyLoad = true) public class LazyService { @@ -21,7 +23,7 @@ public class LazyService { */ @Init public void init() throws Exception { - System.out.println("I was lazy inited"); + log.info("I was lazy inited"); } /** diff --git a/src/main/java/ua/yet/adv/java/annotation/services/SimpleService.java b/src/main/java/ua/yet/adv/java/annotation/services/SimpleService.java index 0bd03d1..56ecc63 100644 --- a/src/main/java/ua/yet/adv/java/annotation/services/SimpleService.java +++ b/src/main/java/ua/yet/adv/java/annotation/services/SimpleService.java @@ -1,5 +1,6 @@ package ua.yet.adv.java.annotation.services; +import lombok.extern.slf4j.Slf4j; import ua.yet.adv.java.annotation.Init; import ua.yet.adv.java.annotation.Note; import ua.yet.adv.java.annotation.Service; @@ -11,6 +12,7 @@ * @author Yuriy Tkach * */ +@Slf4j @Service(name = "Simple service") @Note("This is an interesting service") @Note("I bet you've never seen something like that :)") @@ -34,10 +36,9 @@ public class SimpleService { @Init public void initService() { inits++; - - System.out.println( - " >> Initializing in public init... (inits=" - + inits + ", const=" + CONST + ")"); + + log.info(" >> Initializing in public init... (inits=" + + inits + ", const = " + CONST + " )"); } /** @@ -49,7 +50,7 @@ public void initService() { @Init public void initServiceArgs(int arg) { inits++; - System.out.println(" >> Initializing with args ..."); + log.info(" >> Initializing with args ..."); } /** @@ -59,7 +60,7 @@ public void initServiceArgs(int arg) { @Init private void privateInit() { inits++; - System.out.println( + log.info( " >> Initializing in private init... (inits=" + inits + ", const=" + CONST + ")"); } diff --git a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java index b249097..97583de 100644 --- a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java +++ b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.Map; +import lombok.extern.slf4j.Slf4j; import ua.yet.adv.java.annotation.Init; import ua.yet.adv.java.annotation.Service; @@ -18,6 +19,7 @@ * * @author Yuriy Tkach */ +@Slf4j public class ServiceLoader { /** @@ -56,16 +58,16 @@ private static void loadService(String className) { createAndInitService(clazz); } catch (InstantiationException | IllegalAccessException e) { - System.err.println("Failed to create service instance for " + log.error("Failed to create service instance for " + className + ": " + e.getMessage()); } } else { - System.out.println("Failed to load service " + className + log.info("Failed to load service " + className + ": No Service annotation present"); } } catch (ClassNotFoundException e) { - System.err.println("Failed to load service " + className + ": " + log.error("Failed to load service " + className + ": " + e.getMessage()); } } @@ -89,14 +91,14 @@ private static void createAndInitService(Class clazz) servicesMap.put(annotation.name(), serviceObj); - System.out.println("Added service instance for " + clazz.getName() + log.info("Added service instance for " + clazz.getName() + ": " + annotation.name()); if (!annotation.lazyLoad()) { setPrivateField(serviceObj); invokeInitMethods(clazz.getDeclaredMethods(), serviceObj); } else { - System.out.println(" Service will lazy load"); + log.info(" Service will lazy load"); } } @@ -117,7 +119,7 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { if (method.isAnnotationPresent(Init.class)) { if (method.getParameterTypes().length > 0) { - System.out.println( + log.info( " Cannot call init method with arguments: " + method.getName()); } else { @@ -126,19 +128,19 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { if (!Modifier.isPublic(method.getModifiers())) { method.setAccessible(true); - System.out.println(" Made method accessible: " + log.info(" Made method accessible: " + method.getName()); } method.invoke(serviceObj); - System.out.println(" Invoked init method for service: " + log.info(" Invoked init method for service: " + method.getName()); } catch (Throwable e) { Init initAnnotation = method.getAnnotation(Init.class); if (initAnnotation.suppressException()) { - System.out.println(" Error occured during init: " + log.info(" Error occured during init: " + e.getMessage()); } else { throw new RuntimeException(e); @@ -169,10 +171,10 @@ private static void setPrivateField(Object serviceObj) { } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - System.out.println( + log.info( " Failed to set private field: " + e.getMessage()); } catch (NoSuchFieldException e) { - System.out.println(" Field 'inits' is not found in class"); + log.info(" Field 'inits' is not found in class"); } } -} +} \ No newline at end of file From ad67754dd04ed6f4875716f2b57495d5f868f771 Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 12:56:04 +0300 Subject: [PATCH 4/6] SonarLint issue fixed. - Replace nested try-catch block as inner one. --- .../adv/java/reflection/ServiceLoader.java | 72 ++++++++----------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java index 97583de..87d6de6 100644 --- a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java +++ b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java @@ -16,7 +16,7 @@ * methods marked with annotation @{@link Init} if lazyLoad=false. * In addition to that the class showcases the possibility to access private * fields and methods. - * + * * @author Yuriy Tkach */ @Slf4j @@ -30,9 +30,8 @@ public class ServiceLoader { /** * Main method that calls service loading by providing full class name of * the service - * - * @param args - * No arguments are expected + * + * @param args No arguments are expected */ public static void main(String[] args) { loadService("ua.yet.adv.java.annotation.services.SimpleService"); @@ -45,22 +44,15 @@ public static void main(String[] args) { * Method gets the class object from the provided className. * Then inspects the class to find annotation @{@link Service}. If found, * then calls {@link #createAndInitService(Class)} method. - * - * @param className - * Full class name of the service + * + * @param className Full class name of the service */ private static void loadService(String className) { try { Class clazz = Class.forName(className); if (clazz.isAnnotationPresent(Service.class)) { - try { - createAndInitService(clazz); - - } catch (InstantiationException | IllegalAccessException e) { - log.error("Failed to create service instance for " - + className + ": " + e.getMessage()); - } + createAndInitService(clazz); } else { log.info("Failed to load service " + className @@ -75,30 +67,31 @@ private static void loadService(String className) { /** * Creates new instance of the service class and puts it into the map. If * lazyLoad=false then invokes init methods. - * - * @param clazz - * Service class object - * @throws InstantiationException - * If instance of the service object can't be created - * @throws IllegalAccessException - * If constructor of the service object can't be accessed + * + * @param clazz Service class object + * @throws InstantiationException If instance of the service object can't be created + * @throws IllegalAccessException If constructor of the service object can't be accessed */ - private static void createAndInitService(Class clazz) - throws InstantiationException, IllegalAccessException { - Object serviceObj = clazz.newInstance(); + private static void createAndInitService(Class clazz){ + try { + Object serviceObj = clazz.newInstance(); - Service annotation = clazz.getAnnotation(Service.class); + Service annotation = clazz.getAnnotation(Service.class); - servicesMap.put(annotation.name(), serviceObj); + servicesMap.put(annotation.name(), serviceObj); - log.info("Added service instance for " + clazz.getName() - + ": " + annotation.name()); + log.info("Added service instance for " + clazz.getName() + + ": " + annotation.name()); - if (!annotation.lazyLoad()) { - setPrivateField(serviceObj); - invokeInitMethods(clazz.getDeclaredMethods(), serviceObj); - } else { - log.info(" Service will lazy load"); + if (!annotation.lazyLoad()) { + setPrivateField(serviceObj); + invokeInitMethods(clazz.getDeclaredMethods(), serviceObj); + } else { + log.info(" Service will lazy load"); + } + } catch (InstantiationException | IllegalAccessException e) { + log.error("Failed to create service instance for " + + clazz.getName() + ": " + e.getMessage()); } } @@ -108,11 +101,9 @@ private static void createAndInitService(Class clazz) * true. * If invocation throws exception, then catching it and re-throwing it if * suppressException=false. Otherwise, just output it. - * - * @param methods - * Array of service's methods - * @param serviceObj - * Service object + * + * @param methods Array of service's methods + * @param serviceObj Service object */ private static void invokeInitMethods(Method[] methods, Object serviceObj) { for (Method method : methods) { @@ -155,9 +146,8 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { * Trying to set private field value of the service object. The method will * fail if the field is not found. The method won't fail if the field is * found, however, the value won't change if the field is final primitive - * - * @param serviceObj - * Object of the service + * + * @param serviceObj Object of the service */ private static void setPrivateField(Object serviceObj) { try { From 1f7e514e1e1d2445b01fb7b96d2c8ce4145aa798 Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 13:06:12 +0300 Subject: [PATCH 5/6] SonarLint issue fixed. - Deprecated Class.newInstance() method replaced by suggested alternative. --- .../ua/yet/adv/java/reflection/ServiceLoader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java index 87d6de6..0ecc949 100644 --- a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java +++ b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java @@ -1,6 +1,7 @@ package ua.yet.adv.java.reflection; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; @@ -74,7 +75,7 @@ private static void loadService(String className) { */ private static void createAndInitService(Class clazz){ try { - Object serviceObj = clazz.newInstance(); + Object serviceObj = clazz.getDeclaredConstructor().newInstance(); Service annotation = clazz.getAnnotation(Service.class); @@ -89,7 +90,8 @@ private static void createAndInitService(Class clazz){ } else { log.info(" Service will lazy load"); } - } catch (InstantiationException | IllegalAccessException e) { + } catch (InstantiationException | NoSuchMethodException + | InvocationTargetException |IllegalAccessException e) { log.error("Failed to create service instance for " + clazz.getName() + ": " + e.getMessage()); } @@ -110,8 +112,7 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { if (method.isAnnotationPresent(Init.class)) { if (method.getParameterTypes().length > 0) { - log.info( - " Cannot call init method with arguments: " + log.info(" Cannot call init method with arguments: " + method.getName()); } else { @@ -127,7 +128,7 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { log.info(" Invoked init method for service: " + method.getName()); - } catch (Throwable e) { + } catch (Exception e) { Init initAnnotation = method.getAnnotation(Init.class); if (initAnnotation.suppressException()) { From bbad19f5b822bb72d69c94f8133db644b9f731af Mon Sep 17 00:00:00 2001 From: Ramazan Sakin Date: Wed, 9 Sep 2020 13:17:32 +0300 Subject: [PATCH 6/6] SonarLint issue fixed. - Cognitive Complexity of methods should not be too high --- .../adv/java/reflection/ServiceLoader.java | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java index 0ecc949..06a10e4 100644 --- a/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java +++ b/src/main/java/ua/yet/adv/java/reflection/ServiceLoader.java @@ -115,30 +115,31 @@ private static void invokeInitMethods(Method[] methods, Object serviceObj) { log.info(" Cannot call init method with arguments: " + method.getName()); } else { + invokeInitMethod(serviceObj, method); + } + } + } + } + + private static void invokeInitMethod(Object serviceObj, Method method) { + try { + if (!Modifier.isPublic(method.getModifiers())) { + method.setAccessible(true); + log.info(" Made method accessible: " + + method.getName()); + } + method.invoke(serviceObj); - try { + log.info(" Invoked init method for service: " + + method.getName()); + } catch (Exception e) { + Init initAnnotation = method.getAnnotation(Init.class); - if (!Modifier.isPublic(method.getModifiers())) { - method.setAccessible(true); - log.info(" Made method accessible: " - + method.getName()); - } - method.invoke(serviceObj); - - log.info(" Invoked init method for service: " - + method.getName()); - - } catch (Exception e) { - Init initAnnotation = method.getAnnotation(Init.class); - - if (initAnnotation.suppressException()) { - log.info(" Error occured during init: " - + e.getMessage()); - } else { - throw new RuntimeException(e); - } - } - } + if (initAnnotation.suppressException()) { + log.info(" Error occurred during init: " + + e.getMessage()); + } else { + throw new RuntimeException(e); } } } @@ -162,8 +163,7 @@ private static void setPrivateField(Object serviceObj) { } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { - log.info( - " Failed to set private field: " + e.getMessage()); + log.info(" Failed to set private field: " + e.getMessage()); } catch (NoSuchFieldException e) { log.info(" Field 'inits' is not found in class"); }