diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml
index 66b48733f2..5dccebd196 100644
--- a/libraries-3/pom.xml
+++ b/libraries-3/pom.xml
@@ -73,6 +73,18 @@
${cache2k.version}
pom
+
+
+ com.jcabi
+ jcabi-aspects
+ ${jcabi-aspects.version}
+
+
+ org.aspectj
+ aspectjrt
+ ${aspectjrt.version}
+ runtime
+
@@ -81,6 +93,36 @@
https://jitpack.io
+
+
+ libraries-3
+
+
+ com.jcabi
+ jcabi-maven-plugin
+ ${jcabi-maven-plugin.version}
+
+
+
+ ajc
+
+
+
+
+
+ org.aspectj
+ aspectjtools
+ ${aspectjtools.version}
+
+
+ org.aspectj
+ aspectjweaver
+ ${aspectjweaver.version}
+
+
+
+
+
1.78
@@ -93,5 +135,11 @@
0.43
2.7.2
1.2.3.Final
+
+ 0.22.6
+ 1.9.2
+ 0.14.1
+ 1.9.2
+ 1.9.2
diff --git a/libraries-3/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java b/libraries-3/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java
new file mode 100644
index 0000000000..6bd345c59c
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/jcabi/JcabiAspectJ.java
@@ -0,0 +1,112 @@
+package com.baeldung.jcabi;
+
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import com.jcabi.aspects.Async;
+import com.jcabi.aspects.Cacheable;
+import com.jcabi.aspects.LogExceptions;
+import com.jcabi.aspects.Loggable;
+import com.jcabi.aspects.Quietly;
+import com.jcabi.aspects.RetryOnFailure;
+import com.jcabi.aspects.UnitedThrow;
+
+public class JcabiAspectJ {
+
+ public static void main(String[] args) {
+ try {
+ displayFactorial(10);
+ getFactorial(10).get();
+
+ String result = cacheExchangeRates();
+ if (result != cacheExchangeRates()) {
+ System.out.println(result);
+ }
+
+ divideByZero();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ divideByZeroQuietly();
+ try {
+ processFile();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ @Loggable
+ @Async
+ public static void displayFactorial(int number) {
+ long result = factorial(number);
+ System.out.println(result);
+ }
+
+ @Loggable
+ @Async
+ public static Future getFactorial(int number) {
+ Future factorialFuture = CompletableFuture.supplyAsync(() -> factorial(number));
+ return factorialFuture;
+ }
+
+ /**
+ * Finds factorial of a number
+ * @param number
+ * @return
+ */
+ public static long factorial(int number) {
+ long result = 1;
+ for(int i=number;i>0;i--) {
+ result *= i;
+ }
+ return result;
+ }
+
+ @Loggable
+ @Cacheable(lifetime = 2, unit = TimeUnit.SECONDS)
+ public static String cacheExchangeRates() {
+ String result = null;
+ try {
+ URL exchangeRateUrl = new URL("https://api.exchangeratesapi.io/latest");
+ URLConnection con = exchangeRateUrl.openConnection();
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ result = in.readLine();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ @LogExceptions
+ public static void divideByZero() {
+ int x = 1/0;
+ }
+
+ @RetryOnFailure(attempts = 2, types = {java.lang.NumberFormatException.class})
+ @Quietly
+ public static void divideByZeroQuietly() {
+ int x = 1/0;
+ }
+
+ @UnitedThrow(IllegalStateException.class)
+ public static void processFile() throws IOException, InterruptedException {
+ BufferedReader reader = new BufferedReader(new FileReader("baeldung.txt"));
+ reader.readLine();
+
+ Thread thread = new Thread();
+ thread.wait(2000);
+ }
+
+}