diff --git a/JGit/pom.xml b/JGit/pom.xml
new file mode 100644
index 0000000000..93c49edb92
--- /dev/null
+++ b/JGit/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+ com.baeldung
+ JGitSnippets
+ 1.0-SNAPSHOT
+ jar
+ http://maven.apache.org
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+ jgit-repository
+ https://repo.eclipse.org/content/groups/releases/
+
+
+
+
+
+
+ org.eclipse.jgit
+ org.eclipse.jgit
+ 4.5.0.201609210915-r
+
+
+ org.eclipse.jgit
+ org.eclipse.jgit.archive
+ 4.5.0.201609210915-r
+
+
+ commons-io
+ commons-io
+ 2.5
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.21
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.2
+
+ 1.7
+ 1.7
+
+
+
+
+
\ No newline at end of file
diff --git a/JGit/src/main/java/com/baeldung/jgit/CreateNewRepository.java b/JGit/src/main/java/com/baeldung/jgit/CreateNewRepository.java
new file mode 100644
index 0000000000..1702efc315
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/CreateNewRepository.java
@@ -0,0 +1,30 @@
+package com.baeldung.jgit;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+
+/**
+ * Simple snippet which shows how to create a new repository
+ *
+ *
+ */
+public class CreateNewRepository {
+
+ public static void main(String[] args) throws IOException, IllegalStateException, GitAPIException {
+ // prepare a new folder
+ File localPath = File.createTempFile("TestGitRepository", "");
+ if(!localPath.delete()) {
+ throw new IOException("Could not delete temporary file " + localPath);
+ }
+
+ // create the directory
+ try (Git git = Git.init().setDirectory(localPath).call()) {
+ System.out.println("Having repository: " + git.getRepository().getDirectory());
+ }
+
+ FileUtils.deleteDirectory(localPath);
+ }
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/OpenRepository.java b/JGit/src/main/java/com/baeldung/jgit/OpenRepository.java
new file mode 100644
index 0000000000..671df2a844
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/OpenRepository.java
@@ -0,0 +1,65 @@
+package com.baeldung.jgit;
+
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Simple snippet which shows how to open an existing repository
+ *
+ *
+ */
+public class OpenRepository {
+
+ public static void main(String[] args) throws IOException, GitAPIException {
+ // first create a test-repository, the return is including the .get directory here!
+ File repoDir = createSampleGitRepo();
+
+ // now open the resulting repository with a FileRepositoryBuilder
+ FileRepositoryBuilder builder = new FileRepositoryBuilder();
+ try (Repository repository = builder.setGitDir(repoDir)
+ .readEnvironment() // scan environment GIT_* variables
+ .findGitDir() // scan up the file system tree
+ .build()) {
+ System.out.println("Having repository: " + repository.getDirectory());
+
+ // the Ref holds an ObjectId for any type of object (tree, commit, blob, tree)
+ Ref head = repository.exactRef("refs/heads/master");
+ System.out.println("Ref of refs/heads/master: " + head);
+ }
+ }
+
+ private static File createSampleGitRepo() throws IOException, GitAPIException {
+ try (Repository repository = Helper.createNewRepository()) {
+ System.out.println("Temporary repository at " + repository.getDirectory());
+
+ // create the file
+ File myfile = new File(repository.getDirectory().getParent(), "testfile");
+ if(!myfile.createNewFile()) {
+ throw new IOException("Could not create file " + myfile);
+ }
+
+ // run the add-call
+ try (Git git = new Git(repository)) {
+ git.add()
+ .addFilepattern("testfile")
+ .call();
+
+
+ // and then commit the changes
+ git.commit()
+ .setMessage("Added testfile")
+ .call();
+ }
+
+ System.out.println("Added file " + myfile + " to repository at " + repository.getDirectory());
+
+ return repository.getDirectory();
+ }
+ }
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/helper/Helper.java b/JGit/src/main/java/com/baeldung/jgit/helper/Helper.java
new file mode 100644
index 0000000000..39d7b767d2
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/helper/Helper.java
@@ -0,0 +1,33 @@
+
+package com.baeldung.jgit.helper;
+
+import java.io.File;
+import java.io.IOException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+
+public class Helper {
+
+ public static Repository openJGitRepository() throws IOException {
+ FileRepositoryBuilder builder = new FileRepositoryBuilder();
+ return builder
+ .readEnvironment() // scan environment GIT_* variables
+ .findGitDir() // scan up the file system tree
+ .build();
+ }
+
+ public static Repository createNewRepository() throws IOException {
+ // prepare a new folder
+ File localPath = File.createTempFile("TestGitRepository", "");
+ if(!localPath.delete()) {
+ throw new IOException("Could not delete temporary file " + localPath);
+ }
+
+ // create the directory
+ Repository repository = FileRepositoryBuilder.create(new File(localPath, ".git"));
+ repository.create();
+
+ return repository;
+ }
+
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java b/JGit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java
new file mode 100644
index 0000000000..314366f08c
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java
@@ -0,0 +1,36 @@
+package com.baeldung.jgit.porcelain;
+
+import java.io.File;
+import java.io.IOException;
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Simple snippet which shows how to add a file to the index
+ *
+ *
+ */
+public class AddFile {
+
+ public static void main(String[] args) throws IOException, GitAPIException {
+ // prepare a new test-repository
+ try (Repository repository = Helper.createNewRepository()) {
+ try (Git git = new Git(repository)) {
+ // create the file
+ File myfile = new File(repository.getDirectory().getParent(), "testfile");
+ if(!myfile.createNewFile()) {
+ throw new IOException("Could not create file " + myfile);
+ }
+
+ // run the add-call
+ git.add()
+ .addFilepattern("testfile")
+ .call();
+
+ System.out.println("Added file " + myfile + " to repository at " + repository.getDirectory());
+ }
+ }
+ }
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java b/JGit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java
new file mode 100644
index 0000000000..4c0956ebf8
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java
@@ -0,0 +1,51 @@
+package com.baeldung.jgit.porcelain;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Simple snippet which shows how to commit all files
+ *
+ *
+ */
+public class CommitAll {
+
+ public static void main(String[] args) throws IOException, GitAPIException {
+ // prepare a new test-repository
+ try (Repository repository = Helper.createNewRepository()) {
+ try (Git git = new Git(repository)) {
+ // create the file
+ File myfile = new File(repository.getDirectory().getParent(), "testfile");
+ if(!myfile.createNewFile()) {
+ throw new IOException("Could not create file " + myfile);
+ }
+
+ // Stage all files in the repo including new files
+ git.add().addFilepattern(".").call();
+
+ // and then commit the changes.
+ git.commit()
+ .setMessage("Commit all changes including additions")
+ .call();
+
+ try(PrintWriter writer = new PrintWriter(myfile)) {
+ writer.append("Hello, world!");
+ }
+
+ // Stage all changed files, omitting new files, and commit with one command
+ git.commit()
+ .setAll(true)
+ .setMessage("Commit changes to all files")
+ .call();
+
+
+ System.out.println("Committed all changes to repository at " + repository.getDirectory());
+ }
+ }
+ }
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java b/JGit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java
new file mode 100644
index 0000000000..0f735daf8c
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java
@@ -0,0 +1,56 @@
+package com.baeldung.jgit.porcelain;
+
+import java.io.IOException;
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+
+/**
+ * Simple snippet which shows how to create a tag
+ *
+ *
+ */
+public class CreateAndDeleteTag {
+
+ public static void main(String[] args) throws IOException, GitAPIException {
+ // prepare test-repository
+ try (Repository repository = Helper.openJGitRepository()) {
+ try (Git git = new Git(repository)) {
+ // remove the tag before creating it
+ git.tagDelete().setTags("tag_for_testing").call();
+
+ // set it on the current HEAD
+ Ref tag = git.tag().setName("tag_for_testing").call();
+ System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory());
+
+ // remove the tag again
+ git.tagDelete().setTags("tag_for_testing").call();
+
+ // read some other commit and set the tag on it
+ ObjectId id = repository.resolve("HEAD^");
+ try (RevWalk walk = new RevWalk(repository)) {
+ RevCommit commit = walk.parseCommit(id);
+ tag = git.tag().setObjectId(commit).setName("tag_for_testing").call();
+ System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory());
+
+ // remove the tag again
+ git.tagDelete().setTags("tag_for_testing").call();
+
+ // create an annotated tag
+ tag = git.tag().setName("tag_for_testing").setAnnotated(true).call();
+ System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory());
+
+ // remove the tag again
+ git.tagDelete().setTags("tag_for_testing").call();
+
+ walk.dispose();
+ }
+ }
+ }
+ }
+}
diff --git a/JGit/src/main/java/com/baeldung/jgit/porcelain/Log.java b/JGit/src/main/java/com/baeldung/jgit/porcelain/Log.java
new file mode 100644
index 0000000000..cb476b9d9e
--- /dev/null
+++ b/JGit/src/main/java/com/baeldung/jgit/porcelain/Log.java
@@ -0,0 +1,74 @@
+package com.baeldung.jgit.porcelain;
+
+import java.io.IOException;
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+/**
+ * Simple snippet which shows how to get the commit-ids for a file to provide log information.
+ *
+ *
+ */
+public class Log {
+
+ @SuppressWarnings("unused")
+ public static void main(String[] args) throws IOException, GitAPIException {
+ try (Repository repository = Helper.openJGitRepository()) {
+ try (Git git = new Git(repository)) {
+ Iterable logs = git.log()
+ .call();
+ int count = 0;
+ for (RevCommit rev : logs) {
+ //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
+ count++;
+ }
+ System.out.println("Had " + count + " commits overall on current branch");
+
+ logs = git.log()
+ .add(repository.resolve("remotes/origin/testbranch"))
+ .call();
+ count = 0;
+ for (RevCommit rev : logs) {
+ System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
+ count++;
+ }
+ System.out.println("Had " + count + " commits overall on test-branch");
+
+ logs = git.log()
+ .all()
+ .call();
+ count = 0;
+ for (RevCommit rev : logs) {
+ //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
+ count++;
+ }
+ System.out.println("Had " + count + " commits overall in repository");
+
+ logs = git.log()
+ // for all log.all()
+ .addPath("README.md")
+ .call();
+ count = 0;
+ for (RevCommit rev : logs) {
+ //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
+ count++;
+ }
+ System.out.println("Had " + count + " commits on README.md");
+
+ logs = git.log()
+ // for all log.all()
+ .addPath("pom.xml")
+ .call();
+ count = 0;
+ for (RevCommit rev : logs) {
+ //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */);
+ count++;
+ }
+ System.out.println("Had " + count + " commits on pom.xml");
+ }
+ }
+ }
+}
diff --git a/JGit/src/test/java/com/baeldung/jgit/JGitBugTest.java b/JGit/src/test/java/com/baeldung/jgit/JGitBugTest.java
new file mode 100644
index 0000000000..acad4e395f
--- /dev/null
+++ b/JGit/src/test/java/com/baeldung/jgit/JGitBugTest.java
@@ -0,0 +1,31 @@
+import com.baeldung.jgit.helper.Helper;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.Test;
+import java.io.IOException;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Tests which show issues with JGit that we reported upstream.
+ */
+public class JGitBugTest {
+ @Test
+ public void testRevWalkDisposeClosesReader() throws IOException {
+ try (Repository repo = Helper.openJGitRepository()) {
+ try (ObjectReader reader = repo.newObjectReader()) {
+ try (RevWalk walk = new RevWalk(reader)) {
+ walk.dispose();
+
+ Ref head = repo.exactRef("refs/heads/master");
+ System.out.println("Found head: " + head);
+
+ ObjectLoader loader = reader.open(head.getObjectId());
+ assertNotNull(loader);
+ }
+ }
+ }
+ }
+}
diff --git a/JGit/src/test/java/com/baeldung/jgit/porcelain/PorcelainTest.java b/JGit/src/test/java/com/baeldung/jgit/porcelain/PorcelainTest.java
new file mode 100644
index 0000000000..ce3a41e657
--- /dev/null
+++ b/JGit/src/test/java/com/baeldung/jgit/porcelain/PorcelainTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.jgit.porcelain;
+
+import org.junit.Test;
+
+public class PorcelainTest {
+ @Test
+ public void runSamples() throws Exception {
+ // simply call all the samples to see any severe problems with the samples
+ AddFile.main(null);
+
+ CommitAll.main(null);
+
+ CreateAndDeleteTag.main(null);
+
+ Log.main(null);
+ }
+}
diff --git a/gradle-tutorial/build.gradle b/gradle/build.gradle
similarity index 100%
rename from gradle-tutorial/build.gradle
rename to gradle/build.gradle
diff --git a/gradle-tutorial/gradle.properties b/gradle/gradle.properties
similarity index 100%
rename from gradle-tutorial/gradle.properties
rename to gradle/gradle.properties
diff --git a/gradle-tutorial/gradle/wrapper/gradle-wrapper.jar b/gradle/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from gradle-tutorial/gradle/wrapper/gradle-wrapper.jar
rename to gradle/gradle/wrapper/gradle-wrapper.jar
diff --git a/gradle-tutorial/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from gradle-tutorial/gradle/wrapper/gradle-wrapper.properties
rename to gradle/gradle/wrapper/gradle-wrapper.properties
diff --git a/gradle-tutorial/gradlew b/gradle/gradlew
similarity index 100%
rename from gradle-tutorial/gradlew
rename to gradle/gradlew
diff --git a/gradle-tutorial/gradlew.bat b/gradle/gradlew.bat
similarity index 100%
rename from gradle-tutorial/gradlew.bat
rename to gradle/gradlew.bat
diff --git a/gradle-tutorial/src/main/java/Main.java b/gradle/src/main/java/Main.java
similarity index 100%
rename from gradle-tutorial/src/main/java/Main.java
rename to gradle/src/main/java/Main.java
diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index e77bf0b284..deb6bd6f6a 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -38,6 +38,11 @@
org.springframework
spring-context
+
+ org.springframework.retry
+ spring-retry
+ ${springretry.version}
+
@@ -166,7 +171,6 @@
ehcache
${ehcache.version}
-
@@ -275,6 +279,7 @@
4.3.4.RELEASE
4.2.0.RELEASE
+ 1.1.5.RELEASE
5.2.5.Final
diff --git a/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java b/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java
new file mode 100644
index 0000000000..63bb2a53f1
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/AppConfig.java
@@ -0,0 +1,34 @@
+package org.baeldung.springretry;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.retry.annotation.EnableRetry;
+import org.springframework.retry.backoff.FixedBackOffPolicy;
+import org.springframework.retry.policy.SimpleRetryPolicy;
+import org.springframework.retry.support.RetryTemplate;
+
+@Configuration
+@ComponentScan(basePackages = "org.baeldung.springretry")
+@EnableRetry
+//Uncomment this two lines if we need XML configuration
+//@EnableAspectJAutoProxy
+//@ImportResource("classpath:/retryadvice.xml")
+public class AppConfig {
+
+ @Bean
+ public RetryTemplate retryTemplate() {
+ RetryTemplate retryTemplate = new RetryTemplate();
+
+ FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
+ fixedBackOffPolicy.setBackOffPeriod(2000l);
+ retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
+
+ SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
+ retryPolicy.setMaxAttempts(2);
+ retryTemplate.setRetryPolicy(retryPolicy);
+
+ retryTemplate.registerListener(new DefaultListenerSupport());
+ return retryTemplate;
+ }
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java b/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java
new file mode 100644
index 0000000000..bc251b4c2f
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/DefaultListenerSupport.java
@@ -0,0 +1,31 @@
+package org.baeldung.springretry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.listener.RetryListenerSupport;
+
+public class DefaultListenerSupport extends RetryListenerSupport {
+
+ private static final Logger logger = LoggerFactory.getLogger(DefaultListenerSupport.class);
+
+ @Override
+ public void close(RetryContext context, RetryCallback callback, Throwable throwable) {
+ logger.info("onClose");
+ super.close(context, callback, throwable);
+ }
+
+ @Override
+ public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
+ logger.info("onError");
+ super.onError(context, callback, throwable);
+ }
+
+ @Override
+ public boolean open(RetryContext context, RetryCallback callback) {
+ logger.info("onOpen");
+ return super.open(context, callback);
+ }
+
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/MyService.java b/spring-all/src/main/java/org/baeldung/springretry/MyService.java
new file mode 100644
index 0000000000..2b8cc16eb3
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/MyService.java
@@ -0,0 +1,21 @@
+package org.baeldung.springretry;
+
+import java.sql.SQLException;
+
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
+
+public interface MyService {
+
+ @Retryable
+ void retryService();
+
+ @Retryable(value = { SQLException.class }, maxAttempts = 2, backoff = @Backoff(delay = 5000))
+ void retryServiceWithRecovery(String sql) throws SQLException;
+
+ @Recover
+ void recover(SQLException e, String sql);
+
+ void templateRetryService();
+}
diff --git a/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java b/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java
new file mode 100644
index 0000000000..1b698f26c9
--- /dev/null
+++ b/spring-all/src/main/java/org/baeldung/springretry/MyServiceImpl.java
@@ -0,0 +1,39 @@
+package org.baeldung.springretry;
+
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+@Service
+public class MyServiceImpl implements MyService {
+
+ private static final Logger logger = LoggerFactory.getLogger(MyServiceImpl.class);
+
+ @Override
+ public void retryService() {
+ logger.info("throw RuntimeException in method retryService()");
+ throw new RuntimeException();
+ }
+
+ @Override
+ public void retryServiceWithRecovery(String sql) throws SQLException {
+ if (StringUtils.isEmpty(sql)) {
+ logger.info("throw SQLException in method retryServiceWithRecovery()");
+ throw new SQLException();
+ }
+ }
+
+ @Override
+ public void recover(SQLException e, String sql) {
+ logger.info("In recover method");
+ }
+
+ @Override
+ public void templateRetryService() {
+ logger.info("throw RuntimeException in method templateRetryService()");
+ throw new RuntimeException();
+ }
+}
diff --git a/spring-all/src/main/resources/retryadvice.xml b/spring-all/src/main/resources/retryadvice.xml
new file mode 100644
index 0000000000..8de7801a58
--- /dev/null
+++ b/spring-all/src/main/resources/retryadvice.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Initial sleep interval value, default 300 ms
+
+
+
+
+ The maximum value of the backoff period in milliseconds.
+
+
+
+
+ The value to increment the exp seed with for each retry attempt.
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
new file mode 100644
index 0000000000..2f3411957e
--- /dev/null
+++ b/spring-all/src/test/java/org/baeldung/springretry/SpringRetryTest.java
@@ -0,0 +1,40 @@
+package org.baeldung.springretry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import java.sql.SQLException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
+public class SpringRetryTest {
+
+ @Autowired
+ private MyService myService;
+
+ @Autowired
+ private RetryTemplate retryTemplate;
+
+ @Test(expected = RuntimeException.class)
+ public void givenRetryService_whenCallWithException_thenRetry() {
+ myService.retryService();
+ }
+
+ @Test
+ public void givenRetryServiceWithRecovery_whenCallWithException_thenRetryRecover() throws SQLException {
+ myService.retryServiceWithRecovery(null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void givenTemplateRetryService_whenCallWithException_thenRetry() {
+ retryTemplate.execute(arg0 -> {
+ myService.templateRetryService();
+ return null;
+ });
+ }
+}