diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml
new file mode 100644
index 0000000000..6d49d74ade
--- /dev/null
+++ b/apache-zookeeper/pom.xml
@@ -0,0 +1,30 @@
+
+ 4.0.0
+ com.baeldung
+ apache-zookeeper
+ 0.0.1-SNAPSHOT
+ jar
+
+
+
+ org.apache.zookeeper
+ zookeeper
+ 3.3.2
+
+
+ com.sun.jmx
+ jmxri
+
+
+ com.sun.jdmk
+ jmxtools
+
+
+ javax.jms
+ jms
+
+
+
+
+
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
new file mode 100644
index 0000000000..0678250d57
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
@@ -0,0 +1,33 @@
+package com.baeldung.zookeeper.connection;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooKeeper;
+
+public class ZKConnection {
+ private ZooKeeper zoo;
+ final CountDownLatch connectionLatch = new CountDownLatch(1);
+
+ public ZKConnection() {
+ }
+
+ public ZooKeeper connect(String host) throws IOException, InterruptedException {
+ zoo = new ZooKeeper(host, 2000, new Watcher() {
+ public void process(WatchedEvent we) {
+ if (we.getState() == KeeperState.SyncConnected) {
+ connectionLatch.countDown();
+ }
+ }
+ });
+ connectionLatch.await();
+ return zoo;
+ }
+
+ public void close() throws InterruptedException {
+ zoo.close();
+ }
+}
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
new file mode 100644
index 0000000000..0c0ad52123
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
@@ -0,0 +1,35 @@
+package com.baeldung.zookeeper.manager;
+
+import org.apache.zookeeper.KeeperException;
+
+public interface ZKManager {
+ /**
+ * Create a Znode and save some data
+ *
+ * @param path
+ * @param data
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public void create(String path, byte[] data) throws KeeperException, InterruptedException;
+
+ /**
+ * Get ZNode Data
+ *
+ * @param path
+ * @param boolean watchFlag
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public Object getZNodeData(String path, boolean watchFlag);
+
+ /**
+ * Update the ZNode Data
+ *
+ * @param path
+ * @param data
+ * @throws KeeperException
+ * @throws InterruptedException
+ */
+ public void update(String path, byte[] data) throws KeeperException, InterruptedException, KeeperException;
+}
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
new file mode 100644
index 0000000000..adf76bc0f2
--- /dev/null
+++ b/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
@@ -0,0 +1,58 @@
+package com.baeldung.zookeeper.manager;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+
+import com.baeldung.zookeeper.connection.ZKConnection;
+
+public class ZKManagerImpl implements ZKManager {
+ private static ZooKeeper zkeeper;
+ private static ZKConnection zkConnection;
+
+ public ZKManagerImpl() {
+ initialize();
+ }
+
+ /** * Initialize connection */
+ private void initialize() {
+ try {
+ zkConnection = new ZKConnection();
+ zkeeper = zkConnection.connect("localhost");
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ public void closeConnection() {
+ try {
+ zkConnection.close();
+ } catch (InterruptedException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+
+ public void create(String path, byte[] data) throws KeeperException, InterruptedException {
+ zkeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ }
+
+ public Object getZNodeData(String path, boolean watchFlag) {
+ try {
+ byte[] b = null;
+ b = zkeeper.getData(path, null, null);
+ String data = new String(b, "UTF-8");
+ System.out.println(data);
+ return data;
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return null;
+ }
+
+ public void update(String path, byte[] data) throws KeeperException, InterruptedException {
+ int version = zkeeper.exists(path, true)
+ .getVersion();
+ zkeeper.setData(path, data, version);
+ }
+}
diff --git a/core-groovy/build.gradle b/core-groovy/build.gradle
new file mode 100644
index 0000000000..b3f33836da
--- /dev/null
+++ b/core-groovy/build.gradle
@@ -0,0 +1,13 @@
+group 'com.baeldung'
+version '1.0-SNAPSHOT'
+
+apply plugin: 'groovy'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'org.codehaus.groovy:groovy-all:2.5.0-alpha-1'
+ testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
+}
diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml
index 965670e78e..961a4ba125 100644
--- a/core-groovy/pom.xml
+++ b/core-groovy/pom.xml
@@ -1,6 +1,5 @@
-
+
4.0.0
core-groovy
@@ -24,12 +23,17 @@
org.codehaus.groovy
groovy
- 2.4.13
+ 2.5.0-alpha-1
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.5.0-alpha-1
org.codehaus.groovy
groovy-sql
- 2.4.13
+ 2.5.0-alpha-1
org.junit.jupiter
@@ -49,6 +53,12 @@
2.4.0
test
+
+ org.spockframework
+ spock-core
+ 1.1-groovy-2.4
+ test
+
@@ -114,5 +124,5 @@
4.12.0
4.12
-
+
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
new file mode 100644
index 0000000000..84b294f0bd
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/json/Account.groovy
@@ -0,0 +1,7 @@
+package com.baeldung.json
+
+class Account {
+ String id
+ BigDecimal value
+ Date createdAt
+}
\ No newline at end of file
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
new file mode 100644
index 0000000000..0d7c451972
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
@@ -0,0 +1,36 @@
+package com.baeldung.json
+
+import groovy.json.JsonGenerator
+import groovy.json.JsonOutput
+import groovy.json.JsonParserType
+import groovy.json.JsonSlurper
+
+class JsonParser {
+
+ Account toObject(String json) {
+ JsonSlurper jsonSlurper = new JsonSlurper()
+ jsonSlurper.parseText(json) as Account
+ }
+
+ Account toObjectWithIndexOverlay(String json) {
+ JsonSlurper jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY)
+ jsonSlurper.parseText(json) as Account
+ }
+
+ String toJson(Account account) {
+ JsonOutput.toJson(account)
+ }
+
+ String toJson(Account account, String dateFormat, String... fieldsToExclude) {
+ JsonGenerator generator = new JsonGenerator.Options()
+ .dateFormat(dateFormat)
+ .excludeFieldsByName(fieldsToExclude)
+ .build()
+ generator.toJson(account)
+ }
+
+ String prettyfy(String json) {
+ JsonOutput.prettyPrint(json)
+ }
+
+}
diff --git a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
new file mode 100644
index 0000000000..fcd51d58bc
--- /dev/null
+++ b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
@@ -0,0 +1,80 @@
+package com.baeldung.json
+
+import spock.lang.Specification
+
+import java.text.SimpleDateFormat
+
+class JsonParserTest extends Specification {
+
+ JsonParser jsonParser
+
+ void setup () {
+ jsonParser = new JsonParser()
+ }
+
+ def 'Should parse to Account given Json String' () {
+ given:
+ def json = '{"id":"1234","value":15.6}'
+ when:
+ def account = jsonParser.toObject(json)
+ then:
+ account
+ account instanceof Account
+ account.id == '1234'
+ account.value == 15.6
+ }
+
+ def 'Should parse to Account given Json String with date property' () {
+ given:
+ def json = '{"id":"1234","value":15.6,"createdAt":"2018-01-01T00:00:00+0000"}'
+ when:
+ def account = jsonParser.toObjectWithIndexOverlay(json)
+ then:
+ account
+ account instanceof Account
+ account.id == '1234'
+ account.value == 15.6
+ println account.createdAt
+ account.createdAt == Date.parse('yyyy-MM-dd', '2018-01-01')
+ }
+
+ def 'Should parse to Json given an Account object' () {
+ given:
+ Account account = new Account(
+ id: '123',
+ value: 15.6,
+ createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
+ )
+ when:
+ def json = jsonParser.toJson(account)
+ then:
+ json
+ json == '{"value":15.6,"createdAt":"2018-01-01T00:00:00+0000","id":"123"}'
+ }
+
+ def 'Should parse to Json given an Account object, a date format and fields to exclude' () {
+ given:
+ Account account = new Account(
+ id: '123',
+ value: 15.6,
+ createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
+ )
+ when:
+ def json = jsonParser.toJson(account, 'MM/dd/yyyy', 'value')
+ then:
+ json
+ json == '{"createdAt":"01/01/2018","id":"123"}'
+ }
+
+ def 'Should prettify given a json string' () {
+ given:
+ String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}'
+ when:
+ def jsonPretty = jsonParser.prettyfy(json)
+ then:
+ jsonPretty
+ jsonPretty == '{\n "value": 15.6,\n "createdAt": "01/01/2018",\n "id": "123456"\n}'
+ }
+
+
+}
diff --git a/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java
new file mode 100644
index 0000000000..479f62cb4e
--- /dev/null
+++ b/core-java-9/src/main/java/com/baeldung/java9/methodhandles/Book.java
@@ -0,0 +1,17 @@
+package com.baeldung.java9.methodhandles;
+
+public class Book {
+
+ String id;
+ String title;
+
+ public Book(String id, String title) {
+ this.id = id;
+ this.title = title;
+ }
+
+ @SuppressWarnings("unused")
+ private String formatBook() {
+ return id + " > " + title;
+ }
+}
diff --git a/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java
new file mode 100644
index 0000000000..7646755358
--- /dev/null
+++ b/core-java-9/src/test/java/com/baeldung/java9/methodhandles/MethodHandlesTest.java
@@ -0,0 +1,152 @@
+package com.baeldung.java9.methodhandles;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Test case for the {@link MethodHandles} API
+ */
+public class MethodHandlesTest {
+
+ @Test
+ public void givenConcatMethodHandle_whenInvoked_thenCorrectlyConcatenated() throws Throwable {
+
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, String.class);
+ MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);
+
+ String output = (String) concatMH.invoke("Effective ", "Java");
+
+ assertEquals("Effective Java", output);
+ }
+
+ @Test
+ public void givenAsListMethodHandle_whenInvokingWithArguments_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(List.class, Object[].class);
+ MethodHandle asListMH = publicLookup.findStatic(Arrays.class, "asList", mt);
+
+ List list = (List) asListMH.invokeWithArguments(1, 2);
+
+ assertThat(Arrays.asList(1, 2), is(list));
+ }
+
+ @Test
+ public void givenConstructorMethodHandle_whenInvoked_thenObjectCreatedCorrectly() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(void.class, String.class);
+ MethodHandle newIntegerMH = publicLookup.findConstructor(Integer.class, mt);
+
+ Integer integer = (Integer) newIntegerMH.invoke("1");
+
+ assertEquals(1, integer.intValue());
+ }
+
+ @Test
+ public void givenAFieldWithoutGetter_whenCreatingAGetter_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodHandle getTitleMH = lookup.findGetter(Book.class, "title", String.class);
+
+ Book book = new Book("ISBN-1234", "Effective Java");
+
+ assertEquals("Effective Java", getTitleMH.invoke(book));
+ }
+
+ @Test
+ public void givenPrivateMethod_whenCreatingItsMethodHandle_thenCorrectlyInvoked() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ Method formatBookMethod = Book.class.getDeclaredMethod("formatBook");
+ formatBookMethod.setAccessible(true);
+
+ MethodHandle formatBookMH = lookup.unreflect(formatBookMethod);
+
+ Book book = new Book("ISBN-123", "Java in Action");
+
+ assertEquals("ISBN-123 > Java in Action", formatBookMH.invoke(book));
+ }
+
+ @Test
+ public void givenReplaceMethod_whenUsingReflectionAndInvoked_thenCorrectlyReplaced() throws Throwable {
+ Method replaceMethod = String.class.getMethod("replace", char.class, char.class);
+
+ String string = (String) replaceMethod.invoke("jovo", 'o', 'a');
+
+ assertEquals("java", string);
+ }
+
+ @Test
+ public void givenReplaceMethodHandle_whenInvoked_thenCorrectlyReplaced() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, char.class, char.class);
+ MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
+
+ String replacedString = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');
+
+ assertEquals("java", replacedString);
+ }
+
+ @Test
+ public void givenReplaceMethodHandle_whenInvokingExact_thenCorrectlyReplaced() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(String.class, char.class, char.class);
+ MethodHandle replaceMH = lookup.findVirtual(String.class, "replace", mt);
+
+ String s = (String) replaceMH.invokeExact("jovo", 'o', 'a');
+
+ assertEquals("java", s);
+ }
+
+ @Test
+ public void givenSumMethodHandle_whenInvokingExact_thenSumIsCorrect() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt);
+
+ int sum = (int) sumMH.invokeExact(1, 11);
+
+ assertEquals(12, sum);
+ }
+
+ @Test(expected = WrongMethodTypeException.class)
+ public void givenSumMethodHandleAndIncompatibleArguments_whenInvokingExact_thenException() throws Throwable {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(int.class, int.class, int.class);
+ MethodHandle sumMH = lookup.findStatic(Integer.class, "sum", mt);
+
+ sumMH.invokeExact(Integer.valueOf(1), 11);
+ }
+
+ @Test
+ public void givenSpreadedEqualsMethodHandle_whenInvokedOnArray_thenCorrectlyEvaluated() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(boolean.class, Object.class);
+ MethodHandle equalsMH = publicLookup.findVirtual(String.class, "equals", mt);
+
+ MethodHandle methodHandle = equalsMH.asSpreader(Object[].class, 2);
+
+ assertTrue((boolean) methodHandle.invoke(new Object[] { "java", "java" }));
+ assertFalse((boolean) methodHandle.invoke(new Object[] { "java", "jova" }));
+ }
+
+ @Test
+ public void givenConcatMethodHandle_whenBindToAString_thenCorrectlyConcatenated() throws Throwable {
+ MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(String.class, String.class);
+ MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);
+
+ MethodHandle bindedConcatMH = concatMH.bindTo("Hello ");
+
+ assertEquals("Hello World!", bindedConcatMH.invoke("World!"));
+ }
+}
diff --git a/core-java/README.md b/core-java/README.md
index b160d2271e..5be4e12592 100644
--- a/core-java/README.md
+++ b/core-java/README.md
@@ -128,3 +128,4 @@
- [Recursion In Java](http://www.baeldung.com/java-recursion)
- [A Guide to the finalize Method in Java](http://www.baeldung.com/java-finalize)
- [Compiling Java *.class Files with javac](http://www.baeldung.com/javac)
+- [Method Overloading and Overriding in Java](http://www.baeldung.com/java-method-overload-override)
diff --git a/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java
new file mode 100644
index 0000000000..b6bb5181b8
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/ArmoredCar.java
@@ -0,0 +1,43 @@
+package com.baeldung.inheritance;
+
+public class ArmoredCar extends Car implements Floatable, Flyable{
+ private int bulletProofWindows;
+ private String model;
+
+ public void remoteStartCar() {
+ // this vehicle can be started by using a remote control
+ }
+
+ public String registerModel() {
+ return model;
+ }
+
+ public String getAValue() {
+ return super.model; // returns value of model defined in base class Car
+ // return this.model; // will return value of model defined in ArmoredCar
+ // return model; // will return value of model defined in ArmoredCar
+ }
+
+ public static String msg() {
+ // return super.msg(); // this won't compile.
+ return "ArmoredCar";
+ }
+
+ @Override
+ public void floatOnWater() {
+ System.out.println("I can float!");
+ }
+
+ @Override
+ public void fly() {
+ System.out.println("I can fly!");
+ }
+
+ public void aMethod() {
+ // System.out.println(duration); // Won't compile
+ System.out.println(Floatable.duration); // outputs 10
+ System.out.println(Flyable.duration); // outputs 20
+ }
+
+
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/BMW.java b/core-java/src/main/java/com/baeldung/inheritance/BMW.java
new file mode 100644
index 0000000000..8ad3bb683f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/BMW.java
@@ -0,0 +1,12 @@
+package com.baeldung.inheritance;
+
+public class BMW extends Car {
+ public BMW() {
+ super(5, "BMW");
+ }
+
+ @Override
+ public String toString() {
+ return model;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Car.java b/core-java/src/main/java/com/baeldung/inheritance/Car.java
new file mode 100644
index 0000000000..21ea9ea569
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Car.java
@@ -0,0 +1,32 @@
+package com.baeldung.inheritance;
+
+public class Car {
+ private final int DEFAULT_WHEEL_COUNT = 5;
+ private final String DEFAULT_MODEL = "Basic";
+
+ protected int wheels;
+ protected String model;
+
+ public Car() {
+ this.wheels = DEFAULT_WHEEL_COUNT;
+ this.model = DEFAULT_MODEL;
+ }
+
+ public Car(int wheels, String model) {
+ this.wheels = wheels;
+ this.model = model;
+ }
+
+ public void start() {
+ // Check essential parts
+ // If okay, start.
+ }
+ public static int count = 10;
+ public static String msg() {
+ return "Car";
+ }
+
+ public String toString() {
+ return model;
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Employee.java b/core-java/src/main/java/com/baeldung/inheritance/Employee.java
new file mode 100644
index 0000000000..599a1d7331
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Employee.java
@@ -0,0 +1,15 @@
+package com.baeldung.inheritance;
+
+public class Employee {
+ private String name;
+ private Car car;
+
+ public Employee(String name, Car car) {
+ this.name = name;
+ this.car = car;
+ }
+
+ public Car getCar() {
+ return car;
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Floatable.java b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java
new file mode 100644
index 0000000000..c0b456dffb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Floatable.java
@@ -0,0 +1,10 @@
+package com.baeldung.inheritance;
+
+public interface Floatable {
+ int duration = 10;
+ void floatOnWater();
+
+ default void repair() {
+ System.out.println("Repairing Floatable object");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/Flyable.java b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java
new file mode 100644
index 0000000000..cb8244cf5b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/Flyable.java
@@ -0,0 +1,13 @@
+package com.baeldung.inheritance;
+
+public interface Flyable {
+ int duration = 10;
+ void fly();
+
+ /*
+ * Commented
+ */
+ //default void repair() {
+ // System.out.println("Repairing Flyable object");
+ //}
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java
new file mode 100644
index 0000000000..8c23b26da9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceCar.java
@@ -0,0 +1,18 @@
+package com.baeldung.inheritance;
+
+public class SpaceCar extends Car implements SpaceTraveller {
+ @Override
+ public void floatOnWater() {
+ System.out.println("SpaceCar floating!");
+ }
+
+ @Override
+ public void fly() {
+ System.out.println("SpaceCar flying!");
+ }
+
+ @Override
+ public void remoteControl() {
+ System.out.println("SpaceCar being controlled remotely!");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java
new file mode 100644
index 0000000000..9b66441791
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/inheritance/SpaceTraveller.java
@@ -0,0 +1,6 @@
+package com.baeldung.inheritance;
+
+public interface SpaceTraveller extends Floatable, Flyable {
+ int duration = 10;
+ void remoteControl();
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/java/list/CustomList.java b/core-java/src/main/java/com/baeldung/java/list/CustomList.java
index bc1321b1a3..8b91fca32f 100644
--- a/core-java/src/main/java/com/baeldung/java/list/CustomList.java
+++ b/core-java/src/main/java/com/baeldung/java/list/CustomList.java
@@ -9,6 +9,58 @@ import java.util.ListIterator;
public class CustomList implements List {
private Object[] internal = {};
+ @Override
+ public boolean isEmpty() {
+ // the first cycle
+ // return true;
+
+ // the second cycle
+ // if (internal.length != 0) {
+ // return false;
+ // } else {
+ // return true;
+ // }
+
+ // refactoring
+ return internal.length == 0;
+ }
+
+ @Override
+ public int size() {
+ // the first cycle
+ // if (isEmpty()) {
+ // return 0;
+ // } else {
+ // return internal.length;
+ // }
+
+ // refactoring
+ return internal.length;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E get(int index) {
+ // the first cycle
+ // return (E) internal[0];
+
+ // improvement
+ return (E) internal[index];
+ }
+
+ @Override
+ public boolean add(E element) {
+ // the first cycle
+ // internal = new Object[] { element };
+ // return true;
+
+ // the second cycle
+ Object[] temp = Arrays.copyOf(internal, internal.length + 1);
+ temp[internal.length] = element;
+ internal = temp;
+ return true;
+ }
+
@Override
public void add(int index, E element) {
throw new UnsupportedOperationException();
@@ -44,40 +96,8 @@ public class CustomList implements List {
throw new UnsupportedOperationException();
}
- @Override
- public int size() {
- return internal.length;
- }
-
- @Override
- public boolean isEmpty() {
- return internal.length == 0;
- }
-
- @Override
- public boolean add(E element) {
- // the first cycle
- // internal = new Object[1];
- // internal[0] = element;
- // return true;
-
- Object[] temp = new Object[internal.length + 1];
- System.arraycopy(internal, 0, temp, 0, internal.length);
- temp[internal.length] = element;
- internal = temp;
- return true;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public E get(int index) {
- return (E) internal[index];
- }
-
@Override
public boolean contains(Object object) {
- // return false
-
for (Object element : internal) {
if (object.equals(element)) {
return true;
@@ -88,14 +108,6 @@ public class CustomList implements List {
@Override
public boolean containsAll(Collection> collection) {
- // the first cycle
- // for (Object element : collection) {
- // if (element.equals(internal[0])) {
- // return true;
- // }
- // }
- // return false;
-
for (Object element : collection)
if (!contains(element)) {
return false;
@@ -118,12 +130,6 @@ public class CustomList implements List {
@Override
public int indexOf(Object object) {
- // the first cycle
- // if (object.equals(internal[0])) {
- // return 0;
- // }
- // return -1;
-
for (int i = 0; i < internal.length; i++) {
if (object.equals(internal[i])) {
return i;
@@ -134,12 +140,6 @@ public class CustomList implements List {
@Override
public int lastIndexOf(Object object) {
- // the first cycle
- // if (object.equals(internal[0])) {
- // return 0;
- // }
- // return -1;
-
for (int i = internal.length - 1; i >= 0; i--) {
if (object.equals(internal[i])) {
return i;
@@ -151,9 +151,6 @@ public class CustomList implements List {
@SuppressWarnings("unchecked")
@Override
public List subList(int fromIndex, int toIndex) {
- // the first cycle
- // return (List) Arrays.asList(internal);
-
Object[] temp = new Object[toIndex - fromIndex];
System.arraycopy(internal, fromIndex, temp, 0, temp.length);
return (List) Arrays.asList(temp);
@@ -167,16 +164,6 @@ public class CustomList implements List {
@SuppressWarnings("unchecked")
@Override
public T[] toArray(T[] array) {
- // the first cycle
- // array[0] = (T) internal[0];
- // return array;
-
- // the second cycle
- // if (array.length < internal.length) {
- // return (T[]) Arrays.copyOf(internal, internal.length, array.getClass());
- // }
- // return (T[]) Arrays.copyOf(internal, internal.length, array.getClass());
-
if (array.length < internal.length) {
return (T[]) Arrays.copyOf(internal, internal.length, array.getClass());
}
@@ -209,18 +196,12 @@ public class CustomList implements List {
@Override
public boolean hasNext() {
- // the first cycle
- // return true;
-
return index != internal.length;
}
@SuppressWarnings("unchecked")
@Override
public E next() {
- // the first cycle
- // return (E) CustomList.this.internal[0];
-
E element = (E) CustomList.this.internal[index];
index++;
return element;
diff --git a/core-java/src/main/java/com/baeldung/system/DetectOS.java b/core-java/src/main/java/com/baeldung/system/DetectOS.java
new file mode 100644
index 0000000000..2d605fe49f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/system/DetectOS.java
@@ -0,0 +1,18 @@
+package com.baeldung.system;
+
+import org.apache.commons.lang3.SystemUtils;
+
+public class DetectOS {
+
+ public String getOperatingSystem() {
+ String os = System.getProperty("os.name");
+ System.out.println("Using System Property: " + os);
+ return os;
+ }
+
+ public String getOperatingSystemSystemUtils() {
+ String os = SystemUtils.OS_NAME;
+ System.out.println("Using SystemUtils: " + os);
+ return os;
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/inheritance/AppTest.java b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java
new file mode 100644
index 0000000000..1235761aba
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/inheritance/AppTest.java
@@ -0,0 +1,46 @@
+package com.baeldung.inheritance;
+
+import com.baeldung.inheritance.*;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+public class AppTest extends TestCase {
+
+ public AppTest(String testName) {
+ super( testName );
+ }
+
+ public static Test suite() {
+ return new TestSuite(AppTest.class);
+ }
+
+ @SuppressWarnings("static-access")
+ public void testStaticMethodUsingBaseClassVariable() {
+ Car first = new ArmoredCar();
+ assertEquals("Car", first.msg());
+ }
+
+ @SuppressWarnings("static-access")
+ public void testStaticMethodUsingDerivedClassVariable() {
+ ArmoredCar second = new ArmoredCar();
+ assertEquals("ArmoredCar", second.msg());
+ }
+
+ public void testAssignArmoredCarToCar() {
+ Employee e1 = new Employee("Shreya", new ArmoredCar());
+ assertNotNull(e1.getCar());
+ }
+
+ public void testAssignSpaceCarToCar() {
+ Employee e2 = new Employee("Paul", new SpaceCar());
+ assertNotNull(e2.getCar());
+ }
+
+ public void testBMWToCar() {
+ Employee e3 = new Employee("Pavni", new BMW());
+ assertNotNull(e3.getCar());
+ }
+
+}
diff --git a/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java
index 3ee3195e80..9ea42e88e8 100644
--- a/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/java/list/CustomListUnitTest.java
@@ -14,6 +14,58 @@ import java.util.List;
import org.junit.Test;
public class CustomListUnitTest {
+ @Test
+ public void givenEmptyList_whenIsEmpty_thenTrueIsReturned() {
+ List
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt
new file mode 100644
index 0000000000..721bdb04bc
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Controller.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class Controller(private val service : Service)
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt
new file mode 100644
index 0000000000..a0be7ef0e0
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Dao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+interface Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt
new file mode 100644
index 0000000000..0a09b95dbf
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/JdbcDao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class JdbcDao : Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt
new file mode 100644
index 0000000000..06436fcd21
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/MongoDao.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class MongoDao : Dao
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt
new file mode 100644
index 0000000000..bb24a5cc21
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/kotlin/kodein/Service.kt
@@ -0,0 +1,3 @@
+package com.baeldung.kotlin.kodein
+
+class Service(private val dao: Dao, private val tag: String)
\ No newline at end of file
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt
new file mode 100644
index 0000000000..7776eebd52
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/kodein/KodeinUnitTest.kt
@@ -0,0 +1,191 @@
+package com.baeldung.kotlin.kodein
+
+import com.github.salomonbrys.kodein.*
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class KodeinUnitTest {
+
+ class InMemoryDao : Dao
+
+ @Test
+ fun whenSingletonBinding_thenSingleInstanceIsCreated() {
+ var created = false
+ val kodein = Kodein {
+ bind() with singleton {
+ created = true
+ MongoDao()
+ }
+ }
+
+ assertThat(created).isFalse()
+
+ val dao1: Dao = kodein.instance()
+
+ assertThat(created).isTrue()
+
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isSameAs(dao2)
+ }
+
+ @Test
+ fun whenFactoryBinding_thenNewInstanceIsCreated() {
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with factory { tag: String -> Service(instance(), tag) }
+ }
+ val service1: Service = kodein.with("myTag").instance()
+ val service2: Service = kodein.with("myTag").instance()
+
+ assertThat(service1).isNotSameAs(service2)
+ }
+
+ @Test
+ fun whenProviderBinding_thenNewInstanceIsCreated() {
+ val kodein = Kodein {
+ bind() with provider { MongoDao() }
+ }
+ val dao1: Dao = kodein.instance()
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isNotSameAs(dao2)
+ }
+
+ @Test
+ fun whenTaggedBinding_thenMultipleInstancesOfSameTypeCanBeRegistered() {
+ val kodein = Kodein {
+ bind("dao1") with singleton { MongoDao() }
+ bind("dao2") with singleton { MongoDao() }
+ }
+ val dao1: Dao = kodein.instance("dao1")
+ val dao2: Dao = kodein.instance("dao2")
+
+ assertThat(dao1).isNotSameAs(dao2)
+ }
+
+ @Test
+ fun whenEagerSingletonBinding_thenCreationIsEager() {
+ var created = false
+ val kodein = Kodein {
+ bind() with eagerSingleton {
+ created = true
+ MongoDao()
+ }
+ }
+
+ assertThat(created).isTrue()
+ val dao1: Dao = kodein.instance()
+ val dao2: Dao = kodein.instance()
+
+ assertThat(dao1).isSameAs(dao2)
+ }
+
+ @Test
+ fun whenMultitonBinding_thenInstancesAreReused() {
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with multiton { tag: String -> Service(instance(), tag) }
+ }
+ val service1: Service = kodein.with("myTag").instance()
+ val service2: Service = kodein.with("myTag").instance()
+
+ assertThat(service1).isSameAs(service2)
+ }
+
+ @Test
+ fun whenInstanceBinding_thenItIsReused() {
+ val dao = MongoDao()
+ val kodein = Kodein {
+ bind() with instance(dao)
+ }
+ val fromContainer: Dao = kodein.instance()
+
+ assertThat(dao).isSameAs(fromContainer)
+ }
+
+ @Test
+ fun whenConstantBinding_thenItIsAvailable() {
+ val kodein = Kodein {
+ constant("magic") with 42
+ }
+ val fromContainer: Int = kodein.instance("magic")
+
+ assertThat(fromContainer).isEqualTo(42)
+ }
+
+ @Test
+ fun whenUsingModules_thenTransitiveDependenciesAreSuccessfullyResolved() {
+ val jdbcModule = Kodein.Module {
+ bind() with singleton { JdbcDao() }
+ }
+ val kodein = Kodein {
+ import(jdbcModule)
+ bind() with singleton { Controller(instance()) }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+
+ val dao: Dao = kodein.instance()
+ assertThat(dao).isInstanceOf(JdbcDao::class.java)
+ }
+
+ @Test
+ fun whenComposition_thenBeansAreReUsed() {
+ val persistenceContainer = Kodein {
+ bind() with singleton { MongoDao() }
+ }
+ val serviceContainer = Kodein {
+ extend(persistenceContainer)
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val fromPersistence: Dao = persistenceContainer.instance()
+ val fromService: Dao = serviceContainer.instance()
+
+ assertThat(fromPersistence).isSameAs(fromService)
+ }
+
+ @Test
+ fun whenOverriding_thenRightBeanIsUsed() {
+ val commonModule = Kodein.Module {
+ bind() with singleton { MongoDao() }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val testContainer = Kodein {
+ import(commonModule)
+ bind(overrides = true) with singleton { InMemoryDao() }
+ }
+ val dao: Dao = testContainer.instance()
+
+ assertThat(dao).isInstanceOf(InMemoryDao::class.java)
+ }
+
+ @Test
+ fun whenMultiBinding_thenWorks() {
+ val kodein = Kodein {
+ bind() from setBinding()
+ bind().inSet() with singleton { MongoDao() }
+ bind().inSet() with singleton { JdbcDao() }
+ }
+ val daos: Set = kodein.instance()
+
+ assertThat(daos.map { it.javaClass as Class<*> }).containsOnly(MongoDao::class.java, JdbcDao::class.java)
+ }
+
+ @Test
+ fun whenInjector_thenWorks() {
+ class Controller2 {
+ private val injector = KodeinInjector()
+ val service: Service by injector.instance()
+ fun injectDependencies(kodein: Kodein) = injector.inject(kodein)
+ }
+
+ val kodein = Kodein {
+ bind() with singleton { MongoDao() }
+ bind() with singleton { Service(instance(), "myService") }
+ }
+ val controller = Controller2()
+ controller.injectDependencies(kodein)
+
+ assertThat(controller.service).isNotNull
+ }
+}
\ No newline at end of file
diff --git a/ethereumj/pom.xml b/ethereumj/pom.xml
index c9f5924d7a..9676106e38 100644
--- a/ethereumj/pom.xml
+++ b/ethereumj/pom.xml
@@ -1,6 +1,5 @@
-
+
4.0.0
com.baeldung.ethereumj
ethereumj
@@ -8,16 +7,11 @@
1.0.0
ethereumj
-
- UTF-8
- 1.8
- 8.5.4
-
-
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.6.RELEASE
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-5
@@ -38,14 +32,12 @@
org.springframework.boot
spring-boot-starter-tomcat
-
org.springframework.boot
spring-boot-starter-test
- 1.5.6.RELEASE
test
@@ -107,4 +99,11 @@
+
+
+ UTF-8
+ 1.8
+ 8.5.4
+
+
\ No newline at end of file
diff --git a/gradle/build.gradle b/gradle/build.gradle
index dcc592a2b4..2e5d984fba 100644
--- a/gradle/build.gradle
+++ b/gradle/build.gradle
@@ -33,3 +33,60 @@ task execSecondTest {
}
println 'This will be executed during the configuration phase as well.'
}
+
+task welcome {
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+task welcomeWithGroup {
+ group 'Sample category'
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+task welcomeWithGroupAndDescription {
+ group 'Sample category'
+ description 'Tasks which shows welcome message'
+ doLast {
+ println 'Welcome on the Baeldung!'
+ }
+}
+
+class PrintToolVersionTask extends DefaultTask {
+ String tool
+
+ @TaskAction
+ void printToolVersion() {
+ switch (tool) {
+ case 'java':
+ println System.getProperty("java.version")
+ break
+ case 'groovy':
+ println GroovySystem.version
+ break
+ default:
+ throw new IllegalArgumentException("Unknown tool")
+ }
+ }
+}
+
+task printJavaVersion(type : PrintToolVersionTask) {
+ tool 'java'
+}
+
+task printGroovyVersion(type : PrintToolVersionTask) {
+ tool 'groovy'
+}
+
+import com.baeldung.PrintToolVersionBuildSrcTask
+
+task printJavaVersionBuildSrc(type : PrintToolVersionBuildSrcTask) {
+ tool 'java'
+}
+
+task printGroovyVersionBuildSrc(type : PrintToolVersionBuildSrcTask) {
+ tool 'groovy'
+}
\ No newline at end of file
diff --git a/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy
new file mode 100644
index 0000000000..0fbd71db56
--- /dev/null
+++ b/gradle/buildSrc/src/main/groovy/com/baeldung/PrintToolVersionBuildSrcTask.groovy
@@ -0,0 +1,22 @@
+package com.baeldung
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.TaskAction
+
+class PrintToolVersionBuildSrcTask extends DefaultTask {
+ String tool
+
+ @TaskAction
+ void printToolVersion() {
+ switch (tool) {
+ case 'java':
+ println System.getProperty("java.version")
+ break
+ case 'groovy':
+ println GroovySystem.version
+ break
+ default:
+ throw new IllegalArgumentException("Unknown tool")
+ }
+ }
+}
\ No newline at end of file
diff --git a/libraries/helloWorld.docx b/libraries/helloWorld.docx
index 09e71a4d4e..6e0a372dad 100644
Binary files a/libraries/helloWorld.docx and b/libraries/helloWorld.docx differ
diff --git a/logging-modules/log4j/src/main/resources/logback.xml b/logging-modules/log4j/src/main/resources/logback.xml
index f567962cb6..097f6694f0 100644
--- a/logging-modules/log4j/src/main/resources/logback.xml
+++ b/logging-modules/log4j/src/main/resources/logback.xml
@@ -78,7 +78,7 @@
-
+
diff --git a/parent-boot-5/pom.xml b/parent-boot-5/pom.xml
index 55ac0957ff..0e3936a73a 100644
--- a/parent-boot-5/pom.xml
+++ b/parent-boot-5/pom.xml
@@ -21,7 +21,7 @@
spring-boot-starter-parent
org.springframework.boot
- 1.5.9.RELEASE
+ 1.5.10.RELEASE
@@ -60,9 +60,6 @@
**/*IntegrationTest.java
**/*LongRunningUnitTest.java
**/*ManualTest.java
- **/JdbcTest.java
- **/AutoconfigurationTest.java
- **/*EntryPointsTest.java
**/*LiveTest.java
diff --git a/pom.xml b/pom.xml
index beb377a40b..3092c0fa40 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,5 @@
-
+
4.0.0
com.baeldung
parent-modules
@@ -15,7 +14,7 @@
true
false
false
-
+
4.12
1.3
2.8.9
@@ -51,7 +50,7 @@
core-java-8
core-groovy
core-java-concurrency
-
+
couchbase
deltaspike
@@ -59,7 +58,7 @@
ethereumj
-
+
feign
@@ -79,20 +78,20 @@
handling-spring-static-resources
hazelcast
hbase
-
+
httpclient
hystrix
- image-processing
+
immutables
influxdb
jackson
-
+
vavr
- java-lite
- java-rmi
- java-vavr-stream
+ java-lite
+ java-rmi
+ java-vavr-stream
javax-servlets
javaxval
jaxb
@@ -116,17 +115,15 @@
logging-modules/log4j2
logging-modules/logback
lombok
-
+
mapstruct
-
+
mesos-marathon
testing-modules/mockito
testing-modules/mockito-2
testing-modules/mocks
mustache
- mvn-wrapper
+ mvn-wrapper
noexception
orientdb
osgi
@@ -146,14 +143,13 @@
resteasy
rxjava
spring-swagger-codegen
-
testing-modules/selenium-junit-testng
persistence-modules/solr
spark-java
-
+ spring-5
spring-5-reactive
spring-5-mvc
- spring-5-security
+
spring-activiti
spring-akka
spring-amqp
@@ -163,7 +159,7 @@
spring-batch
spring-bom
spring-boot
- spring-boot-keycloak
+ spring-boot-keycloak
spring-boot-bootstrap
spring-boot-admin
spring-boot-security
@@ -192,7 +188,7 @@
spring-integration
spring-jenkins-pipeline
spring-jersey
- jmeter
+
spring-jms
spring-jooq
persistence-modules/spring-jpa
@@ -252,7 +248,7 @@
spring-vertx
spring-jinq
- spring-rest-embedded-tomcat
+ spring-rest-embedded-tomcat
testing-modules/testing
@@ -280,7 +276,7 @@
saas
deeplearning4j
lucene
- vraptor
+ vraptor
persistence-modules/java-cockroachdb
@@ -307,7 +303,7 @@
${org.slf4j.version}
-
+
junit
junit
diff --git a/spring-5-security/pom.xml b/spring-5-security/pom.xml
index 0a1d1f5df0..ffe6865704 100644
--- a/spring-5-security/pom.xml
+++ b/spring-5-security/pom.xml
@@ -12,7 +12,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.M7
+ 2.0.0.RC2
diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java
new file mode 100644
index 0000000000..94987029db
--- /dev/null
+++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/BaeldungPasswordEncoderSetup.java
@@ -0,0 +1,35 @@
+package com.baeldung.passwordstorage;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@Configuration
+public class BaeldungPasswordEncoderSetup {
+
+ private final static Logger LOG = LoggerFactory.getLogger(BaeldungPasswordEncoderSetup.class);
+
+ @Bean
+ public ApplicationListener authenticationSuccessListener(final PasswordEncoder encoder) {
+
+ return (AuthenticationSuccessEvent event) -> {
+ final Authentication auth = event.getAuthentication();
+
+ if (auth instanceof UsernamePasswordAuthenticationToken && auth.getCredentials() != null) {
+
+ final CharSequence clearTextPass = (CharSequence) auth.getCredentials(); // 1
+ final String newPasswordHash = encoder.encode(clearTextPass); // 2
+
+ LOG.info("New password hash {} for user {}", newPasswordHash, auth.getName());
+
+ ((UsernamePasswordAuthenticationToken) auth).eraseCredentials(); // 3
+ }
+ };
+ }
+}
diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java
new file mode 100644
index 0000000000..173d979a45
--- /dev/null
+++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.passwordstorage;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PasswordStorageApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PasswordStorageApplication.class, args);
+ }
+
+}
diff --git a/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
new file mode 100644
index 0000000000..22ef2f0835
--- /dev/null
+++ b/spring-5-security/src/main/java/com/baeldung/passwordstorage/PasswordStorageWebSecurityConfigurer.java
@@ -0,0 +1,53 @@
+package com.baeldung.passwordstorage;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.crypto.password.StandardPasswordEncoder;
+import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
+import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class PasswordStorageWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
+
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.eraseCredentials(false) // 4
+ .userDetailsService(getUserDefaultDetailsService())
+ .passwordEncoder(passwordEncoder());
+ }
+
+ @Bean
+ public UserDetailsService getUserDefaultDetailsService() {
+ User testUser = new User("baeldung", "{noop}SpringSecurity5", Collections.emptyList());
+ return new InMemoryUserDetailsManager(testUser);
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ // set up the list of supported encoders and their prefixes
+ PasswordEncoder defaultEncoder = new StandardPasswordEncoder();
+ Map encoders = new HashMap<>();
+ encoders.put("bcrypt", new BCryptPasswordEncoder());
+ encoders.put("scrypt", new SCryptPasswordEncoder());
+ encoders.put("noop", NoOpPasswordEncoder.getInstance());
+
+ DelegatingPasswordEncoder passwordEncoder = new DelegatingPasswordEncoder("bcrypt", encoders);
+ passwordEncoder.setDefaultPasswordEncoderForMatches(defaultEncoder);
+
+ return passwordEncoder;
+ }
+
+}
diff --git a/spring-5/pom.xml b/spring-5/pom.xml
index 19dd65d78f..3b21f86e60 100644
--- a/spring-5/pom.xml
+++ b/spring-5/pom.xml
@@ -14,7 +14,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.M7
+ 2.0.0.RC2
@@ -39,10 +39,14 @@
org.springframework.boot
spring-boot-starter-webflux
-
+
org.springframework.boot
spring-boot-starter-hateoas
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
org.projectreactor
reactor-spring
diff --git a/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java b/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java
index 287356256c..1670da54c3 100644
--- a/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java
+++ b/spring-5/src/main/java/com/baeldung/execption/SpringExceptionApplication.java
@@ -1,14 +1,14 @@
-package com.baeldung.execption;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
-import org.springframework.context.annotation.ComponentScan;
-
-@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
-@ComponentScan(basePackages = { "com.baeldung.execption" })
-public class SpringExceptionApplication {
- public static void main(String[] args) {
- SpringApplication.run(SpringExceptionApplication.class, args);
- }
+package com.baeldung.execption;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
+@ComponentScan(basePackages = { "com.baeldung.execption" })
+public class SpringExceptionApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(SpringExceptionApplication.class, args);
+ }
}
\ No newline at end of file
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/Config.java b/spring-5/src/main/java/com/baeldung/sessionattrs/Config.java
new file mode 100644
index 0000000000..9d5c9d9f42
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/Config.java
@@ -0,0 +1,44 @@
+package com.baeldung.sessionattrs;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Scope;
+import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.core.Ordered;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.thymeleaf.templatemode.TemplateMode;
+import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
+import org.thymeleaf.templateresolver.ITemplateResolver;
+
+@EnableWebMvc
+@Configuration
+public class Config implements WebMvcConfigurer {
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/").setViewName("index");
+ registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
+ }
+
+ @Bean
+ @Scope(
+ value = WebApplicationContext.SCOPE_SESSION,
+ proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public TodoList todos() {
+ return new TodoList();
+ }
+
+ @Bean
+ public ITemplateResolver templateResolver() {
+ ClassLoaderTemplateResolver resolver
+ = new ClassLoaderTemplateResolver();
+ resolver.setPrefix("templates/sessionattrs/");
+ resolver.setSuffix(".html");
+ resolver.setTemplateMode(TemplateMode.HTML);
+ resolver.setCharacterEncoding("UTF-8");
+ return resolver;
+ }
+}
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java b/spring-5/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java
new file mode 100644
index 0000000000..7b9f8a700f
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java
@@ -0,0 +1,16 @@
+package com.baeldung.sessionattrs;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
+
+@SpringBootApplication(
+ exclude = {SecurityAutoConfiguration.class,
+ DataSourceAutoConfiguration.class})
+public class SessionAttrsApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SessionAttrsApplication.class, args);
+ }
+}
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java
new file mode 100644
index 0000000000..0c3bd6c8b6
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java
@@ -0,0 +1,45 @@
+package com.baeldung.sessionattrs;
+
+import java.time.LocalDateTime;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+@RequestMapping("/scopedproxy")
+public class TodoControllerWithScopedProxy {
+
+ private TodoList todos;
+
+ public TodoControllerWithScopedProxy(TodoList todos) {
+ this.todos = todos;
+ }
+
+ @GetMapping("/form")
+ public String showForm(Model model) {
+ if (!todos.isEmpty()) {
+ model.addAttribute("todo", todos.peekLast());
+ } else {
+ model.addAttribute("todo", new TodoItem());
+ }
+
+ return "scopedproxyform";
+ }
+
+ @PostMapping("/form")
+ public String create(@ModelAttribute TodoItem todo) {
+ todo.setCreateDate(LocalDateTime.now());
+ todos.add(todo);
+ return "redirect:/scopedproxy/todos.html";
+ }
+
+ @GetMapping("/todos.html")
+ public String list(Model model) {
+ model.addAttribute("todos", todos);
+ return "scopedproxytodos";
+ }
+}
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java
new file mode 100644
index 0000000000..fc7e57b1db
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java
@@ -0,0 +1,55 @@
+package com.baeldung.sessionattrs;
+
+import java.time.LocalDateTime;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+import org.springframework.web.servlet.view.RedirectView;
+
+@Controller
+@RequestMapping("/sessionattributes")
+@SessionAttributes("todos")
+public class TodoControllerWithSessionAttributes {
+
+ @GetMapping("/form")
+ public String showForm(
+ Model model,
+ @ModelAttribute("todos") TodoList todos) {
+ if (!todos.isEmpty()) {
+ model.addAttribute("todo", todos.peekLast());
+ } else {
+ model.addAttribute("todo", new TodoItem());
+ }
+ return "sessionattributesform";
+ }
+
+ @PostMapping("/form")
+ public RedirectView create(
+ @ModelAttribute TodoItem todo,
+ @ModelAttribute("todos") TodoList todos,
+ RedirectAttributes attributes) {
+ todo.setCreateDate(LocalDateTime.now());
+ todos.add(todo);
+ attributes.addFlashAttribute("todos", todos);
+ return new RedirectView("/sessionattributes/todos.html");
+ }
+
+ @GetMapping("/todos.html")
+ public String list(
+ Model model,
+ @ModelAttribute("todos") TodoList todos) {
+ model.addAttribute("todos", todos);
+ return "sessionattributestodos";
+ }
+
+ @ModelAttribute("todos")
+ public TodoList todos() {
+ return new TodoList();
+ }
+}
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/TodoItem.java b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoItem.java
new file mode 100644
index 0000000000..619d61d5f0
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoItem.java
@@ -0,0 +1,39 @@
+package com.baeldung.sessionattrs;
+
+import java.time.LocalDateTime;
+
+public class TodoItem {
+
+ private String description;
+ private LocalDateTime createDate;
+
+ public TodoItem(String description, LocalDateTime createDate) {
+ this.description = description;
+ this.createDate = createDate;
+ }
+
+ public TodoItem() {
+ // default no arg constructor
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public LocalDateTime getCreateDate() {
+ return createDate;
+ }
+
+ public void setCreateDate(LocalDateTime createDate) {
+ this.createDate = createDate;
+ }
+
+ @Override
+ public String toString() {
+ return "TodoItem [description=" + description + ", createDate=" + createDate + "]";
+ }
+}
diff --git a/spring-5/src/main/java/com/baeldung/sessionattrs/TodoList.java b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoList.java
new file mode 100644
index 0000000000..cad7811da4
--- /dev/null
+++ b/spring-5/src/main/java/com/baeldung/sessionattrs/TodoList.java
@@ -0,0 +1,8 @@
+package com.baeldung.sessionattrs;
+
+import java.util.ArrayDeque;
+
+@SuppressWarnings("serial")
+public class TodoList extends ArrayDeque{
+
+}
diff --git a/spring-5/src/main/resources/templates/sessionattrs/index.html b/spring-5/src/main/resources/templates/sessionattrs/index.html
new file mode 100644
index 0000000000..72427cd62b
--- /dev/null
+++ b/spring-5/src/main/resources/templates/sessionattrs/index.html
@@ -0,0 +1,27 @@
+
+
+
+ Session Scope in Spring MVC
+
+
+
+
+
+
+
+
+
+
Session Scope in Spring MVC - Example
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/main/resources/templates/sessionattrs/scopedproxyform.html b/spring-5/src/main/resources/templates/sessionattrs/scopedproxyform.html
new file mode 100644
index 0000000000..e72651556b
--- /dev/null
+++ b/spring-5/src/main/resources/templates/sessionattrs/scopedproxyform.html
@@ -0,0 +1,27 @@
+
+
+
+ Session Scope in Spring MVC
+
+
+
+
+
+
+
+
+
+
Scoped Proxy Example
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/main/resources/templates/sessionattrs/scopedproxytodos.html b/spring-5/src/main/resources/templates/sessionattrs/scopedproxytodos.html
new file mode 100644
index 0000000000..5493b5cf64
--- /dev/null
+++ b/spring-5/src/main/resources/templates/sessionattrs/scopedproxytodos.html
@@ -0,0 +1,48 @@
+
+
+
+ Session Scope in Spring MVC
+
+
+
+
+
+
+
+
+
+
Scoped Proxy Example
+
+
+
+
+
+
+
+
+
+
TODO List
+
+
+
+ Description |
+ Create Date |
+
+
+ Description |
+ Create Date |
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/main/resources/templates/sessionattrs/sessionattributesform.html b/spring-5/src/main/resources/templates/sessionattrs/sessionattributesform.html
new file mode 100644
index 0000000000..28e1d5d2c1
--- /dev/null
+++ b/spring-5/src/main/resources/templates/sessionattrs/sessionattributesform.html
@@ -0,0 +1,27 @@
+
+
+
+ Session Scope in Spring MVC
+
+
+
+
+
+
+
+
+
+
Session Attributes Example
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/main/resources/templates/sessionattrs/sessionattributestodos.html b/spring-5/src/main/resources/templates/sessionattrs/sessionattributestodos.html
new file mode 100644
index 0000000000..4bae12ffb9
--- /dev/null
+++ b/spring-5/src/main/resources/templates/sessionattrs/sessionattributestodos.html
@@ -0,0 +1,48 @@
+
+
+
+ Session Scope in Spring MVC
+
+
+
+
+
+
+
+
+
+
Session Attributes Example
+
+
+
+
+
+
+
+
+
+
TODO List
+
+
+
+ Description |
+ Create Date |
+
+
+ Description |
+ Create Date |
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationTests.java b/spring-5/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationTests.java
new file mode 100644
index 0000000000..0b15a2114d
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationTests.java
@@ -0,0 +1,16 @@
+package com.baeldung.sessionattrs;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SessionAttrsApplicationTests {
+
+ @Test
+ public void contextLoads() {
+ }
+
+}
diff --git a/spring-5/src/test/java/com/baeldung/sessionattrs/TestConfig.java b/spring-5/src/test/java/com/baeldung/sessionattrs/TestConfig.java
new file mode 100644
index 0000000000..07d65dd7c2
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/sessionattrs/TestConfig.java
@@ -0,0 +1,17 @@
+package com.baeldung.sessionattrs;
+
+import org.springframework.beans.factory.config.CustomScopeConfigurer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.SimpleThreadScope;
+
+@Configuration
+public class TestConfig {
+
+ @Bean
+ public CustomScopeConfigurer customScopeConfigurer() {
+ CustomScopeConfigurer configurer = new CustomScopeConfigurer();
+ configurer.addScope("session", new SimpleThreadScope());
+ return configurer;
+ }
+}
diff --git a/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyTest.java b/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyTest.java
new file mode 100644
index 0000000000..3db7c183ce
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.sessionattrs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.WebApplicationContext;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+@Import(TestConfig.class)
+public class TodoControllerWithScopedProxyTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
+ .build();
+ }
+
+ @Test
+ public void whenFirstRequest_thenContainsAllCategoriesAndUnintializedTodo() throws Exception {
+ MvcResult result = mockMvc.perform(get("/scopedproxy/form"))
+ .andExpect(status().isOk())
+ .andExpect(model().attributeExists("todo"))
+ .andReturn();
+
+ TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
+ assertTrue(StringUtils.isEmpty(item.getDescription()));
+ }
+
+ @Test
+ public void whenSubmit_thenSubsequentFormRequestContainsMostRecentTodo() throws Exception {
+ mockMvc.perform(post("/scopedproxy/form")
+ .param("description", "newtodo"))
+ .andExpect(status().is3xxRedirection())
+ .andReturn();
+
+ MvcResult result = mockMvc.perform(get("/scopedproxy/form"))
+ .andExpect(status().isOk())
+ .andExpect(model().attributeExists("todo"))
+ .andReturn();
+ TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
+ assertEquals("newtodo", item.getDescription());
+ }
+
+}
diff --git a/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesTest.java b/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesTest.java
new file mode 100644
index 0000000000..a09fac9699
--- /dev/null
+++ b/spring-5/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesTest.java
@@ -0,0 +1,68 @@
+package com.baeldung.sessionattrs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.util.StringUtils;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.FlashMap;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@AutoConfigureMockMvc
+public class TodoControllerWithSessionAttributesTest {
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private WebApplicationContext wac;
+
+ @Before
+ public void setup() {
+ this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
+ .build();
+ }
+
+ @Test
+ public void whenFirstRequest_thenContainsUnintializedTodo() throws Exception {
+ MvcResult result = mockMvc.perform(get("/sessionattributes/form"))
+ .andExpect(status().isOk())
+ .andExpect(model().attributeExists("todo"))
+ .andReturn();
+
+ TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
+ assertTrue(StringUtils.isEmpty(item.getDescription()));
+ }
+
+ @Test
+ public void whenSubmit_thenSubsequentFormRequestContainsMostRecentTodo() throws Exception {
+ FlashMap flashMap = mockMvc.perform(post("/sessionattributes/form")
+ .param("description", "newtodo"))
+ .andExpect(status().is3xxRedirection())
+ .andReturn().getFlashMap();
+
+ MvcResult result = mockMvc.perform(get("/sessionattributes/form")
+ .sessionAttrs(flashMap))
+ .andExpect(status().isOk())
+ .andExpect(model().attributeExists("todo"))
+ .andReturn();
+ TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
+ assertEquals("newtodo", item.getDescription());
+ }
+
+}
diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml
index 5ad8330a89..21c0ea60a8 100644
--- a/spring-boot-bootstrap/pom.xml
+++ b/spring-boot-bootstrap/pom.xml
@@ -24,12 +24,12 @@
org.springframework.boot
spring-boot-starter-data-jpa
- 1.5.5.RELEASE
+ 1.5.10.RELEASE
org.springframework.boot
spring-boot-dependencies
- 1.5.6.RELEASE
+ 1.5.10.RELEASE
pom
import
diff --git a/spring-boot-property-exp/pom.xml b/spring-boot-property-exp/pom.xml
index 0c54d57db1..1a1e31385e 100644
--- a/spring-boot-property-exp/pom.xml
+++ b/spring-boot-property-exp/pom.xml
@@ -1,6 +1,11 @@
-
+
+ 4.0.0
+ spring-boot-property-exp
+
+ com.baeldung
+ spring-boot-property-exp
+ 0.0.1-SNAPSHOT
+ pom
parent-modules
@@ -8,17 +13,6 @@
1.0.0-SNAPSHOT
- 4.0.0
-
- com.baeldung
- spring-boot-property-exp
- 0.0.1-SNAPSHOT
-
- pom
-
- spring-boot-property-exp
- http://maven.apache.org
-
UTF-8
@@ -28,5 +22,4 @@
property-exp-custom-config
-
diff --git a/spring-boot-property-exp/property-exp-custom-config/pom.xml b/spring-boot-property-exp/property-exp-custom-config/pom.xml
index 7822b31cf2..019e2362a1 100644
--- a/spring-boot-property-exp/property-exp-custom-config/pom.xml
+++ b/spring-boot-property-exp/property-exp-custom-config/pom.xml
@@ -1,32 +1,26 @@
-
-
- spring-boot-property-exp
- com.baeldung
- 0.0.1-SNAPSHOT
-
+
4.0.0
+ property-exp-custom
com.baeldung
property-exp-custom-config
0.0.1-SNAPSHOT
jar
- property-exp-custom
- http://maven.apache.org
-
-
- UTF-8
- Custom Property Value
-
+
+ spring-boot-property-exp
+ com.baeldung
+ 0.0.1-SNAPSHOT
+
+
org.springframework.boot
spring-boot-starter
- 1.5.4.RELEASE
+ 1.5.10.RELEASE
+
@@ -73,5 +67,9 @@
+
+ UTF-8
+ Custom Property Value
+
diff --git a/spring-boot-property-exp/property-exp-default-config/pom.xml b/spring-boot-property-exp/property-exp-default-config/pom.xml
index 0625916d32..5dc47d287d 100644
--- a/spring-boot-property-exp/property-exp-default-config/pom.xml
+++ b/spring-boot-property-exp/property-exp-default-config/pom.xml
@@ -1,27 +1,17 @@
-
-
+
4.0.0
-
-
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.4.RELEASE
-
-
+ property-exp-default
+
com.baeldung
property-exp-default-config
0.0.1-SNAPSHOT
jar
- property-exp-default
- http://maven.apache.org
-
-
- UTF-8
- Custom Property Value
-
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 1.5.10.RELEASE
+
@@ -42,4 +32,9 @@
+
+ UTF-8
+ Custom Property Value
+
+
diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java
index f164af89e6..58e6d5d5b8 100644
--- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java
+++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/main/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathController.java
@@ -16,7 +16,7 @@ public class BasicMathController {
private RestTemplate restTemplate;
@GetMapping("/calculate")
- public String checkOddAndEven(@RequestParam("number") String number) {
+ public String checkOddAndEven(@RequestParam("number") Integer number) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Type", "application/json");
diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java
index e61cc1120c..b8cc002fb4 100644
--- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java
+++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/src/main/java/com/baeldung/spring/cloud/springcloudcontractproducer/controller/EvenOddController.java
@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.RestController;
public class EvenOddController {
@GetMapping("/validate/prime-number")
- public String isNumberPrime(@RequestParam("number") String number) {
- return Integer.parseInt(number) % 2 == 0 ? "Even" : "Odd";
+ public String isNumberPrime(@RequestParam("number") Integer number) {
+ return number % 2 == 0 ? "Even" : "Odd";
}
}
diff --git a/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java
index b6bfd0bcf6..c77a5e02c5 100644
--- a/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java
+++ b/spring-cloud/spring-cloud-security/auth-client/src/main/java/com/baeldung/controller/CloudSiteController.java
@@ -19,10 +19,10 @@ public class CloudSiteController {
return "Hello From Baeldung!";
}
- @GetMapping("/person")
+ @GetMapping("/personInfo")
public ModelAndView person() {
ModelAndView mav = new ModelAndView("personinfo");
- String personResourceUrl = "http://localhost:9000/personResource";
+ String personResourceUrl = "http://localhost:9000/person";
mav.addObject("person", restOperations.getForObject(personResourceUrl, String.class));
return mav;
}
diff --git a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml
index 06a950d270..2a758faeae 100644
--- a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml
+++ b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml
@@ -13,7 +13,7 @@ security:
clientId: authserver
clientSecret: passwordforauthserver
resource:
- userInfoUri: http://localhost:7070/authserver/user
+ userInfoUri: http://localhost:9000/user
person:
url: http://localhost:9000/person
@@ -27,7 +27,7 @@ zuul:
url: http://localhost:9000
user:
path: /user/**
- url: http://localhost:7070/authserver/user
+ url: http://localhost:9000/user
# Make sure the OAuth2 token is only relayed when using the internal API,
# do not pass any authentication to the external API
diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java
index 9e5420da5a..1958c0ebb8 100644
--- a/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java
+++ b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/PersonInfoController.java
@@ -10,9 +10,9 @@ import com.baeldung.model.Person;
@RestController
public class PersonInfoController {
- @GetMapping("/personResource")
+ @GetMapping("/person")
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public @ResponseBody Person personInfo() {
return new Person("abir", "Dhaka", "Bangladesh", 29, "Male");
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/controller/ResourceController.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/ResourceController.java
similarity index 100%
rename from spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/controller/ResourceController.java
rename to spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/controller/ResourceController.java
diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml
index 20a3313a60..52e02ba41b 100644
--- a/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml
+++ b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml
@@ -8,7 +8,6 @@ security:
sessions: NEVER
oauth2:
resource:
- userInfoUri: http://localhost:7070/authserver/user
jwt:
keyValue: |
-----BEGIN PUBLIC KEY-----
diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/ResourceServerConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/ResourceServerConfigurer.java
deleted file mode 100644
index f97544dc59..0000000000
--- a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/ResourceServerConfigurer.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.baeldung.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
-import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
-
-/**
- * Our configuration for the OAuth2 User Info Resource Server.
- */
-@Configuration
-@EnableResourceServer
-public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
- @Override
- public void configure(HttpSecurity http) throws Exception {
- http.antMatcher("/user")
- .authorizeRequests()
- .anyRequest()
- .authenticated();
- }
-}
diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student.java
deleted file mode 100644
index 9bd218c332..0000000000
--- a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.baeldung.dependencyinjectiontypes;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Student {
-
- private TeacherFinder teacherFinder;
-
- @Autowired
- public Student(TeacherFinder teacherFinder) {
- this.teacherFinder = teacherFinder;
- }
-
- public String getTeacher() {
- return teacherFinder.getTeacherFinder();
- }
- // business logic that actually uses the injected teacherFinders is omitted...
-}
-
diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student2.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student2.java
deleted file mode 100644
index e6724d82ec..0000000000
--- a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/Student2.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.baeldung.dependencyinjectiontypes;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class Student2 {
-
- private TeacherFinder teacherFinder;
-
- @Autowired
- public void setTeacherFinder(TeacherFinder teacherFinder) {
- this.teacherFinder = teacherFinder;
- }
-
- public String getTeacher() {
- return teacherFinder.getTeacherFinder();
- }
-
-}
\ No newline at end of file
diff --git a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TeacherFinder.java b/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TeacherFinder.java
deleted file mode 100644
index b349dc19d0..0000000000
--- a/spring-core/src/main/java/com/baeldung/dependencyinjectiontypes/TeacherFinder.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.baeldung.dependencyinjectiontypes;
-public class TeacherFinder {
-
- private String teacherFinder;
-
- public String getTeacherFinder() {
- return teacherFinder;
- }
-
- public void setTeacherFinder(String teacherFinder) {
- this.teacherFinder = teacherFinder;
- }
-
-
-}
-
diff --git a/spring-core/src/main/java/com/baeldung/setterdi/Config.java b/spring-core/src/main/java/com/baeldung/setterdi/Config.java
index d61510971c..68c1ae12a2 100644
--- a/spring-core/src/main/java/com/baeldung/setterdi/Config.java
+++ b/spring-core/src/main/java/com/baeldung/setterdi/Config.java
@@ -1,58 +1,35 @@
-package com.baeldung.setterdi;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-import com.baeldung.dependencyinjectiontypes.Student;
-import com.baeldung.dependencyinjectiontypes.Student2;
-import com.baeldung.dependencyinjectiontypes.TeacherFinder;
-import com.baeldung.setterdi.domain.Engine;
-import com.baeldung.setterdi.domain.Trailer;
-import com.baeldung.setterdi.domain.Transmission;
-
-@Configuration
-@ComponentScan("com.baeldung.setterdi")
-public class Config {
-
- @Bean
- public Engine engine() {
- Engine engine = new Engine();
- engine.setType("v8");
- engine.setVolume(5);
- return engine;
- }
-
- @Bean
- public Transmission transmission() {
- Transmission transmission = new Transmission();
- transmission.setType("sliding");
- return transmission;
- }
-
- @Bean
- public Trailer trailer() {
- Trailer trailer = new Trailer();
- return trailer;
- }
-
- @Bean
- public TeacherFinder teacherFinder(){
- TeacherFinder teacherFinder =new TeacherFinder();
- teacherFinder.setTeacherFinder("author");
- return teacherFinder;
- }
-
- @Bean
- public Student student() {
- return new Student(teacherFinder());
- }
-
- @Bean
- public Student2 student2() {
- Student2 student2 = new Student2();
- student2.setTeacherFinder(teacherFinder());
- return student2;
- }
-
+package com.baeldung.setterdi;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+import com.baeldung.setterdi.domain.Engine;
+import com.baeldung.setterdi.domain.Trailer;
+import com.baeldung.setterdi.domain.Transmission;
+
+@Configuration
+@ComponentScan("com.baeldung.setterdi")
+public class Config {
+
+ @Bean
+ public Engine engine() {
+ Engine engine = new Engine();
+ engine.setType("v8");
+ engine.setVolume(5);
+ return engine;
+ }
+
+ @Bean
+ public Transmission transmission() {
+ Transmission transmission = new Transmission();
+ transmission.setType("sliding");
+ return transmission;
+ }
+
+ @Bean
+ public Trailer trailer() {
+ Trailer trailer = new Trailer();
+ return trailer;
+ }
}
\ No newline at end of file
diff --git a/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java b/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java
index 7ec477d2e2..57c1927e58 100644
--- a/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java
+++ b/spring-core/src/test/java/com/baeldung/dependencyinjectiontypes/DependencyInjectionTest.java
@@ -2,25 +2,13 @@ package com.baeldung.dependencyinjectiontypes;
import static org.junit.Assert.assertTrue;
-import org.apache.log4j.Logger;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.support.AnnotationConfigContextLoader;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes=com.baeldung.setterdi.Config.class, loader=AnnotationConfigContextLoader.class)
public class DependencyInjectionTest {
-
- @Autowired
- private ApplicationContext appContext;
-
- Logger logger = Logger.getLogger(this.getClass());
- /* @Test
+ @Test
public void givenAutowiredAnnotation_WhenSetOnSetter_ThenDependencyValid() {
ApplicationContext context = new ClassPathXmlApplicationContext("dependencyinjectiontypes-context.xml");
@@ -42,20 +30,6 @@ public class DependencyInjectionTest {
String formattedArticle = article.format(originalText);
assertTrue(originalText.toUpperCase().equals(formattedArticle));
- }*/
-
- @Test
- public void givenAutowiredAnnotation_OnSetter_ThenDependencyValid() {
- Student student = (Student) appContext.getBean("student");
- String teacherFound = student.getTeacher();
- assertTrue(teacherFound.equals("author"));
- }
-
- @Test
- public void givenAutowiredAnnotation_OnConstructor_ThenDependencyValid() {
- Student2 student2 = (Student2) appContext.getBean("student2");
- String teacherFound = student2.getTeacher();
- assertTrue(teacherFound.equals("author"));
}
}
diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml
index f42fc5c2e2..b7b898237f 100644
--- a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml
+++ b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml
@@ -9,7 +9,7 @@
org.springframework.boot
spring-boot-starter-parent
- 1.5.6.RELEASE
+ 1.5.10.RELEASE
diff --git a/vavr/pom.xml b/vavr/pom.xml
index f9fed7d4fc..28747af3ee 100644
--- a/vavr/pom.xml
+++ b/vavr/pom.xml
@@ -1,17 +1,15 @@
-
+
4.0.0
com.baeldung
vavr
1.0
vavr
-
- org.springframework.boot
- spring-boot-starter-parent
- 1.5.6.RELEASE
-
-
+
+ parent-boot-5
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-5
@@ -21,12 +19,6 @@
${vavr.version}
-
- junit
- junit
- ${junit.version}
-
-
org.springframework.boot
spring-boot-starter-data-jpa
@@ -42,15 +34,15 @@
spring-boot-starter-test
test
-
+
- org.awaitility
- awaitility
- ${awaitility.version}
- test
-
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
-
+
spring-snapshot
@@ -66,20 +58,13 @@
https://repo.spring.io/libs-snapshot
-
-
+
+
spring-snapshots
http://repo.spring.io/snapshot
-
-
- 1.8
- 0.9.1
- 4.12
- 3.0.0
-
@@ -97,10 +82,16 @@
**/JdbcTest.java
**/*LiveTest.java
-
+
+ 1.8
+ 0.9.1
+ 4.12
+ 3.0.0
+
+
\ No newline at end of file