Merge branch 'master' into feature/ktln-43/working-with-lists-in-kotlin
This commit is contained in:
commit
18fe351a21
|
@ -15,9 +15,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
||||||
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
||||||
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
||||||
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
||||||
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
|
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6)
|
||||||
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
|
||||||
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
|
||||||
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
|
||||||
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)
|
|
||||||
|
|
|
@ -25,12 +25,6 @@
|
||||||
<artifactId>commons-math3</artifactId>
|
<artifactId>commons-math3</artifactId>
|
||||||
<version>${commons-math3.version}</version>
|
<version>${commons-math3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>${lombok.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.allegro.finance</groupId>
|
<groupId>pl.allegro.finance</groupId>
|
||||||
<artifactId>tradukisto</artifactId>
|
<artifactId>tradukisto</artifactId>
|
||||||
|
|
|
@ -2,3 +2,9 @@
|
||||||
|
|
||||||
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
|
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
|
||||||
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
||||||
|
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
|
||||||
|
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
||||||
|
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
||||||
|
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
||||||
|
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
||||||
|
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
|
||||||
|
|
|
@ -18,10 +18,35 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-commons</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${org.assertj.core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-math3</artifactId>
|
||||||
|
<version>${commons-math3.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<guava.version>28.1-jre</guava.version>
|
<guava.version>28.1-jre</guava.version>
|
||||||
|
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||||
|
<junit.platform.version>1.6.0</junit.platform.version>
|
||||||
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This module contains articles about Apache CXF
|
This module contains articles about Apache CXF
|
||||||
|
|
||||||
## Relevant Articles:
|
## Relevant Articles:
|
||||||
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
|
||||||
- [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api)
|
- [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api)
|
||||||
- [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring)
|
- [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring)
|
||||||
- [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf)
|
- [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-1</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../parent-boot-1</relativePath>
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.*;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||||
|
import org.apache.shiro.authc.LockedAccountException;
|
||||||
|
import org.apache.shiro.authc.UnknownAccountException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
import org.apache.shiro.realm.Realm;
|
import org.apache.shiro.realm.Realm;
|
||||||
import org.apache.shiro.realm.text.IniRealm;
|
|
||||||
import org.apache.shiro.session.Session;
|
import org.apache.shiro.session.Session;
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
package com.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.apache.shiro.authc.*;
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.AuthenticationInfo;
|
||||||
|
import org.apache.shiro.authc.AuthenticationToken;
|
||||||
|
import org.apache.shiro.authc.SimpleAuthenticationInfo;
|
||||||
|
import org.apache.shiro.authc.UnknownAccountException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
import org.apache.shiro.authz.AuthorizationInfo;
|
import org.apache.shiro.authz.AuthorizationInfo;
|
||||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||||
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
import org.apache.shiro.realm.jdbc.JdbcRealm;
|
||||||
import org.apache.shiro.subject.PrincipalCollection;
|
import org.apache.shiro.subject.PrincipalCollection;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class MyCustomRealm extends JdbcRealm {
|
public class MyCustomRealm extends JdbcRealm {
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package com.baeldung.shiro.permissions.custom;
|
package com.baeldung.shiro.permissions.custom;
|
||||||
|
|
||||||
import com.baeldung.MyCustomRealm;
|
|
||||||
import org.apache.shiro.SecurityUtils;
|
import org.apache.shiro.SecurityUtils;
|
||||||
import org.apache.shiro.authc.*;
|
import org.apache.shiro.authc.AuthenticationException;
|
||||||
|
import org.apache.shiro.authc.IncorrectCredentialsException;
|
||||||
|
import org.apache.shiro.authc.LockedAccountException;
|
||||||
|
import org.apache.shiro.authc.UnknownAccountException;
|
||||||
|
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||||
import org.apache.shiro.config.Ini;
|
import org.apache.shiro.config.Ini;
|
||||||
import org.apache.shiro.mgt.DefaultSecurityManager;
|
import org.apache.shiro.mgt.DefaultSecurityManager;
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
import org.apache.shiro.realm.Realm;
|
|
||||||
import org.apache.shiro.realm.text.IniRealm;
|
import org.apache.shiro.realm.text.IniRealm;
|
||||||
import org.apache.shiro.session.Session;
|
|
||||||
import org.apache.shiro.subject.Subject;
|
import org.apache.shiro.subject.Subject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
## Atomikos
|
## Atomikos
|
||||||
|
|
||||||
This module contains articles about Atomikos
|
This module contains articles about Atomikos
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Guide Transactions Using Atomikos]()
|
- [A Guide to Atomikos](https://www.baeldung.com/java-atomikos)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [AWS AppSync With Spring Boot](https://www.baeldung.com/aws-appsync-spring)
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.2.6.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>aws-app-sync</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>aws-app-sync</name>
|
||||||
|
|
||||||
|
<description>Spring Boot using AWS App Sync</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.junit.vintage</groupId>
|
||||||
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.awsappsync;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.reactive.function.BodyInserters;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AppSyncClientHelper {
|
||||||
|
|
||||||
|
static String apiUrl = "<INSERT API URL HERE>";
|
||||||
|
static String apiKey = "<INSERT API KEY HERE>";
|
||||||
|
static String API_KEY_HEADER = "x-api-key";
|
||||||
|
|
||||||
|
public static WebClient.ResponseSpec getResponseBodySpec(Map<String, Object> requestBody) {
|
||||||
|
return WebClient
|
||||||
|
.builder()
|
||||||
|
.baseUrl(apiUrl)
|
||||||
|
.defaultHeader(API_KEY_HEADER, apiKey)
|
||||||
|
.defaultHeader("Content-Type", "application/json")
|
||||||
|
.build()
|
||||||
|
.method(HttpMethod.POST)
|
||||||
|
.uri("/graphql")
|
||||||
|
.body(BodyInserters.fromValue(requestBody))
|
||||||
|
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
|
||||||
|
.acceptCharset(StandardCharsets.UTF_8)
|
||||||
|
.retrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.awsappsync;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class AwsAppSyncApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AwsAppSyncApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.baeldung.awsappsync;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@Disabled
|
||||||
|
class AwsAppSyncApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenGraphQuery_whenListEvents_thenReturnAllEvents() {
|
||||||
|
|
||||||
|
Map<String, Object> requestBody = new HashMap<>();
|
||||||
|
requestBody.put("query", "query ListEvents {"
|
||||||
|
+ " listEvents {"
|
||||||
|
+ " items {"
|
||||||
|
+ " id"
|
||||||
|
+ " name"
|
||||||
|
+ " where"
|
||||||
|
+ " when"
|
||||||
|
+ " description"
|
||||||
|
+ " }"
|
||||||
|
+ " }"
|
||||||
|
+ "}");
|
||||||
|
requestBody.put("variables", "");
|
||||||
|
requestBody.put("operationName", "ListEvents");
|
||||||
|
|
||||||
|
String bodyString = AppSyncClientHelper.getResponseBodySpec(requestBody)
|
||||||
|
.bodyToMono(String.class).block();
|
||||||
|
|
||||||
|
assertNotNull(bodyString);
|
||||||
|
assertTrue(bodyString.contains("My First Event"));
|
||||||
|
assertTrue(bodyString.contains("where"));
|
||||||
|
assertTrue(bodyString.contains("when"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenGraphAdd_whenMutation_thenReturnIdNameDesc() {
|
||||||
|
|
||||||
|
String queryString = "mutation add {"
|
||||||
|
+ " createEvent("
|
||||||
|
+ " name:\"My added GraphQL event\""
|
||||||
|
+ " where:\"Day 2\""
|
||||||
|
+ " when:\"Saturday night\""
|
||||||
|
+ " description:\"Studying GraphQL\""
|
||||||
|
+ " ){"
|
||||||
|
+ " id"
|
||||||
|
+ " name"
|
||||||
|
+ " description"
|
||||||
|
+ " }"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
Map<String, Object> requestBody = new HashMap<>();
|
||||||
|
requestBody.put("query", queryString);
|
||||||
|
requestBody.put("variables", "");
|
||||||
|
requestBody.put("operationName", "add");
|
||||||
|
|
||||||
|
WebClient.ResponseSpec response = AppSyncClientHelper.getResponseBodySpec(requestBody);
|
||||||
|
|
||||||
|
String bodyString = response.bodyToMono(String.class).block();
|
||||||
|
|
||||||
|
assertNotNull(bodyString);
|
||||||
|
assertTrue(bodyString.contains("My added GraphQL event"));
|
||||||
|
assertFalse(bodyString.contains("where"));
|
||||||
|
assertFalse(bodyString.contains("when"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
### Relevant Articles:
|
|
||||||
|
|
||||||
- [Building Java Applications with Bazel](https://www.baeldung.com/bazel-build-tool)
|
|
|
@ -16,10 +16,6 @@
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
|
@ -13,4 +13,5 @@ This module contains articles about core Groovy concepts
|
||||||
- [Metaprogramming in Groovy](https://www.baeldung.com/groovy-metaprogramming)
|
- [Metaprogramming in Groovy](https://www.baeldung.com/groovy-metaprogramming)
|
||||||
- [A Quick Guide to Working with Web Services in Groovy](https://www.baeldung.com/groovy-web-services)
|
- [A Quick Guide to Working with Web Services in Groovy](https://www.baeldung.com/groovy-web-services)
|
||||||
- [Categories in Groovy](https://www.baeldung.com/groovy-categories)
|
- [Categories in Groovy](https://www.baeldung.com/groovy-categories)
|
||||||
|
- [How to Determine the Data Type in Groovy](https://www.baeldung.com/groovy-determine-data-type)
|
||||||
- [[<-- Prev]](/core-groovy)
|
- [[<-- Prev]](/core-groovy)
|
||||||
|
|
|
@ -12,4 +12,5 @@ This module contains articles about core Groovy concepts
|
||||||
- [Closures in Groovy](https://www.baeldung.com/groovy-closures)
|
- [Closures in Groovy](https://www.baeldung.com/groovy-closures)
|
||||||
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
- [Converting a String to a Date in Groovy](https://www.baeldung.com/groovy-string-to-date)
|
||||||
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
- [Guide to I/O in Groovy](https://www.baeldung.com/groovy-io)
|
||||||
|
- [Convert String to Integer in Groovy](https://www.baeldung.com/groovy-convert-string-to-integer)
|
||||||
- [[More -->]](/core-groovy-2)
|
- [[More -->]](/core-groovy-2)
|
|
@ -8,3 +8,4 @@ This module contains articles about Java 14.
|
||||||
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
- [Java Text Blocks](https://www.baeldung.com/java-text-blocks)
|
||||||
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
- [Pattern Matching for instanceof in Java 14](https://www.baeldung.com/java-pattern-matching-instanceof)
|
||||||
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
- [Helpful NullPointerExceptions in Java 14](https://www.baeldung.com/java-14-nullpointerexception)
|
||||||
|
- [Foreign Memory Access API in Java 14](https://www.baeldung.com/java-foreign-memory-access)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.java14.record;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record Person (String name, String address) {
|
||||||
|
|
||||||
|
public static String UNKWOWN_ADDRESS = "Unknown";
|
||||||
|
public static String UNNAMED = "Unnamed";
|
||||||
|
|
||||||
|
public Person {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
Objects.requireNonNull(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(String name) {
|
||||||
|
this(name, UNKWOWN_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Person unnamed(String address) {
|
||||||
|
return new Person(UNNAMED, address);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.baeldung.java14.foreign.api;
|
||||||
|
|
||||||
|
import jdk.incubator.foreign.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.lang.invoke.VarHandle;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public class ForeignMemoryUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAValueIsSet_thenAccessTheValue() {
|
||||||
|
long value = 10;
|
||||||
|
MemoryAddress memoryAddress =
|
||||||
|
MemorySegment.allocateNative(8).baseAddress();
|
||||||
|
VarHandle varHandle = MemoryHandles.varHandle(long.class,
|
||||||
|
ByteOrder.nativeOrder());
|
||||||
|
varHandle.set(memoryAddress, value);
|
||||||
|
assertThat(varHandle.get(memoryAddress), is(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMultipleValuesAreSet_thenAccessAll() {
|
||||||
|
VarHandle varHandle = MemoryHandles.varHandle(int.class,
|
||||||
|
ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
try(MemorySegment memorySegment =
|
||||||
|
MemorySegment.allocateNative(100)) {
|
||||||
|
MemoryAddress base = memorySegment.baseAddress();
|
||||||
|
for(int i=0; i<25; i++) {
|
||||||
|
varHandle.set(base.addOffset((i*4)), i);
|
||||||
|
}
|
||||||
|
for(int i=0; i<25; i++) {
|
||||||
|
assertThat(varHandle.get(base.addOffset((i*4))), is(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSetValuesWithMemoryLayout_thenTheyCanBeRetrieved() {
|
||||||
|
SequenceLayout sequenceLayout =
|
||||||
|
MemoryLayout.ofSequence(25,
|
||||||
|
MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder()));
|
||||||
|
VarHandle varHandle =
|
||||||
|
sequenceLayout.varHandle(long.class,
|
||||||
|
MemoryLayout.PathElement.sequenceElement());
|
||||||
|
|
||||||
|
try(MemorySegment memorySegment =
|
||||||
|
MemorySegment.allocateNative(sequenceLayout)) {
|
||||||
|
MemoryAddress base = memorySegment.baseAddress();
|
||||||
|
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||||
|
varHandle.set(base, i, i);
|
||||||
|
}
|
||||||
|
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||||
|
assertThat(varHandle.get(base, i), is(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSlicingMemorySegment_thenTheyCanBeAccessedIndividually() {
|
||||||
|
MemoryAddress memoryAddress =
|
||||||
|
MemorySegment.allocateNative(12).baseAddress();
|
||||||
|
MemoryAddress memoryAddress1 =
|
||||||
|
memoryAddress.segment().asSlice(0,4).baseAddress();
|
||||||
|
MemoryAddress memoryAddress2 =
|
||||||
|
memoryAddress.segment().asSlice(4,4).baseAddress();
|
||||||
|
MemoryAddress memoryAddress3 =
|
||||||
|
memoryAddress.segment().asSlice(8,4).baseAddress();
|
||||||
|
|
||||||
|
VarHandle intHandle =
|
||||||
|
MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
|
||||||
|
intHandle.set(memoryAddress1, Integer.MIN_VALUE);
|
||||||
|
intHandle.set(memoryAddress2, 0);
|
||||||
|
intHandle.set(memoryAddress3, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
assertThat(intHandle.get(memoryAddress1), is(Integer.MIN_VALUE));
|
||||||
|
assertThat(intHandle.get(memoryAddress2), is(0));
|
||||||
|
assertThat(intHandle.get(memoryAddress3), is(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package com.baeldung.java14.record;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PersonTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, address);
|
||||||
|
Person person2 = new Person(name, address);
|
||||||
|
|
||||||
|
assertTrue(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentObject_whenEquals_thenNotEqual() {
|
||||||
|
|
||||||
|
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||||
|
|
||||||
|
assertFalse(person.equals(new Object()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentName_whenEquals_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person("Jane Doe", address);
|
||||||
|
Person person2 = new Person("John Doe", address);
|
||||||
|
|
||||||
|
assertFalse(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, "100 Linda Ln.");
|
||||||
|
Person person2 = new Person(name, "200 London Ave.");
|
||||||
|
|
||||||
|
assertFalse(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, address);
|
||||||
|
Person person2 = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentObject_whenHashCode_thenNotEqual() {
|
||||||
|
|
||||||
|
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||||
|
|
||||||
|
assertNotEquals(person.hashCode(), new Object().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentName_whenHashCode_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person("Jane Doe", address);
|
||||||
|
Person person2 = new Person("John Doe", address);
|
||||||
|
|
||||||
|
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, "100 Linda Ln.");
|
||||||
|
Person person2 = new Person(name, "200 London Ave.");
|
||||||
|
|
||||||
|
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals(name, person.name());
|
||||||
|
assertEquals(address, person.address());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void givenNullName_whenConstruct_thenErrorThrown() {
|
||||||
|
new Person(null, "100 Linda Ln.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void givenNullAddress_whenConstruct_thenErrorThrown() {
|
||||||
|
new Person("John Doe", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnknownAddress_whenConstructing_thenAddressPopulated() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person = new Person(name);
|
||||||
|
|
||||||
|
assertEquals(name, person.name());
|
||||||
|
assertEquals(Person.UNKWOWN_ADDRESS, person.address());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = Person.unnamed(address);
|
||||||
|
|
||||||
|
assertEquals(Person.UNNAMED, person.name());
|
||||||
|
assertEquals(address, person.address());
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-8-2</name>
|
<name>core-java-8-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
<name>core-java-8-datetime</name>
|
<name>core-java-8-datetime</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.parent.version}</version>
|
||||||
<name>core-java-8-datetime</name>
|
<name>core-java-8-datetime</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-8</name>
|
<name>core-java-8</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -9,3 +9,4 @@ This module contains articles about the improvements to core Java features intro
|
||||||
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
- [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api)
|
||||||
- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new)
|
- [Java 9 java.util.Objects Additions](https://www.baeldung.com/java-9-objects-new)
|
||||||
- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture)
|
- [Java 9 CompletableFuture API Improvements](https://www.baeldung.com/java-9-completablefuture)
|
||||||
|
- [Java InputStream to Byte Array and ByteBuffer](https://www.baeldung.com/convert-input-stream-to-array-of-bytes)
|
||||||
|
|
|
@ -33,6 +33,11 @@
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons-io.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.platform</groupId>
|
<groupId>org.junit.platform</groupId>
|
||||||
<artifactId>junit-platform-runner</artifactId>
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.java9.io.conversion;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteSource;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
|
||||||
|
public class InputStreamToByteArrayUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenUsingPlainJavaOnFixedSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||||
|
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||||
|
final byte[] targetArray = new byte[initialStream.available()];
|
||||||
|
initialStream.read(targetArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenUsingPlainJavaOnUnknownSizeStream_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||||
|
final InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||||
|
|
||||||
|
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
int nRead;
|
||||||
|
final byte[] data = new byte[1024];
|
||||||
|
while ((nRead = is.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.flush();
|
||||||
|
final byte[] byteArray = buffer.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUsingPlainJava9_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||||
|
final InputStream is = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||||
|
|
||||||
|
byte[] data = is.readAllBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenUsingGuava_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||||
|
final InputStream initialStream = ByteSource.wrap(new byte[] { 0, 1, 2 })
|
||||||
|
.openStream();
|
||||||
|
final byte[] targetArray = ByteStreams.toByteArray(initialStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void givenUsingCommonsIO_whenConvertingAnInputStreamToAByteArray_thenCorrect() throws IOException {
|
||||||
|
final InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||||
|
final byte[] targetArray = IOUtils.toByteArray(initialStream);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.baeldung.inputstreamtobytes;
|
package com.baeldung.java9.io.conversion;
|
||||||
|
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
|
@ -12,3 +12,4 @@ This module contains articles about core Java features that have been introduced
|
||||||
- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api)
|
- [Introduction to Java 9 StackWalking API](https://www.baeldung.com/java-9-stackwalking-api)
|
||||||
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
- [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api)
|
||||||
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
|
- [Java 9 Reactive Streams](https://www.baeldung.com/java-9-reactive-streams)
|
||||||
|
- [Multi-Release JAR Files with Maven](https://www.baeldung.com/maven-multi-release-jars)
|
||||||
|
|
|
@ -28,8 +28,104 @@
|
||||||
<version>${junit.platform.version}</version>
|
<version>${junit.platform.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.awaitility</groupId>
|
||||||
|
<artifactId>awaitility</artifactId>
|
||||||
|
<version>${awaitility.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>incubator-features</id>
|
||||||
|
<build>
|
||||||
|
<finalName>core-java-9-new-features</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${maven.compiler.source}</source>
|
||||||
|
<target>${maven.compiler.target}</target>
|
||||||
|
<compilerArgument>--add-modules=jdk.incubator.httpclient</compilerArgument>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<argLine>--add-modules=jdk.incubator.httpclient</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>mrjar-generation</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile-java-8</id>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<compileSourceRoots>
|
||||||
|
<compileSourceRoot>${project.basedir}/src/main/java8</compileSourceRoot>
|
||||||
|
</compileSourceRoots>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>compile-java-9</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<release>9</release>
|
||||||
|
<compileSourceRoots>
|
||||||
|
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
|
||||||
|
</compileSourceRoots>
|
||||||
|
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/9</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>default-testCompile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>testCompile</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>${maven-jar-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestEntries>
|
||||||
|
<Multi-Release>true</Multi-Release>
|
||||||
|
</manifestEntries>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.baeldung.multireleaseapp.App</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
<build>
|
<build>
|
||||||
<finalName>core-java-9-new-features</finalName>
|
<finalName>core-java-9-new-features</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -56,8 +152,10 @@
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj.version>3.10.0</assertj.version>
|
<assertj.version>3.10.0</assertj.version>
|
||||||
<junit.platform.version>1.2.0</junit.platform.version>
|
<junit.platform.version>1.2.0</junit.platform.version>
|
||||||
|
<awaitility.version>4.0.2</awaitility.version>
|
||||||
<maven.compiler.source>1.9</maven.compiler.source>
|
<maven.compiler.source>1.9</maven.compiler.source>
|
||||||
<maven.compiler.target>1.9</maven.compiler.target>
|
<maven.compiler.target>1.9</maven.compiler.target>
|
||||||
|
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.multireleaseapp;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
logger.info(String.format("Running on %s", new DefaultVersion().version()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.multireleaseapp;
|
||||||
|
|
||||||
|
public class DefaultVersion implements Version {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String version() {
|
||||||
|
return System.getProperty("java.version");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.multireleaseapp;
|
||||||
|
|
||||||
|
interface Version {
|
||||||
|
public String version();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.multireleaseapp;
|
||||||
|
|
||||||
|
public class DefaultVersion implements Version {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String version() {
|
||||||
|
return Runtime.version().toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ import static org.junit.Assert.assertThat;
|
||||||
/**
|
/**
|
||||||
* Created by adam.
|
* Created by adam.
|
||||||
*/
|
*/
|
||||||
public class HttpClientTest {
|
public class HttpClientIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException {
|
public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException {
|
||||||
|
@ -55,7 +55,7 @@ public class HttpClientTest {
|
||||||
.send(request, HttpResponse.BodyHandler.asString());
|
.send(request, HttpResponse.BodyHandler.asString());
|
||||||
|
|
||||||
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_MOVED_PERM));
|
assertThat(response.statusCode(), equalTo(HttpURLConnection.HTTP_MOVED_PERM));
|
||||||
assertThat(response.body(), containsString("https://stackoverflow.com/"));
|
assertThat(response.body(), containsString(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
|
@ -22,7 +22,7 @@ import static org.junit.Assert.assertThat;
|
||||||
/**
|
/**
|
||||||
* Created by adam.
|
* Created by adam.
|
||||||
*/
|
*/
|
||||||
public class HttpRequestTest {
|
public class HttpRequestIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
|
@ -18,7 +18,7 @@ import static org.junit.Assert.assertThat;
|
||||||
/**
|
/**
|
||||||
* Created by adam.
|
* Created by adam.
|
||||||
*/
|
*/
|
||||||
public class HttpResponseTest {
|
public class HttpResponseIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException {
|
|
@ -5,10 +5,12 @@ import org.junit.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.SubmissionPublisher;
|
import java.util.concurrent.SubmissionPublisher;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
public class ReactiveStreamsTest {
|
public class ReactiveStreamsUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenPublisher_whenSubscribeToIt_thenShouldConsumeAllElements() throws InterruptedException {
|
public void givenPublisher_whenSubscribeToIt_thenShouldConsumeAllElements() throws InterruptedException {
|
||||||
|
@ -25,7 +27,7 @@ public class ReactiveStreamsTest {
|
||||||
|
|
||||||
//then
|
//then
|
||||||
|
|
||||||
await().atMost(1000, TimeUnit.MILLISECONDS).until(
|
await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
|
||||||
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(items)
|
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(items)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ public class ReactiveStreamsTest {
|
||||||
publisher.close();
|
publisher.close();
|
||||||
|
|
||||||
//then
|
//then
|
||||||
await().atMost(1000, TimeUnit.MILLISECONDS).until(
|
await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
|
||||||
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expectedResult)
|
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expectedResult)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +68,7 @@ public class ReactiveStreamsTest {
|
||||||
publisher.close();
|
publisher.close();
|
||||||
|
|
||||||
//then
|
//then
|
||||||
await().atMost(1000, TimeUnit.MILLISECONDS).until(
|
await().atMost(1000, TimeUnit.MILLISECONDS).untilAsserted(
|
||||||
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expected)
|
() -> assertThat(subscriber.consumedElements).containsExactlyElementsOf(expected)
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ import java.lang.invoke.VarHandle;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
public class VariableHandlesTest {
|
public class VariableHandlesUnitTest {
|
||||||
|
|
||||||
public int publicTestVariable = 1;
|
public int publicTestVariable = 1;
|
||||||
private int privateTestVariable = 1;
|
private int privateTestVariable = 1;
|
||||||
|
@ -20,22 +20,22 @@ public class VariableHandlesTest {
|
||||||
public void whenVariableHandleForPublicVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
public void whenVariableHandleForPublicVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "publicTestVariable", int.class);
|
||||||
|
|
||||||
assertThat(publicIntHandle.coordinateTypes().size() == 1);
|
assertThat(publicIntHandle.coordinateTypes().size() == 1);
|
||||||
assertThat(publicIntHandle.coordinateTypes().get(0) == VariableHandles.class);
|
assertThat(publicIntHandle.coordinateTypes().get(0) == VariableHandlesUnitTest.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenVariableHandleForPrivateVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
public void whenVariableHandleForPrivateVariableIsCreated_ThenItIsInitializedProperly() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle privateIntHandle = MethodHandles
|
VarHandle privateIntHandle = MethodHandles
|
||||||
.privateLookupIn(VariableHandlesTest.class, MethodHandles.lookup())
|
.privateLookupIn(VariableHandlesUnitTest.class, MethodHandles.lookup())
|
||||||
.findVarHandle(VariableHandlesTest.class, "privateTestVariable", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "privateTestVariable", int.class);
|
||||||
|
|
||||||
assertThat(privateIntHandle.coordinateTypes().size() == 1);
|
assertThat(privateIntHandle.coordinateTypes().size() == 1);
|
||||||
assertThat(privateIntHandle.coordinateTypes().get(0) == VariableHandlesTest.class);
|
assertThat(privateIntHandle.coordinateTypes().get(0) == VariableHandlesUnitTest.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ public class VariableHandlesTest {
|
||||||
public void givenVarHandle_whenGetIsInvoked_ThenValueOfVariableIsReturned() throws NoSuchFieldException, IllegalAccessException {
|
public void givenVarHandle_whenGetIsInvoked_ThenValueOfVariableIsReturned() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "publicTestVariable", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "publicTestVariable", int.class);
|
||||||
|
|
||||||
assertThat((int) publicIntHandle.get(this) == 1);
|
assertThat((int) publicIntHandle.get(this) == 1);
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@ public class VariableHandlesTest {
|
||||||
public void givenVarHandle_whenSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
public void givenVarHandle_whenSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "variableToSet", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "variableToSet", int.class);
|
||||||
publicIntHandle.set(this, 15);
|
publicIntHandle.set(this, 15);
|
||||||
|
|
||||||
assertThat((int) publicIntHandle.get(this) == 15);
|
assertThat((int) publicIntHandle.get(this) == 15);
|
||||||
|
@ -73,8 +73,8 @@ public class VariableHandlesTest {
|
||||||
public void givenVarHandle_whenCompareAndSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
public void givenVarHandle_whenCompareAndSetIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "variableToCompareAndSet", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "variableToCompareAndSet", int.class);
|
||||||
publicIntHandle.compareAndSet(this, 1, 100);
|
publicIntHandle.compareAndSet(this, 1, 100);
|
||||||
|
|
||||||
assertThat((int) publicIntHandle.get(this) == 100);
|
assertThat((int) publicIntHandle.get(this) == 100);
|
||||||
|
@ -84,8 +84,8 @@ public class VariableHandlesTest {
|
||||||
public void givenVarHandle_whenGetAndAddIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
public void givenVarHandle_whenGetAndAddIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "variableToGetAndAdd", int.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "variableToGetAndAdd", int.class);
|
||||||
int before = (int) publicIntHandle.getAndAdd(this, 200);
|
int before = (int) publicIntHandle.getAndAdd(this, 200);
|
||||||
|
|
||||||
assertThat(before == 0);
|
assertThat(before == 0);
|
||||||
|
@ -96,8 +96,8 @@ public class VariableHandlesTest {
|
||||||
public void givenVarHandle_whenGetAndBitwiseOrIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
public void givenVarHandle_whenGetAndBitwiseOrIsInvoked_ThenValueOfVariableIsChanged() throws NoSuchFieldException, IllegalAccessException {
|
||||||
VarHandle publicIntHandle = MethodHandles
|
VarHandle publicIntHandle = MethodHandles
|
||||||
.lookup()
|
.lookup()
|
||||||
.in(VariableHandlesTest.class)
|
.in(VariableHandlesUnitTest.class)
|
||||||
.findVarHandle(VariableHandlesTest.class, "variableToBitwiseOr", byte.class);
|
.findVarHandle(VariableHandlesUnitTest.class, "variableToBitwiseOr", byte.class);
|
||||||
byte before = (byte) publicIntHandle.getAndBitwiseOr(this, (byte) 127);
|
byte before = (byte) publicIntHandle.getAndBitwiseOr(this, (byte) 127);
|
||||||
|
|
||||||
assertThat(before == 0);
|
assertThat(before == 0);
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-9-streams</name>
|
<name>core-java-9-streams</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>core-java-modules</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<groupId>com.baeldung.core-java-modules</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
<artifactId>core-java-collections-2</artifactId>
|
<artifactId>core-java-collections-2</artifactId>
|
||||||
<name>core-java-collections-2</name>
|
<name>core-java-collections-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-3</name>
|
<name>core-java-collections-3</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-array-list</name>
|
<name>core-java-collections-array-list</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-list-2</name>
|
<name>core-java-collections-list-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-list-3</name>
|
<name>core-java-collections-list-3</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-list</name>
|
<name>core-java-collections-list</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-maps-2</name>
|
<name>core-java-collections-maps-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -5,4 +5,5 @@ This module contains articles about Map data structures in Java.
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Java TreeMap vs HashMap](https://www.baeldung.com/java-treemap-vs-hashmap)
|
- [Java TreeMap vs HashMap](https://www.baeldung.com/java-treemap-vs-hashmap)
|
||||||
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
||||||
|
- [The Map.computeIfAbsent() Method](https://www.baeldung.com/java-map-computeifabsent)
|
||||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-maps-3</name>
|
<name>core-java-collections-maps-3</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-maps</name>
|
<name>core-java-collections-maps</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
<parent>
|
||||||
<parent>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<groupId>com.baeldung</groupId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<artifactId>parent-java</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections-set</name>
|
<name>core-java-collections-set</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-collections</name>
|
<name>core-java-collections</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Using a Mutex Object in Java](https://www.baeldung.com/java-mutex)
|
- [Using a Mutex Object in Java](https://www.baeldung.com/java-mutex)
|
||||||
- [Testing Multi-Threaded Code in Java] (https://www.baeldung.com/java-testing-multithreaded)
|
- [Testing Multi-Threaded Code in Java](https://www.baeldung.com/java-testing-multithreaded)
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-2</name>
|
<name>core-java-concurrency-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-advanced-2</name>
|
<name>core-java-concurrency-advanced-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -11,4 +11,6 @@ This module contains articles about advanced topics about multithreading with co
|
||||||
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
- [Guide to Work Stealing in Java](https://www.baeldung.com/java-work-stealing)
|
||||||
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
- [Asynchronous Programming in Java](https://www.baeldung.com/java-asynchronous-programming)
|
||||||
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
|
- [Java Thread Deadlock and Livelock](https://www.baeldung.com/java-deadlock-livelock)
|
||||||
|
- [Guide to AtomicStampedReference in Java](https://www.baeldung.com/java-atomicstampedreference)
|
||||||
|
- [The ABA Problem in Concurrency](https://www.baeldung.com/cs/aba-concurrency)
|
||||||
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
- [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2)
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-advanced-3</name>
|
<name>core-java-concurrency-advanced-3</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -9,13 +9,11 @@ public class StampedAccount {
|
||||||
private AtomicStampedReference<Integer> account = new AtomicStampedReference<>(0, 0);
|
private AtomicStampedReference<Integer> account = new AtomicStampedReference<>(0, 0);
|
||||||
|
|
||||||
public int getBalance() {
|
public int getBalance() {
|
||||||
return this.account.get(new int[1]);
|
return account.getReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStamp() {
|
public int getStamp() {
|
||||||
int[] stamps = new int[1];
|
return account.getStamp();
|
||||||
this.account.get(stamps);
|
|
||||||
return stamps[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean deposit(int funds) {
|
public boolean deposit(int funds) {
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.deadlockAndLivelock;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class DeadlockExample {
|
||||||
|
|
||||||
|
private Lock lock1 = new ReentrantLock(true);
|
||||||
|
private Lock lock2 = new ReentrantLock(true);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
DeadlockExample deadlock = new DeadlockExample();
|
||||||
|
new Thread(deadlock::operation1, "T1").start();
|
||||||
|
new Thread(deadlock::operation2, "T2").start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operation1() {
|
||||||
|
lock1.lock();
|
||||||
|
print("lock1 acquired, waiting to acquire lock2.");
|
||||||
|
sleep(50);
|
||||||
|
|
||||||
|
lock2.lock();
|
||||||
|
print("lock2 acquired");
|
||||||
|
|
||||||
|
print("executing first operation.");
|
||||||
|
|
||||||
|
lock2.unlock();
|
||||||
|
lock1.unlock();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operation2() {
|
||||||
|
lock2.lock();
|
||||||
|
print("lock2 acquired, waiting to acquire lock1.");
|
||||||
|
sleep(50);
|
||||||
|
|
||||||
|
lock1.lock();
|
||||||
|
print("lock1 acquired");
|
||||||
|
|
||||||
|
print("executing second operation.");
|
||||||
|
|
||||||
|
lock1.unlock();
|
||||||
|
lock2.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void print(String message) {
|
||||||
|
System.out.println("Thread " + Thread.currentThread()
|
||||||
|
.getName() + ": " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sleep(long millis) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(millis);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.baeldung.deadlockAndLivelock;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class LivelockExample {
|
||||||
|
|
||||||
|
private Lock lock1 = new ReentrantLock(true);
|
||||||
|
private Lock lock2 = new ReentrantLock(true);
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
LivelockExample livelock = new LivelockExample();
|
||||||
|
new Thread(livelock::operation1, "T1").start();
|
||||||
|
new Thread(livelock::operation2, "T2").start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operation1() {
|
||||||
|
while (true) {
|
||||||
|
tryLock(lock1, 50);
|
||||||
|
print("lock1 acquired, trying to acquire lock2.");
|
||||||
|
sleep(50);
|
||||||
|
|
||||||
|
if (tryLock(lock2)) {
|
||||||
|
print("lock2 acquired.");
|
||||||
|
} else {
|
||||||
|
print("cannot acquire lock2, releasing lock1.");
|
||||||
|
lock1.unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("executing first operation.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lock2.unlock();
|
||||||
|
lock1.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operation2() {
|
||||||
|
while (true) {
|
||||||
|
tryLock(lock2, 50);
|
||||||
|
print("lock2 acquired, trying to acquire lock1.");
|
||||||
|
sleep(50);
|
||||||
|
|
||||||
|
if (tryLock(lock1)) {
|
||||||
|
print("lock1 acquired.");
|
||||||
|
} else {
|
||||||
|
print("cannot acquire lock1, releasing lock2.");
|
||||||
|
lock2.unlock();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
print("executing second operation.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lock1.unlock();
|
||||||
|
lock2.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void print(String message) {
|
||||||
|
System.out.println("Thread " + Thread.currentThread()
|
||||||
|
.getName() + ": " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sleep(long millis) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(millis);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryLock(Lock lock, long millis) {
|
||||||
|
try {
|
||||||
|
lock.tryLock(10, TimeUnit.MILLISECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tryLock(Lock lock) {
|
||||||
|
return lock.tryLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.baeldung.lockfree;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
public class NonBlockingQueue<T> {
|
||||||
|
|
||||||
|
private final AtomicReference<Node<T>> head, tail;
|
||||||
|
private final AtomicInteger size;
|
||||||
|
|
||||||
|
public NonBlockingQueue() {
|
||||||
|
head = new AtomicReference<>(null);
|
||||||
|
tail = new AtomicReference<>(null);
|
||||||
|
size = new AtomicInteger();
|
||||||
|
size.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(T element) {
|
||||||
|
if (element == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> node = new Node<>(element);
|
||||||
|
Node<T> currentTail;
|
||||||
|
do {
|
||||||
|
currentTail = tail.get();
|
||||||
|
node.setPrevious(currentTail);
|
||||||
|
} while(!tail.compareAndSet(currentTail, node));
|
||||||
|
|
||||||
|
if(node.previous != null) {
|
||||||
|
node.previous.next = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
head.compareAndSet(null, node); //if we are inserting the first element
|
||||||
|
size.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T get() {
|
||||||
|
if(head.get() == null) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> currentHead;
|
||||||
|
Node<T> nextNode;
|
||||||
|
do {
|
||||||
|
currentHead = head.get();
|
||||||
|
nextNode = currentHead.getNext();
|
||||||
|
} while(!head.compareAndSet(currentHead, nextNode));
|
||||||
|
|
||||||
|
size.decrementAndGet();
|
||||||
|
return currentHead.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.size.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Node<T> {
|
||||||
|
private final T value;
|
||||||
|
private volatile Node<T> next;
|
||||||
|
private volatile Node<T> previous;
|
||||||
|
|
||||||
|
public Node(T value) {
|
||||||
|
this.value = value;
|
||||||
|
this.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node<T> getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrevious(Node<T> previous) {
|
||||||
|
this.previous = previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.baeldung.exchanger;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.Exchanger;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static java.util.concurrent.CompletableFuture.runAsync;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ExchangerPipeLineManualTest {
|
||||||
|
|
||||||
|
private static final int BUFFER_SIZE = 100;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenData_whenPassedThrough_thenCorrect() throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Exchanger<Queue<String>> readerExchanger = new Exchanger<>();
|
||||||
|
Exchanger<Queue<String>> writerExchanger = new Exchanger<>();
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
Runnable reader = () -> {
|
||||||
|
Queue<String> readerBuffer = new ConcurrentLinkedQueue<>();
|
||||||
|
while (true) {
|
||||||
|
readerBuffer.add(UUID.randomUUID().toString());
|
||||||
|
if (readerBuffer.size() >= BUFFER_SIZE) {
|
||||||
|
try {
|
||||||
|
readerBuffer = readerExchanger.exchange(readerBuffer);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable processor = () -> {
|
||||||
|
Queue<String> processorBuffer = new ConcurrentLinkedQueue<>();
|
||||||
|
Queue<String> writerBuffer = new ConcurrentLinkedQueue<>();
|
||||||
|
try {
|
||||||
|
processorBuffer = readerExchanger.exchange(processorBuffer);
|
||||||
|
while (true) {
|
||||||
|
writerBuffer.add(processorBuffer.poll());
|
||||||
|
if (processorBuffer.isEmpty()) {
|
||||||
|
try {
|
||||||
|
processorBuffer = readerExchanger.exchange(processorBuffer);
|
||||||
|
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable writer = () -> {
|
||||||
|
Queue<String> writerBuffer = new ConcurrentLinkedQueue<>();
|
||||||
|
try {
|
||||||
|
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||||
|
while (true) {
|
||||||
|
System.out.println(writerBuffer.poll());
|
||||||
|
if (writerBuffer.isEmpty()) {
|
||||||
|
writerBuffer = writerExchanger.exchange(writerBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CompletableFuture.allOf(runAsync(reader), runAsync(processor), runAsync(writer)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.baeldung.exchanger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Exchanger;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static java.util.concurrent.CompletableFuture.runAsync;
|
||||||
|
|
||||||
|
public class ExchangerUnitTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThreads_whenMessageExchanged_thenCorrect() {
|
||||||
|
Exchanger<String> exchanger = new Exchanger<>();
|
||||||
|
|
||||||
|
Runnable taskA = () -> {
|
||||||
|
try {
|
||||||
|
String message = exchanger.exchange("from A");
|
||||||
|
assertEquals("from B", message);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Runnable taskB = () -> {
|
||||||
|
try {
|
||||||
|
String message = exchanger.exchange("from B");
|
||||||
|
assertEquals("from A", message);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CompletableFuture.allOf(runAsync(taskA), runAsync(taskB)).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThread_WhenExchangedMessage_thenCorrect() throws InterruptedException, ExecutionException {
|
||||||
|
Exchanger<String> exchanger = new Exchanger<>();
|
||||||
|
|
||||||
|
Runnable runner = () -> {
|
||||||
|
try {
|
||||||
|
String message = exchanger.exchange("from runner");
|
||||||
|
assertEquals("to runner", message);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CompletableFuture<Void> result = CompletableFuture.runAsync(runner);
|
||||||
|
String msg = exchanger.exchange("to runner");
|
||||||
|
assertEquals("from runner", msg);
|
||||||
|
result.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-advanced</name>
|
<name>core-java-concurrency-advanced</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-basic-2</name>
|
<name>core-java-concurrency-basic-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>core-java-concurrency-basic</name>
|
<name>core-java-concurrency-basic</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung.core-java-modules</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>core-java-modules</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -23,7 +23,12 @@
|
||||||
<artifactId>jmh-generator-annprocess</artifactId>
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
<version>${jmh.version}</version>
|
<version>${jmh.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
@ -42,6 +47,8 @@
|
||||||
<properties>
|
<properties>
|
||||||
<jmh.version>1.21</jmh.version>
|
<jmh.version>1.21</jmh.version>
|
||||||
<guava.version>28.2-jre</guava.version>
|
<guava.version>28.2-jre</guava.version>
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj.version>3.6.1</assertj.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.baeldung.concurrent.queue;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@FixMethodOrder
|
||||||
|
public class TestConcurrentLinkedQueue {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
||||||
|
Collection<Integer> elements = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>(elements);
|
||||||
|
assertThat(concurrentLinkedQueue).containsExactly(1, 2, 3, 4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenQueueIsEmpty_WhenAccessingTheQueue_ThenQueueReturnsNull() throws InterruptedException {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||||
|
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
executorService.submit(() -> assertNull("Retrieve object is null", concurrentLinkedQueue.poll()));
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenProducerOffersElementInQueue_WhenConsumerPollsQueue_ThenItRetrievesElement() throws Exception {
|
||||||
|
int element = 1;
|
||||||
|
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
Runnable offerTask = () -> concurrentLinkedQueue.offer(element);
|
||||||
|
|
||||||
|
Callable<Integer> pollTask = () -> {
|
||||||
|
while (concurrentLinkedQueue.peek() != null) {
|
||||||
|
return concurrentLinkedQueue.poll()
|
||||||
|
.intValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
executorService.submit(offerTask);
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
|
||||||
|
Future<Integer> returnedElement = executorService.submit(pollTask);
|
||||||
|
assertThat(returnedElement.get()
|
||||||
|
.intValue(), is(equalTo(element)));
|
||||||
|
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.baeldung.concurrent.queue;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@FixMethodOrder
|
||||||
|
public class TestLinkedBlockingQueue {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThereIsExistingCollection_WhenAddedIntoQueue_ThenShouldContainElements() {
|
||||||
|
Collection<Integer> elements = Arrays.asList(1, 2, 3, 4, 5);
|
||||||
|
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>(elements);
|
||||||
|
assertThat(linkedBlockingQueue).containsExactly(1, 2, 3, 4, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenQueueIsEmpty_WhenAccessingTheQueue_ThenThreadBlocks() throws InterruptedException {
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(1);
|
||||||
|
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||||
|
executorService.submit(() -> {
|
||||||
|
try {
|
||||||
|
linkedBlockingQueue.take();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenProducerPutsElementInQueue_WhenConsumerAccessQueue_ThenItRetrieve() {
|
||||||
|
int element = 10;
|
||||||
|
ExecutorService executorService = Executors.newFixedThreadPool(2);
|
||||||
|
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();
|
||||||
|
Runnable putTask = () -> {
|
||||||
|
try {
|
||||||
|
linkedBlockingQueue.put(element);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Callable<Integer> takeTask = () -> {
|
||||||
|
try {
|
||||||
|
return linkedBlockingQueue.take();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
executorService.submit(putTask);
|
||||||
|
Future<Integer> returnElement = executorService.submit(takeTask);
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
assertThat(returnElement.get()
|
||||||
|
.intValue(), is(equalTo(element)));
|
||||||
|
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue