diff --git a/aws-lambda/README.md b/aws-lambda/README.md index 759c9dd506..0ae188fc97 100644 --- a/aws-lambda/README.md +++ b/aws-lambda/README.md @@ -6,3 +6,4 @@ This module contains articles about AWS Lambda - [Using AWS Lambda with API Gateway](https://www.baeldung.com/aws-lambda-api-gateway) - [Introduction to AWS Serverless Application Model](https://www.baeldung.com/aws-serverless) - [How to Implement Hibernate in an AWS Lambda Function in Java](https://www.baeldung.com/java-aws-lambda-hibernate) +- [Writing an Enterprise-Grade AWS Lambda in Java](https://www.baeldung.com/java-enterprise-aws-lambda) diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/CustomFoo.java b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/CustomFoo.java new file mode 100644 index 0000000000..388927fbfe --- /dev/null +++ b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/CustomFoo.java @@ -0,0 +1,10 @@ +package com.baeldung.java9.interfaces; + +public class CustomFoo implements Foo { + + public static void main(String... args) { + Foo customFoo = new CustomFoo(); + customFoo.bar(); // 'Hello world!' + Foo.buzz(); // 'Hello static world!' + } +} diff --git a/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/Foo.java b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/Foo.java new file mode 100644 index 0000000000..8ccee83b7e --- /dev/null +++ b/core-java-modules/core-java-9/src/main/java/com/baeldung/java9/interfaces/Foo.java @@ -0,0 +1,22 @@ +package com.baeldung.java9.interfaces; + +public interface Foo { + + public default void bar() { + System.out.print("Hello"); + baz(); + } + + public static void buzz() { + System.out.print("Hello"); + staticBaz(); + } + + private void baz() { + System.out.print(" world!"); + } + + private static void staticBaz() { + System.out.print(" static world!"); + } +} diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/interfaces/CustomFooUnitTest.java b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/interfaces/CustomFooUnitTest.java new file mode 100644 index 0000000000..d107c091fb --- /dev/null +++ b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/interfaces/CustomFooUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.java9.interfaces; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.assertj.core.api.Assertions.assertThat; + +class CustomFooUnitTest { + private ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private PrintStream originalOut = System.out; + + @BeforeEach + void setup() { + System.setOut(new PrintStream(outContent)); + } + + @AfterEach + void tearDown() { + System.setOut(originalOut); + } + + @Test + void givenACustomFooObject_whenCallingDefaultMethodBar_thenExpectedStringIsWrittenToSystemOut() { + CustomFoo customFoo = new CustomFoo(); + customFoo.bar(); + assertThat(outContent.toString()).isEqualTo("Hello world!"); + } + + @Test + void givenAFooInterface_whenCallingStaticMethodBuzz_thenExpectedStringIsWrittenToSystemOut() { + Foo.buzz(); + assertThat(outContent.toString()).isEqualTo("Hello static world!"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-arrays-guides/README.md b/core-java-modules/core-java-arrays-guides/README.md index 7338ff9523..00bb6b53c8 100644 --- a/core-java-modules/core-java-arrays-guides/README.md +++ b/core-java-modules/core-java-arrays-guides/README.md @@ -8,3 +8,4 @@ This module contains complete guides about arrays in Java - [What is \[Ljava.lang.Object;?](https://www.baeldung.com/java-tostring-array) - [Guide to ArrayStoreException](https://www.baeldung.com/java-arraystoreexception) - [Creating a Generic Array in Java](https://www.baeldung.com/java-generic-array) +- [Maximum Size of Java Arrays](https://www.baeldung.com/java-arrays-max-size) diff --git a/core-java-modules/core-java-exceptions-3/README.md b/core-java-modules/core-java-exceptions-3/README.md index e1372381a8..f79eb41a8b 100644 --- a/core-java-modules/core-java-exceptions-3/README.md +++ b/core-java-modules/core-java-exceptions-3/README.md @@ -8,3 +8,4 @@ - [Localizing Exception Messages in Java](https://www.baeldung.com/java-localize-exception-messages) - [Explanation of ClassCastException in Java](https://www.baeldung.com/java-classcastexception) - [NoSuchFieldError in Java](https://www.baeldung.com/java-nosuchfielderror) +- [IllegalAccessError in Java](https://www.baeldung.com/java-illegalaccesserror) diff --git a/core-java-modules/core-java-networking-3/README.md b/core-java-modules/core-java-networking-3/README.md index 09470fe88c..730231525f 100644 --- a/core-java-modules/core-java-networking-3/README.md +++ b/core-java-modules/core-java-networking-3/README.md @@ -5,4 +5,5 @@ This module contains articles about networking in Java ### Relevant Articles - [Finding a Free Port in Java](https://www.baeldung.com/java-free-port) +- [Downloading Email Attachments in Java](https://www.baeldung.com/java-download-email-attachments) - [[<-- Prev]](/core-java-modules/core-java-networking-2) diff --git a/core-java-modules/core-java-reflection-2/README.md b/core-java-modules/core-java-reflection-2/README.md index 3195cddc42..4c888bdf58 100644 --- a/core-java-modules/core-java-reflection-2/README.md +++ b/core-java-modules/core-java-reflection-2/README.md @@ -5,3 +5,4 @@ - [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static) - [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract) - [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method) +- [Finding All Classes in a Java Package](https://www.baeldung.com/java-find-all-classes-in-package) diff --git a/core-java-modules/core-java-regex/README.md b/core-java-modules/core-java-regex/README.md index 92321fa656..4c78f64d75 100644 --- a/core-java-modules/core-java-regex/README.md +++ b/core-java-modules/core-java-regex/README.md @@ -13,3 +13,5 @@ - [Regular Expressions \s and \s+ in Java](https://www.baeldung.com/java-regex-s-splus) - [Validate Phone Numbers With Java Regex](https://www.baeldung.com/java-regex-validate-phone-numbers) - [How to Count the Number of Matches for a Regex?](https://www.baeldung.com/java-count-regex-matches) +- [Find All Numbers in a String in Java](https://www.baeldung.com/java-find-numbers-in-string) +- [Understanding the Pattern.quote Method](https://www.baeldung.com/java-pattern-quote) diff --git a/core-java-modules/core-java-regex/src/test/java/com/baeldung/ignore/pattern/metacharacters/IgnoringPatternMetacharactersUnitTest.java b/core-java-modules/core-java-regex/src/test/java/com/baeldung/ignore/pattern/metacharacters/IgnoringPatternMetacharactersUnitTest.java index 921876c0d5..8c07282716 100644 --- a/core-java-modules/core-java-regex/src/test/java/com/baeldung/ignore/pattern/metacharacters/IgnoringPatternMetacharactersUnitTest.java +++ b/core-java-modules/core-java-regex/src/test/java/com/baeldung/ignore/pattern/metacharacters/IgnoringPatternMetacharactersUnitTest.java @@ -12,7 +12,7 @@ public class IgnoringPatternMetacharactersUnitTest { private static final String patternStr = "$100.50"; @Test - public void givenPatternStringHasMetacharacters_whenPatternMatchedWithoutEscapingMetacharacters_thenNoMatchesFound() { + public void whenMetacharactersNotEscaped_thenNoMatchesFound() { Pattern pattern = Pattern.compile(patternStr); Matcher matcher = pattern.matcher(dollarAmounts); @@ -25,7 +25,7 @@ public class IgnoringPatternMetacharactersUnitTest { } @Test - public void givenPatternStringHasMetacharacters_whenPatternCompiledUsingManuallyMetaEscapedPattern_thenMatchingSuccessful() { + public void whenMetacharactersManuallyEscaped_thenMatchingSuccessful() { String metaEscapedPatternStr = "\\Q" + patternStr + "\\E"; Pattern pattern = Pattern.compile(metaEscapedPatternStr); Matcher matcher = pattern.matcher(dollarAmounts); @@ -39,7 +39,7 @@ public class IgnoringPatternMetacharactersUnitTest { } @Test - public void givenPatternStringHasMetacharacters_whenPatternCompiledUsingLiteralPatternFromQuote_thenMatchingSuccessful() { + public void whenMetacharactersEscapedUsingPatternQuote_thenMatchingSuccessful() { String literalPatternStr = Pattern.quote(patternStr); Pattern pattern = Pattern.compile(literalPatternStr); Matcher matcher = pattern.matcher(dollarAmounts); diff --git a/core-java-modules/core-java-security-3/README.md b/core-java-modules/core-java-security-3/README.md index 4585b6cc86..970faaac88 100644 --- a/core-java-modules/core-java-security-3/README.md +++ b/core-java-modules/core-java-security-3/README.md @@ -4,5 +4,5 @@ This module contains articles about core Java Security ### Relevant Articles: -- [Secret Key and String Conversion in Java](https://www.baeldung.com/secret-key-and-string-conversion-in-java/) +- [Secret Key and String Conversion in Java](https://www.baeldung.com/java-secret-key-to-string) - More articles: [[<-- prev]](/core-java-modules/core-java-security-2) diff --git a/gradle/gradle-cucumber/README.md b/gradle/gradle-cucumber/README.md new file mode 100644 index 0000000000..a92593e959 --- /dev/null +++ b/gradle/gradle-cucumber/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Using Cucumber with Gradle](https://www.baeldung.com/java-cucumber-gradle) diff --git a/gradle/gradle-jacoco/build.gradle b/gradle/gradle-jacoco/build.gradle new file mode 100644 index 0000000000..ef9e0a9c7c --- /dev/null +++ b/gradle/gradle-jacoco/build.gradle @@ -0,0 +1,54 @@ + +plugins { + id 'java' + id 'jacoco' +} + +ext { + junitVersion = '5.7.2' + lombokVersion = '1.18.20' +} + +group 'com.com.baeldung' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}" + + compileOnly "org.projectlombok:lombok:${lombokVersion}" + annotationProcessor "org.projectlombok:lombok:${lombokVersion}" +} + +test { + useJUnitPlatform() + + finalizedBy jacocoTestReport // report is always generated after tests run +} + +jacocoTestReport { + dependsOn test // tests are required to run before generating the report + + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: [ + "com/baeldung/**/ExcludedPOJO.class", + "com/baeldung/**/*DTO.*", + "**/config/*" + ]) + })) + } +} + +jacoco { + toolVersion = "0.8.6" +} diff --git a/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.jar b/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..e708b1c023 Binary files /dev/null and b/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..da9702f9e7 --- /dev/null +++ b/gradle/gradle-jacoco/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradle/gradle-jacoco/gradlew b/gradle/gradle-jacoco/gradlew new file mode 100755 index 0000000000..4f906e0c81 --- /dev/null +++ b/gradle/gradle-jacoco/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradle/gradle-jacoco/gradlew.bat b/gradle/gradle-jacoco/gradlew.bat new file mode 100644 index 0000000000..ac1b06f938 --- /dev/null +++ b/gradle/gradle-jacoco/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/gradle/gradle-jacoco/lombok.config b/gradle/gradle-jacoco/lombok.config new file mode 100644 index 0000000000..7a21e88040 --- /dev/null +++ b/gradle/gradle-jacoco/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true diff --git a/gradle/gradle-jacoco/settings.gradle b/gradle/gradle-jacoco/settings.gradle new file mode 100644 index 0000000000..b0ed8f1486 --- /dev/null +++ b/gradle/gradle-jacoco/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'gradle-jacoco' diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/config/AppConfig.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/config/AppConfig.java new file mode 100644 index 0000000000..d103f4b4f5 --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/config/AppConfig.java @@ -0,0 +1,11 @@ +package com.baeldung.config; + +import com.baeldung.service.ProductService; + +public class AppConfig { + + public ProductService productService() { + return new ProductService(); + } + +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/domain/Product.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/domain/Product.java new file mode 100644 index 0000000000..c64b6d2eae --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/domain/Product.java @@ -0,0 +1,12 @@ +package com.baeldung.domain; + +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class Product { + private int id; + private String name; + +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ExcludedPOJO.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ExcludedPOJO.java new file mode 100644 index 0000000000..0f7278459e --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ExcludedPOJO.java @@ -0,0 +1,4 @@ +package com.baeldung.dto; + +public class ExcludedPOJO { +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ProductDTO.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ProductDTO.java new file mode 100644 index 0000000000..0ae1659c14 --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/dto/ProductDTO.java @@ -0,0 +1,4 @@ +package com.baeldung.dto; + +public class ProductDTO { +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Customer.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Customer.java new file mode 100644 index 0000000000..e7bb837a5c --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Customer.java @@ -0,0 +1,11 @@ +package com.baeldung.generated; + +@Generated +public class Customer { + // everything in this class will be excluded from jacoco report because of @Generated + + @Override + public String toString() { + return "Customer{}"; + } +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Generated.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Generated.java new file mode 100644 index 0000000000..865df8ca8a --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/generated/Generated.java @@ -0,0 +1,15 @@ +package com.baeldung.generated; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Documented +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +public @interface Generated { +} \ No newline at end of file diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/service/CustomerService.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/service/CustomerService.java new file mode 100644 index 0000000000..e6dbe8df5e --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/service/CustomerService.java @@ -0,0 +1,16 @@ +package com.baeldung.service; + +import com.baeldung.generated.Generated; + +public class CustomerService { + + //this method will be excluded from coverage due to @Generated. + @Generated + public String getProductId() { + return "An ID"; + } + + public String getCustomerName() { + return "some name"; + } +} diff --git a/gradle/gradle-jacoco/src/main/java/com/baeldung/service/ProductService.java b/gradle/gradle-jacoco/src/main/java/com/baeldung/service/ProductService.java new file mode 100644 index 0000000000..5f73ddc7fd --- /dev/null +++ b/gradle/gradle-jacoco/src/main/java/com/baeldung/service/ProductService.java @@ -0,0 +1,9 @@ +package com.baeldung.service; + +public class ProductService { + private static final double DISCOUNT = 0.25; + + public double getSalePrice(double originalPrice) { + return originalPrice - originalPrice * DISCOUNT; + } +} diff --git a/gradle/gradle-jacoco/src/test/java/com/baeldung/service/CustomerServiceUnitTest.java b/gradle/gradle-jacoco/src/test/java/com/baeldung/service/CustomerServiceUnitTest.java new file mode 100644 index 0000000000..63dd2c755a --- /dev/null +++ b/gradle/gradle-jacoco/src/test/java/com/baeldung/service/CustomerServiceUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.service; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class CustomerServiceUnitTest { + + @Test + public void givenCustomer_whenGetCustomer_thenReturnNewCustomer() { + CustomerService customerService = new CustomerService(); + assertNotNull(customerService.getCustomerName()); + } +} diff --git a/gradle/gradle-jacoco/src/test/java/com/baeldung/service/ProductServiceUnitTest.java b/gradle/gradle-jacoco/src/test/java/com/baeldung/service/ProductServiceUnitTest.java new file mode 100644 index 0000000000..a9d216785a --- /dev/null +++ b/gradle/gradle-jacoco/src/test/java/com/baeldung/service/ProductServiceUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.service; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ProductServiceUnitTest { + + @Test + public void givenOriginalPrice_whenGetSalePrice_thenReturnsDiscountedPrice() { + ProductService productService = new ProductService(); + double salePrice = productService.getSalePrice(100); + assertEquals(salePrice, 75); + } +} diff --git a/gradle/gradle-jacoco/src/test/resources/features/account_credited.feature b/gradle/gradle-jacoco/src/test/resources/features/account_credited.feature new file mode 100644 index 0000000000..bd7940d1a5 --- /dev/null +++ b/gradle/gradle-jacoco/src/test/resources/features/account_credited.feature @@ -0,0 +1,6 @@ +Feature: Account is credited with amount + + Scenario: Credit amount + Given account balance is 0.0 + When the account is credited with 10.0 + Then account should have a balance of 10.0 diff --git a/java-collections-conversions-2/pom.xml b/java-collections-conversions-2/pom.xml index 7845e0d934..74f955ebdd 100644 --- a/java-collections-conversions-2/pom.xml +++ b/java-collections-conversions-2/pom.xml @@ -44,6 +44,12 @@ ${hamcrest.version} test + + io.vavr + vavr + 0.10.3 + + diff --git a/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java b/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java new file mode 100644 index 0000000000..ee0943ec1c --- /dev/null +++ b/java-collections-conversions-2/src/test/java/com/baeldung/setiteration/SetIteration.java @@ -0,0 +1,74 @@ +package com.baeldung.setiteration; + +import com.google.common.collect.Sets; +import io.vavr.collection.Stream; +import org.junit.jupiter.api.Test; + +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; + +class SetIteration { + + @Test + void givenSet_whenIteratorUsed_shouldIterateOverElements() { + // given + Set names = Sets.newHashSet("Tom", "Jane", "Karen"); + + // when + Iterator namesIterator1 = names.iterator(); + Iterator namesIterator2 = names.iterator(); + + // then + namesIterator1.forEachRemaining(System.out::println); + while(namesIterator2.hasNext()) { + System.out.println(namesIterator2.next()); + } + } + + @Test + void givenSet_whenStreamUsed_shouldIterateOverElements() { + // given + Set names = Sets.newHashSet("Tom", "Jane", "Karen"); + + // when & then + String namesJoined = names.stream() + .map(String::toUpperCase) + .peek(System.out::println) + .collect(Collectors.joining()); + } + + @Test + void givenSet_whenEnhancedLoopUsed_shouldIterateOverElements() { + // given + Set names = Sets.newHashSet("Tom", "Jane", "Karen"); + + // when & then + for (String name : names) { + System.out.println(name); + } + } + + @Test + void givenSet_whenMappedToArray_shouldIterateOverElements() { + // given + Set names = Sets.newHashSet("Tom", "Jane", "Karen"); + + // when & then + Object[] namesArray = names.toArray(); + for (int i = 0; i < namesArray.length; i++) { + System.out.println(i + ": " + namesArray[i]); + } + } + + @Test + void givenSet_whenZippedWithIndex_shouldIterateOverElements() { + // given + Set names = Sets.newHashSet("Tom", "Jane", "Karen"); + + // when & then + Stream.ofAll(names) + .zipWithIndex() + .forEach(t -> System.out.println(t._2() + ": " + t._1())); + } +} diff --git a/kubernetes/k8s-intro/README.md b/kubernetes/k8s-intro/README.md index 6ac593452c..8c11f4d53e 100644 --- a/kubernetes/k8s-intro/README.md +++ b/kubernetes/k8s-intro/README.md @@ -17,3 +17,4 @@ If you get a valid response, then you're good to go. - [Paging and Async Calls with the Kubernetes API](https://www.baeldung.com/java-kubernetes-paging-async) - [Using Watch with the Kubernetes API](https://www.baeldung.com/java-kubernetes-watch) - [Using Namespaces and Selectors With the Kubernetes Java API](https://www.baeldung.com/java-kubernetes-namespaces-selectors) +- [Creating, Updating and Deleting Resources with the Java Kubernetes API](https://www.baeldung.com/java-kubernetes-api-crud) diff --git a/libraries-data-3/README.md b/libraries-data-3/README.md index fffdf65252..2c01d2e320 100644 --- a/libraries-data-3/README.md +++ b/libraries-data-3/README.md @@ -3,7 +3,7 @@ This module contains articles about libraries for data processing in Java. ### Relevant articles -- [Kafka Streams vs Kafka Consumer]() +- [Kafka Streams vs Kafka Consumer](https://www.baeldung.com/java-kafka-streams-vs-kafka-consumer) - More articles: [[<-- prev]](/../libraries-data-2) ##### Building the project diff --git a/logging-modules/log4j/README.md b/logging-modules/log4j/README.md index a7a7ea9643..371d0246ce 100644 --- a/logging-modules/log4j/README.md +++ b/logging-modules/log4j/README.md @@ -3,3 +3,4 @@ - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [A Guide to Rolling File Appenders](http://www.baeldung.com/java-logging-rolling-file-appenders) - [Logging Exceptions Using SLF4J](https://www.baeldung.com/slf4j-log-exceptions) +- [Log4j Warning: "No Appenders Could Be Found for Logger"](https://www.baeldung.com/log4j-no-appenders-found) diff --git a/logging-modules/log4j/src/main/java/com/baeldung/log4j/NoAppenderExample.java b/logging-modules/log4j/src/main/java/com/baeldung/log4j/NoAppenderExample.java new file mode 100644 index 0000000000..9bd8a06537 --- /dev/null +++ b/logging-modules/log4j/src/main/java/com/baeldung/log4j/NoAppenderExample.java @@ -0,0 +1,18 @@ +package com.baeldung.log4j; + +import org.apache.log4j.Logger; + +public class NoAppenderExample { + + private final static Logger logger = Logger.getLogger(NoAppenderExample.class); + + public static void main(String[] args) { + + //Setup default appender + //BasicConfigurator.configure(); + + //Define path to configuration file + //PropertyConfigurator.configure("src\\main\\resources\\log4j.properties"); + logger.info("Info log message"); + } +} diff --git a/logging-modules/log4j/src/main/resources/log4j.properties b/logging-modules/log4j/src/main/resources/log4j.properties new file mode 100644 index 0000000000..b10ba2b7d4 --- /dev/null +++ b/logging-modules/log4j/src/main/resources/log4j.properties @@ -0,0 +1,5 @@ +log4j.rootLogger=INFO, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n \ No newline at end of file diff --git a/logging-modules/log4j/src/main/resources/log4j.xml b/logging-modules/log4j/src/main/resources/log4j.xml index 562d6920f9..3004649edf 100644 --- a/logging-modules/log4j/src/main/resources/log4j.xml +++ b/logging-modules/log4j/src/main/resources/log4j.xml @@ -90,6 +90,8 @@ + + diff --git a/mapstruct/pom.xml b/mapstruct/pom.xml index 1434db0d54..1e7ce6cbfc 100644 --- a/mapstruct/pom.xml +++ b/mapstruct/pom.xml @@ -34,7 +34,12 @@ org.projectlombok lombok - ${org.projectlombok.version} + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + ${lombok.mapstruct.binding.version} org.assertj @@ -63,7 +68,12 @@ org.projectlombok lombok - ${org.projectlombok.version} + ${lombok.version} + + + org.projectlombok + lombok-mapstruct-binding + ${lombok.mapstruct.binding.version} @@ -72,11 +82,11 @@ - 1.3.1.Final + 1.4.2.Final 4.3.4.RELEASE 1.8 1.8 - 1.18.4 + 0.2.0 3.16.1 diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/DBConfig.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/DBConfig.java new file mode 100644 index 0000000000..3907434239 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/DBConfig.java @@ -0,0 +1,26 @@ +package com.baeldung.insertnull; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +public class DBConfig { + + private static Connection INSTANCE; + + public static Connection getConnection() throws SQLException { + if (INSTANCE == null) { + INSTANCE = DriverManager.getConnection("jdbc:h2:mem:insertnull", "user", "password"); + createPersonTable(); + } + return INSTANCE; + } + + private static void createPersonTable() throws SQLException { + try(Statement statement = INSTANCE.createStatement()) { + String sql = "CREATE TABLE Person (id INTEGER not null, name VARCHAR(50), lastName VARCHAR(50), age INTEGER, PRIMARY KEY (id))"; + statement.executeUpdate(sql); + } + } +} diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/Person.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/Person.java new file mode 100644 index 0000000000..e261a7d74c --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/insertnull/Person.java @@ -0,0 +1,48 @@ +package com.baeldung.insertnull; + +public class Person { + + private Integer id; + private String name; + private String lastName; + private Integer age; + + public Person(Integer id, String name, String lastName, Integer age) { + this.id = id; + this.name = name; + this.lastName = lastName; + this.age = age; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/insertnull/InsertNullUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/insertnull/InsertNullUnitTest.java new file mode 100644 index 0000000000..508fa98e8f --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/insertnull/InsertNullUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.insertnull; + +import org.junit.jupiter.api.Test; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +public class InsertNullUnitTest { + + private final String SQL = "INSERT INTO Person VALUES(?,?,?,?)"; + + @Test + public void givenNewPerson_whenSetNullIsUsed_thenNewRecordIsCreated() throws SQLException { + Person person = new Person(1, "John", "Doe", null); + + try (PreparedStatement preparedStatement = DBConfig.getConnection().prepareStatement(SQL)) { + preparedStatement.setInt(1, person.getId()); + preparedStatement.setString(2, person.getName()); + preparedStatement.setString(3, person.getLastName()); + if (person.getAge() == null) { + preparedStatement.setNull(4, Types.INTEGER); + } + else { + preparedStatement.setInt(4, person.getAge()); + } + int noOfRows = preparedStatement.executeUpdate(); + + assertThat(noOfRows, equalTo(1)); + } + } + + @Test + public void givenNewPerson_whenSetObjectIsUsed_thenNewRecordIsCreated() throws SQLException { + Person person = new Person(2, "John", "Doe", null); + + try (PreparedStatement preparedStatement = DBConfig.getConnection().prepareStatement(SQL)) { + preparedStatement.setInt(1, person.getId()); + preparedStatement.setString(2, person.getName()); + preparedStatement.setString(3, person.getLastName()); + preparedStatement.setObject(4, person.getAge(), Types.INTEGER); + int noOfRows = preparedStatement.executeUpdate(); + + assertThat(noOfRows, equalTo(1)); + } + } +} diff --git a/persistence-modules/java-jpa-3/README.md b/persistence-modules/java-jpa-3/README.md index e607043880..c024d7c540 100644 --- a/persistence-modules/java-jpa-3/README.md +++ b/persistence-modules/java-jpa-3/README.md @@ -11,3 +11,5 @@ This module contains articles about the Java Persistence API (JPA) in Java. - [A Guide to MultipleBagFetchException in Hibernate](https://www.baeldung.com/java-hibernate-multiplebagfetchexception) - [How to Convert a Hibernate Proxy to a Real Entity Object](https://www.baeldung.com/hibernate-proxy-to-real-entity-object) - [Returning an Auto-Generated Id with JPA](https://www.baeldung.com/jpa-get-auto-generated-id) +- [How to Return Multiple Entities In JPA Query](https://www.baeldung.com/jpa-return-multiple-entities) +- [Defining Unique Constraints in JPA](https://www.baeldung.com/jpa-unique-constraints) diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java new file mode 100644 index 0000000000..b20de6a471 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Address.java @@ -0,0 +1,37 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table +public class Address implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private String streetAddress; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getStreetAddress() { + return streetAddress; + } + + public void setStreetAddress(String streetAddress) { + this.streetAddress = streetAddress; + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java new file mode 100644 index 0000000000..c5df90df73 --- /dev/null +++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/uniqueconstraints/Person.java @@ -0,0 +1,116 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +@Entity +@Table(uniqueConstraints = { @UniqueConstraint(name = "UniqueNumberAndStatus", columnNames = { "personNumber", "isActive" }), + @UniqueConstraint(name = "UniqueSecurityAndDepartment", columnNames = { "securityNumber", "departmentCode" }), + @UniqueConstraint(name = "UniqueNumberAndAddress", columnNames = { "personNumber", "address" }) }) +public class Person implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue + private Long id; + + private String name; + + private String password; + + @Column(unique = true) + private String email; + + @Column(unique = true) + private Long personNumber; + + private Boolean isActive; + + private String securityNumber; + + private String departmentCode; + + @Column(unique = true) + @JoinColumn(name = "addressId", referencedColumnName = "id") + private Address address; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Long getPersonNumber() { + return personNumber; + } + + public void setPersonNumber(Long personNumber) { + this.personNumber = personNumber; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public String getScode() { + return securityNumber; + } + + public void setScode(String scode) { + this.securityNumber = scode; + } + + public String getDcode() { + return departmentCode; + } + + public void setDcode(String dcode) { + this.departmentCode = dcode; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml index 666fc1500a..1166aaca71 100644 --- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml @@ -113,6 +113,22 @@ + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.uniqueconstraints.Person + com.baeldung.jpa.uniqueconstraints.Address + true + + + + + + + + + + + org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.returnmultipleentities.Channel diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java new file mode 100644 index 0000000000..ca776ba00b --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueColumnIntegrationTest.java @@ -0,0 +1,119 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.util.Optional; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.hibernate.exception.ConstraintViolationException; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class UniqueColumnIntegrationTest { + + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeAll + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-unique-constraints"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenPersistPersonWithSameNumber_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(2000L); + person1.setEmail("john.beth@gmail.com"); + + Person person2 = new Person(); + person2.setPersonNumber(2000L); + person2.setEmail("anthony.green@gmail.com"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameEmail_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(4000L); + person1.setEmail("timm.beth@gmail.com"); + + Person person2 = new Person(); + person2.setPersonNumber(3000L); + person2.setEmail("timm.beth@gmail.com"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameAddress_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(5000L); + person1.setEmail("chris.beck@gmail.com"); + + Address address1 = new Address(); + address1.setStreetAddress("20 Street"); + person1.setAddress(address1); + + Person person2 = new Person(); + person2.setPersonNumber(6000L); + person2.setEmail("mark.jonson@gmail.com"); + person2.setAddress(address1); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } +} \ No newline at end of file diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java new file mode 100644 index 0000000000..f12313724e --- /dev/null +++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/uniqueconstraints/UniqueConstraintIntegrationTest.java @@ -0,0 +1,116 @@ +package com.baeldung.jpa.uniqueconstraints; + +import java.util.Optional; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.hibernate.exception.ConstraintViolationException; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class UniqueConstraintIntegrationTest { + private static EntityManagerFactory factory; + private static EntityManager entityManager; + + @BeforeAll + public static void setup() { + factory = Persistence.createEntityManagerFactory("jpa-unique-constraints"); + entityManager = factory.createEntityManager(); + } + + @Test + public void whenPersistPersonWithSameNumberAndStatus_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setPersonNumber(12345L); + person1.setIsActive(Boolean.TRUE); + + Person person2 = new Person(); + person2.setPersonNumber(12345L); + person2.setIsActive(Boolean.TRUE); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameSCodeAndDecode_thenConstraintViolationException() { + Person person1 = new Person(); + person1.setDcode("Sec1"); + person1.setScode("Axybg356"); + + Person person2 = new Person(); + person2.setDcode("Sec1"); + person2.setScode("Axybg356"); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } + + @Test + public void whenPersistPersonWithSameNumberAndAddress_thenConstraintViolationException() { + Address address1 = new Address(); + address1.setStreetAddress("40 Street"); + + Person person1 = new Person(); + person1.setPersonNumber(54321L); + person1.setAddress(address1); + + Person person2 = new Person(); + person2.setPersonNumber(99999L); + person2.setAddress(address1); + + entityManager.getTransaction().begin(); + entityManager.persist(person1); + entityManager.getTransaction().commit(); + + entityManager.getTransaction().begin(); + try { + entityManager.persist(person2); + entityManager.getTransaction().commit(); + Assert.fail("Should raise an exception - unique key violation"); + } catch (Exception ex) { + Assert.assertTrue(Optional.of(ex) + .map(Throwable::getCause) + .map(Throwable::getCause) + .filter(x -> x instanceof ConstraintViolationException) + .isPresent()); + } finally { + entityManager.getTransaction().rollback(); + } + } +} \ No newline at end of file diff --git a/reactor-core/README.md b/reactor-core/README.md index 08dac354ab..21ccc1ed92 100644 --- a/reactor-core/README.md +++ b/reactor-core/README.md @@ -9,3 +9,4 @@ This module contains articles about Reactor Core. - [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor) - [How to Extract a Mono’s Content in Java](https://www.baeldung.com/java-string-from-mono) - [How to Convert Mono> Into Flux](https://www.baeldung.com/java-mono-list-to-flux) +- [Project Reactor: map() vs flatMap()](https://www.baeldung.com/java-reactor-map-flatmap) diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index 53af0de315..7a93cabb82 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -73,6 +73,7 @@ spring-boot-actuator spring-boot-data-2 spring-boot-react + spring-boot-validation diff --git a/spring-boot-modules/spring-boot-exceptions/README.md b/spring-boot-modules/spring-boot-exceptions/README.md index 33ae193fb8..97a51203c7 100644 --- a/spring-boot-modules/spring-boot-exceptions/README.md +++ b/spring-boot-modules/spring-boot-exceptions/README.md @@ -5,3 +5,4 @@ This module contains articles about Spring Boot Exceptions ### Relevant Articles: - [The BeanDefinitionOverrideException in Spring Boot](https://www.baeldung.com/spring-boot-bean-definition-override-exception) +- [Spring Boot Error ApplicationContextException](https://www.baeldung.com/spring-boot-application-context-exception) diff --git a/spring-boot-modules/spring-boot-exceptions/pom.xml b/spring-boot-modules/spring-boot-exceptions/pom.xml index c0c335f55c..9866c418be 100644 --- a/spring-boot-modules/spring-boot-exceptions/pom.xml +++ b/spring-boot-modules/spring-boot-exceptions/pom.xml @@ -15,6 +15,14 @@ ../ + + + + org.springframework.boot + spring-boot-starter-web + + + spring-boot-exceptions diff --git a/spring-boot-modules/spring-boot-exceptions/src/test/java/com/baeldung/applicationcontextexception/MainEntryPoint.java b/spring-boot-modules/spring-boot-exceptions/src/test/java/com/baeldung/applicationcontextexception/MainEntryPoint.java new file mode 100644 index 0000000000..c187399636 --- /dev/null +++ b/spring-boot-modules/spring-boot-exceptions/src/test/java/com/baeldung/applicationcontextexception/MainEntryPoint.java @@ -0,0 +1,14 @@ +package com.baeldung.applicationcontextexception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +//Remove this annotation to produce ApplicationContextException error +@SpringBootApplication +public class MainEntryPoint { + + public static void main(String[] args) { + SpringApplication.run(MainEntryPoint.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index 37d57d6556..b80dbfa191 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -76,7 +76,7 @@ - 11.0.2 + 13.0.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 1860818b7b..f4df242f2c 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -147,6 +147,7 @@ 1.2-groovy-2.4 1.6 0.7.2 + 2.5.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-validation/.gitignore b/spring-boot-modules/spring-boot-validation/.gitignore new file mode 100644 index 0000000000..8f5ee06047 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/.gitignore @@ -0,0 +1,63 @@ +# Created by https://www.gitignore.io/api/eclipse + +### Eclipse ### + +.metadata +target/ +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# End of https://www.gitignore.io/api/eclipse \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-validation/README.md b/spring-boot-modules/spring-boot-validation/README.md new file mode 100644 index 0000000000..8c3c8b9305 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/README.md @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Spring Validation in the Service Layer](https://www.baeldung.com/spring-service-layer-validation) diff --git a/spring-boot-modules/spring-boot-validation/pom.xml b/spring-boot-modules/spring-boot-validation/pom.xml new file mode 100644 index 0000000000..1aba8efeac --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/pom.xml @@ -0,0 +1,41 @@ + + + + 4.0.0 + + com.baeldung + spring-boot-validation + 0.0.1-SNAPSHOT + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.hibernate.validator + hibernate-validator + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/SpringServiceLayerValidationApp.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/SpringServiceLayerValidationApp.java new file mode 100644 index 0000000000..b976342dda --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/SpringServiceLayerValidationApp.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.servicevalidation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringServiceLayerValidationApp { + + public static void main(String[] args) { + SpringApplication.run(SpringServiceLayerValidationApp.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/controller/UserAccountController.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/controller/UserAccountController.java new file mode 100644 index 0000000000..33d9966e42 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/controller/UserAccountController.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.servicevalidation.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.spring.servicevalidation.domain.UserAccount; +import com.baeldung.spring.servicevalidation.service.UserAccountService; + +@RestController +public class UserAccountController { + + @Autowired + private UserAccountService service; + + @PostMapping("/addUserAccount") + public Object addUserAccount(@RequestBody UserAccount userAccount) { + return service.addUserAccount(userAccount); + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java new file mode 100644 index 0000000000..c49c5220f4 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/dao/UserAccountDao.java @@ -0,0 +1,31 @@ +package com.baeldung.spring.servicevalidation.dao; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.stereotype.Service; + +import com.baeldung.spring.servicevalidation.domain.UserAccount; + +@Service +public class UserAccountDao { + + private Map DB = new HashMap(); + + public String addUserAccount(UserAccount useraccount) { + DB.put(useraccount.getName(), useraccount); + return "success"; + } + + public Collection getAllUserAccounts() { + + Collection list = DB.values(); + if (list.isEmpty()) { + list.addAll(DB.values()); + } + return list; + + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java new file mode 100644 index 0000000000..5b0e795a8a --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAccount.java @@ -0,0 +1,77 @@ +package com.baeldung.spring.servicevalidation.domain; + +import javax.validation.Valid; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +public class UserAccount { + + @NotNull(message = "Password must be between 4 to 15 characters") + @Size(min = 4, max = 15) + private String password; + + @NotBlank(message = "Name must not be blank") + private String name; + + @Min(value = 18, message = "Age should not be less than 18") + private int age; + + @NotBlank(message = "Phone must not be blank") + private String phone; + + @Valid + @NotNull(message = "UserAddress must not be blank") + private UserAddress useraddress; + + public UserAddress getUseraddress() { + return useraddress; + } + + public void setUseraddress(UserAddress useraddress) { + this.useraddress = useraddress; + } + + public UserAccount() { + + } + + public UserAccount(String email, String password, String name, int age) { + this.password = password; + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java new file mode 100644 index 0000000000..cd149dc5f5 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/domain/UserAddress.java @@ -0,0 +1,18 @@ +package com.baeldung.spring.servicevalidation.domain; + +import javax.validation.constraints.NotBlank; + +public class UserAddress { + + @NotBlank + private String countryCode; + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java new file mode 100644 index 0000000000..417e9a32b7 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/main/java/com/baeldung/spring/servicevalidation/service/UserAccountService.java @@ -0,0 +1,42 @@ +package com.baeldung.spring.servicevalidation.service; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.spring.servicevalidation.dao.UserAccountDao; +import com.baeldung.spring.servicevalidation.domain.UserAccount; + +@Service +public class UserAccountService { + + @Autowired + private Validator validator; + + @Autowired + private UserAccountDao dao; + + public String addUserAccount(UserAccount useraccount) { + + Set> violations = validator.validate(useraccount); + + if (!violations.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (ConstraintViolation constraintViolation : violations) { + sb.append(constraintViolation.getMessage()); + } + + dao.addUserAccount(useraccount); + + throw new ConstraintViolationException("Error occurred: " + sb.toString(), violations); + } + + return "Account for " + useraccount.getName() + " Added!"; + } + +} diff --git a/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..f4076a7756 --- /dev/null +++ b/spring-boot-modules/spring-boot-validation/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,14 @@ +package com.baeldung; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import com.baeldung.spring.servicevalidation.SpringServiceLayerValidationApp; + +@SpringBootTest(classes = SpringServiceLayerValidationApp.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md index bcfd769d0c..5d3dc060c7 100644 --- a/spring-cloud/spring-cloud-openfeign/README.md +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -3,3 +3,4 @@ - [Introduction to Spring Cloud OpenFeign](https://www.baeldung.com/spring-cloud-openfeign) - [Differences Between Netflix Feign and OpenFeign](https://www.baeldung.com/netflix-feign-vs-openfeign) - [File Upload With Open Feign](https://www.baeldung.com/java-feign-file-upload) +- [Feign Logging Configuration](https://www.baeldung.com/java-feign-logging) diff --git a/testing-modules/testing-libraries-2/README.md b/testing-modules/testing-libraries-2/README.md index 868d8f307d..7cc08a8140 100644 --- a/testing-modules/testing-libraries-2/README.md +++ b/testing-modules/testing-libraries-2/README.md @@ -3,3 +3,4 @@ - [Guide to the System Rules Library](https://www.baeldung.com/java-system-rules-junit) - [Guide to the System Stubs Library](https://www.baeldung.com/java-system-stubs) - [Code Coverage with SonarQube and JaCoCo](https://www.baeldung.com/sonarqube-jacoco-code-coverage) +- [Exclusions from Jacoco Report](https://www.baeldung.com/jacoco-report-exclude) diff --git a/testing-modules/testing-libraries-2/lombok.config b/testing-modules/testing-libraries-2/lombok.config new file mode 100644 index 0000000000..7a21e88040 --- /dev/null +++ b/testing-modules/testing-libraries-2/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index 5a57dc0958..d914fcfb86 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -13,6 +13,12 @@ + + org.projectlombok + lombok + ${lombok.version} + provided + org.assertj assertj-core @@ -85,6 +91,13 @@ org.jacoco jacoco-maven-plugin ${jacoco.version} + + + com/baeldung/**/ExcludedPOJO.class + com/baeldung/**/*DTO.* + **/config/* + + jacoco-initialize diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/config/AppConfig.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/config/AppConfig.java new file mode 100644 index 0000000000..26bfe7b196 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/config/AppConfig.java @@ -0,0 +1,11 @@ +package com.baeldung.jacocoexclusions.config; + +import com.baeldung.jacocoexclusions.service.ProductService; + +public class AppConfig { + + public ProductService productService() { + return new ProductService(); + } + +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/domain/Product.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/domain/Product.java new file mode 100644 index 0000000000..5606107371 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/domain/Product.java @@ -0,0 +1,12 @@ +package com.baeldung.jacocoexclusions.domain; + +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class Product { + private int id; + private String name; + +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ExcludedPOJO.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ExcludedPOJO.java new file mode 100644 index 0000000000..27b461f70e --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ExcludedPOJO.java @@ -0,0 +1,4 @@ +package com.baeldung.jacocoexclusions.dto; + +public class ExcludedPOJO { +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ProductDTO.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ProductDTO.java new file mode 100644 index 0000000000..fb0ec05621 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/dto/ProductDTO.java @@ -0,0 +1,4 @@ +package com.baeldung.jacocoexclusions.dto; + +public class ProductDTO { +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Customer.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Customer.java new file mode 100644 index 0000000000..cab70467e3 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Customer.java @@ -0,0 +1,11 @@ +package com.baeldung.jacocoexclusions.generated; + +@Generated +public class Customer { + // everything in this class will be excluded from jacoco report because of @Generated + + @Override + public String toString() { + return "Customer{}"; + } +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Generated.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Generated.java new file mode 100644 index 0000000000..93be21e32d --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/generated/Generated.java @@ -0,0 +1,15 @@ +package com.baeldung.jacocoexclusions.generated; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Documented +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +public @interface Generated { +} \ No newline at end of file diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/CustomerService.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/CustomerService.java new file mode 100644 index 0000000000..889153ba0a --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/CustomerService.java @@ -0,0 +1,16 @@ +package com.baeldung.jacocoexclusions.service; + +import com.baeldung.jacocoexclusions.generated.Generated; + +public class CustomerService { + + //this method will be excluded from coverage due to @Generated. + @Generated + public String getProductId() { + return "An ID"; + } + + public String getCustomerName() { + return "some name"; + } +} diff --git a/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/ProductService.java b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/ProductService.java new file mode 100644 index 0000000000..c87295e642 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/main/java/com/baeldung/jacocoexclusions/service/ProductService.java @@ -0,0 +1,9 @@ +package com.baeldung.jacocoexclusions.service; + +public class ProductService { + private static final double DISCOUNT = 0.25; + + public double getSalePrice(double originalPrice) { + return originalPrice - originalPrice * DISCOUNT; + } +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/CustomerServiceUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/CustomerServiceUnitTest.java new file mode 100644 index 0000000000..b35f92ca20 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/CustomerServiceUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.jacocoexclusions.service; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class CustomerServiceUnitTest { + + @Test + public void givenCustomer_whenGetCustomer_thenReturnNewCustomer() { + CustomerService customerService = new CustomerService(); + assertNotNull(customerService.getCustomerName()); + } +} diff --git a/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/ProductServiceUnitTest.java b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/ProductServiceUnitTest.java new file mode 100644 index 0000000000..609be33640 --- /dev/null +++ b/testing-modules/testing-libraries-2/src/test/java/com/baeldung/jacocoexclusions/service/ProductServiceUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.jacocoexclusions.service; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ProductServiceUnitTest { + + @Test + public void givenOriginalPrice_whenGetSalePrice_thenReturnsDiscountedPrice() { + ProductService productService = new ProductService(); + double salePrice = productService.getSalePrice(100); + assertEquals(salePrice, 75); + } +}