diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5b063201..ea8f494e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,7 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bb880f10..2a74508b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,31 +1,26 @@ # Quickstart for GitHub Actions # https://docs.github.com/en/actions/quickstart +name: Fast CI +on: [ push, pull_request, workflow_dispatch ] -name: CI -on: [ push, pull_request ] jobs: + test: runs-on: ${{ matrix.os }} + timeout-minutes: 5 strategy: matrix: os: [ ubuntu-latest, windows-latest ] - java: [ 8, 11, 16, 17, 18, 19-ea ] + java: [ 8.0.345, 8, 11, 17, 21, 23 ] fail-fast: false max-parallel: 64 - name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} + name: Fast CI on Java ${{ matrix.java }} OS ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v6 + - uses: actions/setup-java@v5 with: java-version: ${{ matrix.java }} - distribution: 'zulu' - cache: 'maven' - - name: Build with Maven - run: ./mvnw -V --no-transfer-progress -Pgen-code-cov clean package - - name: Upload coverage to Codecov - # https://github.com/marketplace/actions/codecov - uses: codecov/codecov-action@v3 - with: - name: codecov-umbrella - token: ${{ secrets.CODECOV_TOKEN }} + distribution: zulu + cache: maven + - run: ./mvnw -V --no-transfer-progress clean package diff --git a/.github/workflows/strong_ci.yaml b/.github/workflows/strong_ci.yaml new file mode 100644 index 00000000..a816ffa9 --- /dev/null +++ b/.github/workflows/strong_ci.yaml @@ -0,0 +1,40 @@ +# Quickstart for GitHub Actions +# https://docs.github.com/en/actions/quickstart + +name: Strong CI +on: [ push, pull_request, workflow_dispatch ] +jobs: + test: + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#choosing-github-hosted-runners + runs-on: ubuntu-latest + timeout-minutes: 10 + name: CI by multiply java versions + + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Setup Java + uses: actions/setup-java@v5 + with: + # https://github.com/actions/setup-java?tab=readme-ov-file#install-multiple-jdks + # + # image(ubuntu-latest/ubuntu-24.04) included Java 8/11/17/21/25 + # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md#java + java-version: | + 8.0.345 + 23 + distribution: zulu + cache: maven + + - name: Run integration test + run: scripts/integration_test + + - name: Remove self maven install files + run: rm -rf $HOME/.m2/repository/com/alibaba/dns-cache-manipulator* + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index b654182a..00154cd8 100644 Binary files a/.gitignore and b/.gitignore differ diff --git a/.idea/dictionaries/dcm_project.xml b/.idea/dictionaries/dcm_project.xml new file mode 100644 index 00000000..dafd7826 --- /dev/null +++ b/.idea/dictionaries/dcm_project.xml @@ -0,0 +1,29 @@ + + + + Denable + Dexec + Dkotlin + Duser + INADDR + Ljava + NULLCHECK + RUNTIMEEXCEPTION + Werror + Xjsr + Xjvm + Xlint + archunit + autoscan + dcm + doctoc + kotest + linkoffline + moditect + mvnw + oldratlee + ossrh + relookup + + + \ No newline at end of file diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java deleted file mode 100644 index b901097f..00000000 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2007-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.net.*; -import java.io.*; -import java.nio.channels.*; -import java.util.Properties; - -public class MavenWrapperDownloader { - - private static final String WRAPPER_VERSION = "0.5.6"; - /** - * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. - */ - private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" - + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; - - /** - * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to - * use instead of the default one. - */ - private static final String MAVEN_WRAPPER_PROPERTIES_PATH = - ".mvn/wrapper/maven-wrapper.properties"; - - /** - * Path where the maven-wrapper.jar will be saved to. - */ - private static final String MAVEN_WRAPPER_JAR_PATH = - ".mvn/wrapper/maven-wrapper.jar"; - - /** - * Name of the property which should be used to override the default download url for the wrapper. - */ - private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; - - public static void main(String args[]) { - System.out.println("- Downloader started"); - File baseDirectory = new File(args[0]); - System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); - - // If the maven-wrapper.properties exists, read it and check if it contains a custom - // wrapperUrl parameter. - File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); - String url = DEFAULT_DOWNLOAD_URL; - if(mavenWrapperPropertyFile.exists()) { - FileInputStream mavenWrapperPropertyFileInputStream = null; - try { - mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); - Properties mavenWrapperProperties = new Properties(); - mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); - url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); - } catch (IOException e) { - System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); - } finally { - try { - if(mavenWrapperPropertyFileInputStream != null) { - mavenWrapperPropertyFileInputStream.close(); - } - } catch (IOException e) { - // Ignore ... - } - } - } - System.out.println("- Downloading from: " + url); - - File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); - if(!outputFile.getParentFile().exists()) { - if(!outputFile.getParentFile().mkdirs()) { - System.out.println( - "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); - } - } - System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); - try { - downloadFileFromURL(url, outputFile); - System.out.println("Done"); - System.exit(0); - } catch (Throwable e) { - System.out.println("- Error downloading"); - e.printStackTrace(); - System.exit(1); - } - } - - private static void downloadFileFromURL(String urlString, File destination) throws Exception { - if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { - String username = System.getenv("MVNW_USERNAME"); - char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); - Authenticator.setDefault(new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); - } - URL website = new URL(urlString); - ReadableByteChannel rbc; - rbc = Channels.newChannel(website.openStream()); - FileOutputStream fos = new FileOutputStream(destination); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - fos.close(); - rbc.close(); - } - -} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 2cc7d4a5..00000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 5d43cd33..8dea6c22 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,3 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip diff --git a/README.md b/README.md index a16f4375..9335589b 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,24 @@ #
🌏 Java Dns Cache Manipulator(DCM)

-Github Workflow Build Status -Appveyor Build Status -Coveralls branch -Maintainability -Java support +Fast Build CI +Strong Build CI +Coverage Status +Java support License Maven Central GitHub release -Javadocs -GitHub Stars -GitHub Forks +Javadocs +GitHub Stars +GitHub Forks GitHub issues user repos GitHub Contributors -gitpod: Ready to Code GitHub repo size -GitHub release download - dcm.tar.gz) +gitpod: Ready to Code +GitHub release download - dcm.tar.gz)

- 📖 English Documentation | 📖 [中文文档](docs/zh-CN/README.md) ---------------------------------------- @@ -28,12 +26,13 @@ Java Dns Cache Manipulator(`DCM`) contains 2 subprojects: - [**`DCM` Library**](library) - A tiny 0-dependency thread-safe lib for setting/viewing dns programmatically without touching host file, make unit/integration test portable. Support `Java 8/11/17/18/19`, support `IPv6`. + A tiny 0-dependency thread-safe lib for setting/viewing dns programmatically without touching host file, make unit/integration test portable. Support `Java 8~21`, support `IPv6`. - [**`DCM` Tool**](tool) A tiny tool for setting/viewing dns of running JVM processes. -> From `DCM 1.7+` upgrade to `Java 8`. -> If you need `Java 6` support, use version `1.6.x` Maven Central +> [!NOTE] +> Start from `DCM 1.7+` upgrade to `Java 8` 🚀 +> If you need `Java 6` support, use version `1.6.x` Maven Central ---------------------------------------- @@ -41,34 +40,36 @@ Java Dns Cache Manipulator(`DCM`) contains 2 subprojects: - [Java Dns Cache Manipulator(`DCM`) Library](#java-dns-cache-manipulatordcm-library) - - [🔧 Features](#-features) - - [🎨 Requirement Scenario](#-requirement-scenario) - - [👥 User Guide](#-user-guide) - - [Set directly](#set-directly) - - [Batch configuration through the `dns-cache.properties` file](#batch-configuration-through-the-dns-cacheproperties-file) - - [View JVM DNS cache](#view-jvm-dns-cache) - - [Remove a DNS cache](#remove-a-dns-cache) - - [Clear JVM DNS cache](#clear-jvm-dns-cache) - - [Set/View the default DNS cache time of JVM](#setview-the-default-dns-cache-time-of-jvm) - - [Precautions for use](#precautions-for-use) - - [JVM settings for Java 16+](#jvm-settings-for-java-16) - - [Domain name case](#domain-name-case) - - [Domain resolution cache](#domain-resolution-cache) - - [More detailed functions](#more-detailed-functions) - - [🔌 Java API Docs](#-java-api-docs) - - [🍪 Dependency](#-dependency) - - [🗿 More Documentation](#-more-documentation) - - [📚 Related Resources](#-related-resources) + - [🔧 Features](#-features) + - [🎨 Requirement Scenario](#-requirement-scenario) + - [👥 User Guide](#-user-guide) + - [Set directly](#set-directly) + - [Batch configuration through the `dns-cache.properties` file](#batch-configuration-through-the-dns-cacheproperties-file) + - [View JVM DNS cache](#view-jvm-dns-cache) + - [Remove a DNS cache](#remove-a-dns-cache) + - [Clear JVM DNS cache](#clear-jvm-dns-cache) + - [Set/View the default DNS cache time of JVM](#setview-the-default-dns-cache-time-of-jvm) + - [Precautions for use](#precautions-for-use) + - [JVM settings for Java 16+](#jvm-settings-for-java-16) + - [Domain name case](#domain-name-case) + - [Domain resolution cache](#domain-resolution-cache) + - [More detailed functions](#more-detailed-functions) + - [🔌 Java API Docs](#-java-api-docs) + - [🍪 Dependency](#-dependency) + - [🗿 More Documentation](#-more-documentation) + - [📚 Related Resources](#-related-resources) - [Java Dns Cache Manipulator Tool](#java-dns-cache-manipulator-tool) - - [🔧 Features](#-features-1) - - [👥 User Guide](#-user-guide-1) - - [Download](#download) - - [Set/reset a DNS cache entry](#setreset-a-dns-cache-entry) - - [View DNS cache entry content](#view-dns-cache-entry-content) - - [Remove a DNS Cache](#remove-a-dns-cache) - - [Clear DNS Cache](#clear-dns-cache) - - [Set/View DNS cache time of `JVM`](#setview-dns-cache-time-of-jvm) - - [📚 Related information](#-related-information) + - [🔧 Features](#-features-1) + - [👥 User Guide](#-user-guide-1) + - [Download](#download) + - [Set/reset a DNS cache entry](#setreset-a-dns-cache-entry) + - [View DNS cache entry content](#view-dns-cache-entry-content) + - [Remove a DNS Cache](#remove-a-dns-cache) + - [Clear DNS Cache](#clear-dns-cache) + - [Set/View DNS cache time of `JVM`](#setview-dns-cache-time-of-jvm) + - [Load Cache Entries from File](#load-cache-entries-from-file) + - [Manipulate cache with a command line option at JVM startup](#manipulate-cache-with-a-command-line-option-at-jvm-startup) + - [📚 Related information](#-related-information) @@ -185,7 +186,7 @@ public static void beforeClass() throws Exception { ```java // Get a dns cache entry by host -DnsCacheEntry entry = DnsCacheManipulator.getDnsCache(); +DnsCacheEntry entry = DnsCacheManipulator.getDnsCache("bing.com"); // get whole dns cache info DnsCache including cache and negative cache. DnsCache dnsCache = DnsCacheManipulator.getWholeDnsCache(); @@ -222,7 +223,7 @@ int cachePolicy = DnsCacheManipulator.getDnsCachePolicy(); DnsCacheManipulator.setDnsCachePolicy(2); // View the cache time of missed entries(negative entries) -DnsCacheManipulator.getDnsNegativeCachePolicy() +DnsCacheManipulator.getDnsNegativeCachePolicy(); // Set the cache time of missed entries DnsCacheManipulator.setDnsNegativeCachePolicy(0); ``` @@ -233,7 +234,7 @@ DnsCacheManipulator.setDnsNegativeCachePolicy(0); With the release of Java 16 the access control of the new Jigsaw module system is starting to be enforced by the JVM. If you use `DCM` under Java 16+, add below Java options: -```java +```sh --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED ``` @@ -306,7 +307,7 @@ Java API document: com.alibaba dns-cache-manipulator - 1.7.2 + 1.8.3 ``` @@ -341,7 +342,7 @@ You can view the latest version at [search.maven.org](https://search.maven.org/a ### Download -[![GitHub release download - dcm.tar.gz)](https://img.shields.io/github/downloads/alibaba/java-dns-cache-manipulator/v1.7.2/dcm-1.7.2.tar.gz.svg?logoColor=white&logo=DocuSign)](https://github.com/alibaba/java-dns-cache-manipulator/releases/download/v1.7.2/dcm-1.7.2.tar.gz) download the file `dcm-x.y.z.tar.gz`. +[![GitHub release download - dcm.tar.gz)](https://img.shields.io/github/downloads/alibaba/java-dns-cache-manipulator/v1.8.3/dcm-1.8.3.tar.gz.svg?logoColor=white&logo=DocuSign)](https://github.com/alibaba/java-dns-cache-manipulator/releases/download/v1.8.3/dcm-1.8.3.tar.gz) download the file `dcm-x.y.z.tar.gz`. After decompression, run `dcm` in the `bin` directory. @@ -421,6 +422,23 @@ $ dcm -p 12345 getNegativePolicy $ dcm -p 12345 setNegativePolicy 0 ``` +### Load Cache Entries from File + +```bash +$ dcm -p 12345 load /foo/bar/my-cache.properties +``` + +### Manipulate cache with a command line option at JVM startup + +To manipulate dns entries at jvm startup, add the following jvm-options: + +```bash +# Set individual entry +java -javaagent:="set foo.com 1.1.1.1" --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED ... +# Load entries from file +java -javaagent:="load my-cache.properties" --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/sun.net=ALL-UNNAMED ... +``` + ## 📚 Related information * [Java Agent Specification](http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index fbb9550c..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,47 +0,0 @@ -# appveyor.yml Reference -# https://www.appveyor.com/docs/appveyor-yml/ -# -# How to use AppVeyor to build a multi-arch Docker image for Linux and Windows -# https://stefanscherer.github.io/use-appveyor-to-build-multi-arch-docker-image/ -# -# Building ASP.NET Core apps on both Windows and Linux using AppVeyor -# https://andrewlock.net/building-asp-net-core-apps-on-both-windows-and-linux-using-appveyor/ -# -# appveyor.yml Example: -# https://github.com/cdcseacave/openMVS/blob/master/.appveyor.yml - -version: '{build}' -image: Ubuntu2004 -build: false -clone_depth: 50 -branches: - except: - - gh-pages - -environment: - APPVEYOR_YML_DISABLE_PS_LINUX: true - MAVEN_OPTS: "-Xmx768m -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2" - JAVA_OPTS: "-Xmx768m" - -install: - - git submodule update --init - -test_script: - - scripts/integration_test - -after_test: - - ./scripts/codecov -s - # remove self maven install - - rm -rf $HOME/.m2/repository/com/alibaba/dns-cache-manipulator* - # remove maven install file - - rm -rf $HOME/.m2/wrapper/dists/*/*/*.zip - # # remove sdkman install file - - rm -rf $HOME/.sdkman/archives/* - - rm -rf $HOME/.sdkman/tmp/* - -cache: - # if cache size is exceed appveyor limit: - # Compressed cache item cannot exceed 1,048,576,000 bytes - # skip below maven cache: - - $HOME/.m2/ - - $HOME/.sdkman/ diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 455bd937..f736f024 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -1,23 +1,22 @@ # 🎓 Developer Guide

-Github Workflow Build Status -Build Status -Coveralls branch -Maintainability -JDK support -License -Javadocs +Fast Build CI +Strong Build CI +Coverage Status +Java support +License Maven Central GitHub release -Chat at gitter.im -GitHub Stars -GitHub Forks -user repos +Javadocs +GitHub Stars +GitHub Forks GitHub issues +user repos GitHub Contributors GitHub repo size -GitHub release download - dcm.tar.gz) +gitpod: Ready to Code +GitHub release download - dcm.tar.gz)

## How to set the DNS Cache of `JVM` safely @@ -26,8 +25,8 @@ The DNS Cache of the JVM is maintained in the private field of the InetAddress c - [`InetAddressCacheUtilCommons.java`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java) -- [`InetAddressCacheUtilForJava8Minus.java`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8Minus.java) -- [`InetAddressCacheUtilForJava9Plus.java`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava9Plus.java) +- [`InetAddressCacheUtilForOld.java`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java) +- [`InetAddressCacheUtilForNew.java`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForNew.java) Pay attention to the thread safety of setting the DNS Cache of JVM The DNS Cache of the JVM is obviously shared globally, so the setting is guaranteed to be thread-safe and there is no concurrency problem. @@ -55,14 +54,13 @@ private static void cacheAddresses(String hostname, } ``` -In the [`InetAddressCacheUtilForJava8Minus`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8Minus.java) class, the read and write to the DNS Cache also consistently adds a synchronized block with `addressCache` field as the lock to ensure thread safety. +In the [`InetAddressCacheUtilForOld`](../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java) class, the read and write to the DNS Cache also consistently adds a synchronized block with `addressCache` field as the lock to ensure thread safety. ## Need test different `JDK` versions The implementation of this library uses the non-public API of the `JDK`, and different `JDK` implementations will be different, that is, compatible logic is required, and different versions of `JDK` are tested to ensure functionality. -The current tested LTS `JDK` versions 8/11/17/18/19, other `JDK` versions should work properly. - +The LTS `JDK` versions(8/11/17) and recent versions are tested , other `JDK` versions should work properly. ## 📚 Related Resources @@ -80,4 +78,4 @@ The current tested LTS `JDK` versions 8/11/17/18/19, other `JDK` versions should - [FileOutput Node - Java DNS caching pitfall - quick clarification and tips](https://www.ibm.com/developerworks/community/blogs/aimsupport/entry/fileoutput_node_dns_caching_pitfall?lang=en) - The [`javahost`](https://github.com/tanhaichao/javahost) project of [`@tanhaichao`](https://github.com/tanhaichao) (Thanks for your work!) - [the documentation](http://leopard.io/modules/javahost) of the project. - - The solution of how to set up Java DNS Cache in this project comes from this project. When I first encountered the host binding problem in the continuous integration project, I also used the project to solve it 👍 + - The solution of how to set up Java DNS Cache comes from this project. When I first encountered the host binding problem in the continuous integration project, I also used the project to solve it 👍 diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index fb8673a6..189d232e 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -1,22 +1,22 @@ #
🌏 Java Dns Cache Manipulator(DCM)

-Build Status -Coveralls branch -Maintainability -Java support +Fast Build CI +Strong Build CI +Coverage Status +Java support License Maven Central GitHub release -Javadocs -GitHub Stars -GitHub Forks +Javadocs +GitHub Stars +GitHub Forks GitHub issues user repos GitHub Contributors -gitpod: Ready to Code GitHub repo size -GitHub release download - dcm.tar.gz) +gitpod: Ready to Code +GitHub release download - dcm.tar.gz)

[📖 English Documentation](../../README.md) | 📖 中文文档 diff --git a/docs/zh-CN/library.md b/docs/zh-CN/library.md index 1ec21c43..beedef21 100644 --- a/docs/zh-CN/library.md +++ b/docs/zh-CN/library.md @@ -2,21 +2,21 @@ Java Dns Cache Manipulator(DCM) Library =======================================

-Build Status -Coveralls branch -Maintainability -JDK support -License -Javadocs +Fast Build CI +Strong Build CI +Coverage Status +Java support +License Maven Central GitHub release -Chat at gitter.im -GitHub Stars -GitHub Forks -user repos +Javadocs +GitHub Stars +GitHub Forks GitHub issues +user repos GitHub Contributors GitHub repo size +gitpod: Ready to Code

:point_right: 用编码的方式设置/查看`JVM`的`DNS`(实际上设置的是`DNS Cache`),支持`JDK 6+`,支持`IPv6`。 @@ -73,7 +73,7 @@ Java Dns Cache Manipulator(DCM) Library - 一个`JVM`进程可以对应一套域名绑定,相互之间不影响,可以实现多场景,多域名绑定的需求压测。 1. 打开`Java`中的`SecurityManager`时(如在`Web`容器`Tomcat`中的`Web`应用),`Java`的`DNS`缺省是不会失效的。 如果域名绑定的`IP`变了,可以通过这个库重置`DNS`。 - - 通过[`Java Dns Cache Manipulator Tool`](../tool)设置运行中`JVM DNS Cache`。 + - 通过[`Java Dns Cache Manipulator Tool`](../../tool)设置运行中`JVM DNS Cache`。 **无需** 应用包含了`Java Dns Cache Manipulator Library`依赖(即`Jar`)。 - 或通过执行入口调用`Java Dns Cache Manipulator Library`的方法,比如远程调用或是[`jvm-ssh-groovy-shell`](https://github.com/palominolabs/jvm-ssh-groovy-shell)。 ***需要*** 应用已经包含了`Java Dns Cache Manipulator Library`依赖(即`Jar`)。 @@ -169,7 +169,7 @@ DnsCacheManipulator.removeDnsCache("aliyun.com"); ---------------------------------- ```java -DnsCache dnsCache = DnsCacheManipulator.getWholeDnsCache() +DnsCache dnsCache = DnsCacheManipulator.getWholeDnsCache(); System.out.println(dnsCache); ``` @@ -183,7 +183,7 @@ int cachePolicy = DnsCacheManipulator.getDnsCachePolicy(); DnsCacheManipulator.setDnsCachePolicy(2); // 查看未命中条目的缓存时间 -DnsCacheManipulator.getDnsNegativeCachePolicy() +DnsCacheManipulator.getDnsNegativeCachePolicy(); // 设置未命中条目的缓存时间 DnsCacheManipulator.setDnsNegativeCachePolicy(0); ``` @@ -218,7 +218,7 @@ content = m2.getResponseBodyAsString(); 更多详细功能 ---------------------------------- -参见类[`DnsCacheManipulator`](src/main/java/com/alibaba/dcm/DnsCacheManipulator.java)的文档说明。 +参见类[`DnsCacheManipulator`](../../library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java)的文档说明。 :electric_plug: Java API Docs ===================================== @@ -234,7 +234,7 @@ content = m2.getResponseBodyAsString(); com.alibaba dns-cache-manipulator - 1.7.2 + 1.8.3 ``` @@ -271,8 +271,8 @@ PS: `JVM`的`DNS Cache`维护在类`InetAddress`的私有字段中,通过反射来设置,具体实现参见 - [`InetAddressCacheUtilCommons.java`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java) -- [`InetAddressCacheUtilForJava9Plus.java`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8Minus.java) -- [`InetAddressCacheUtilForJava9Plus.java`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava9Plus.java) +- [`InetAddressCacheUtilForOld.java`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java) +- [`InetAddressCacheUtilForNew.java`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForNew.java) 注意设置`JVM`的`DNS Cache`的线程安全问题 ---------------------------------- @@ -302,7 +302,7 @@ private static void cacheAddresses(String hostname, } ``` -[`InetAddressCacheUtilForJdk8Minus`](src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJdk8Minus.java)类中对`DNS Cache`的读写也一致地加了以`addressCache`为锁的`synchronized`块,以保证线程安全。 +[`InetAddressCacheUtilForOld`](../../library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java)类中对`DNS Cache`的读写也一致地加了以`addressCache`为锁的`synchronized`块,以保证线程安全。 需要测试不同版本`JDK` ---------------------------------- diff --git a/docs/zh-CN/tool.md b/docs/zh-CN/tool.md index 46260845..1911dcba 100644 --- a/docs/zh-CN/tool.md +++ b/docs/zh-CN/tool.md @@ -2,22 +2,22 @@ Java Dns Cache Manipulator Tool =================================

-Build Status -Coveralls branch -Maintainability -JDK support -License -Javadocs +Fast Build CI +Strong Build CI +Coverage Status +Java support +License Maven Central GitHub release -Chat at gitter.im -GitHub Stars -GitHub Forks -user repos +Javadocs +GitHub Stars +GitHub Forks GitHub issues +user repos GitHub Contributors GitHub repo size -GitHub release download - dcm.tar.gz) +gitpod: Ready to Code +GitHub release download - dcm.tar.gz)

:point_right: 设置/查看 运行中`JVM`进程的`DNS Cache`,支持`IPv6`。 @@ -52,7 +52,7 @@ Java Dns Cache Manipulator Tool 下载 ---------- -[![GitHub release download - dcm.tar.gz)](https://img.shields.io/github/downloads/alibaba/java-dns-cache-manipulator/v1.7.2/dcm-1.7.2.tar.gz.svg?logoColor=white&logo=DocuSign)](https://github.com/alibaba/java-dns-cache-manipulator/releases/download/v1.7.2/dcm-1.7.2.tar.gz) 下载文件`dcm-x.y.z.tar.gz`。 +[![GitHub release download - dcm.tar.gz)](https://img.shields.io/github/downloads/alibaba/java-dns-cache-manipulator/v1.8.3/dcm-1.8.3.tar.gz.svg?logoColor=white&logo=DocuSign)](https://github.com/alibaba/java-dns-cache-manipulator/releases/download/v1.8.3/dcm-1.8.3.tar.gz) 下载文件`dcm-x.y.z.tar.gz`。 解压后,运行`bin`目录下的`dcm`。 diff --git a/library/pom.xml b/library/pom.xml index a78832d7..f4c28195 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -4,7 +4,7 @@ com.alibaba dns-cache-manipulator-parent - 1.8.0-SNAPSHOT + 1.x-SNAPSHOT ../pom.xml @@ -14,7 +14,7 @@ 🌏 a tiny 0-dependency thread-safe Java™ lib for setting/viewing dns programmatically without touching host file, - make unit/integration test portable. support Java 8/11/17/18/19, support IPv6. + make unit/integration test portable. support Java 8~21, support IPv6. https://github.com/alibaba/java-dns-cache-manipulator 2015 @@ -62,15 +62,22 @@ commons-lang3 test + + commons-io + commons-io + test + + org.apache.maven.plugins maven-jar-plugin + com.alibaba.dcm.agent.DcmAgent com.alibaba.dcm.agent.DcmAgent false false diff --git a/library/src/api/overview.html b/library/src/javadoc/overview.html similarity index 100% rename from library/src/api/overview.html rename to library/src/javadoc/overview.html diff --git a/library/src/main/java/com/alibaba/dcm/DnsCache.java b/library/src/main/java/com/alibaba/dcm/DnsCache.java index 72e19704..8b8faa6f 100644 --- a/library/src/main/java/com/alibaba/dcm/DnsCache.java +++ b/library/src/main/java/com/alibaba/dcm/DnsCache.java @@ -1,9 +1,7 @@ package com.alibaba.dcm; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.Immutable; import java.io.Serializable; import java.util.ArrayList; @@ -17,8 +15,6 @@ * @since 1.2.0 */ @Immutable -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault public final class DnsCache implements Serializable { private static final long serialVersionUID = -8614746635950970028L; @@ -28,8 +24,8 @@ public final class DnsCache implements Serializable { /** * Construct a {@link DnsCache}. */ - public DnsCache(@SuppressFBWarnings("EI_EXPOSE_REP2") List cache, - @SuppressFBWarnings("EI_EXPOSE_REP2") List negativeCache) { + @SuppressFBWarnings("EI_EXPOSE_REP2") + public DnsCache(List cache, List negativeCache) { this.cache = cache; this.negativeCache = negativeCache; } @@ -55,10 +51,7 @@ public List getNegativeCache() { */ @Override public String toString() { - return "DnsCache{" + - "cache=" + cache + - ", negativeCache=" + negativeCache + - '}'; + return "DnsCache{cache=" + cache + ", negativeCache=" + negativeCache + '}'; } /** diff --git a/library/src/main/java/com/alibaba/dcm/DnsCacheEntry.java b/library/src/main/java/com/alibaba/dcm/DnsCacheEntry.java index a3efd682..ecc3003f 100644 --- a/library/src/main/java/com/alibaba/dcm/DnsCacheEntry.java +++ b/library/src/main/java/com/alibaba/dcm/DnsCacheEntry.java @@ -1,9 +1,7 @@ package com.alibaba.dcm; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.Immutable; import java.io.Serializable; import java.text.SimpleDateFormat; @@ -18,8 +16,6 @@ * @see DnsCache */ @Immutable -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault public final class DnsCacheEntry implements Serializable { private static final long serialVersionUID = -7476648934387757732L; @@ -63,9 +59,8 @@ public Date getExpiration() { * @deprecated use {@link #DnsCacheEntry(String, String[], long)} instead */ @Deprecated - public DnsCacheEntry(String host, - @SuppressFBWarnings("EI_EXPOSE_REP2") String[] ips, - @SuppressFBWarnings("EI_EXPOSE_REP2") Date expiration) { + @SuppressFBWarnings("EI_EXPOSE_REP2") + public DnsCacheEntry(String host, String[] ips, Date expiration) { this.host = host; this.ips = ips; this.expiration = expiration.getTime(); @@ -76,9 +71,8 @@ public DnsCacheEntry(String host, * * @since 1.6.0 */ - public DnsCacheEntry(String host, - @SuppressFBWarnings("EI_EXPOSE_REP2") String[] ips, - long expiration) { + @SuppressFBWarnings("EI_EXPOSE_REP2") + public DnsCacheEntry(String host, String[] ips, long expiration) { this.host = host; this.ips = ips; this.expiration = expiration; @@ -91,11 +85,8 @@ public DnsCacheEntry(String host, public String toString() { final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); - return "DnsCacheEntry{" + - "host='" + host + '\'' + - ", ips=" + Arrays.toString(ips) + - ", expiration=" + dateFormat.format(expiration) + - '}'; + return "DnsCacheEntry{host='" + host + '\'' + ", ips=" + Arrays.toString(ips) + + ", expiration=" + dateFormat.format(expiration) + '}'; } /** @@ -117,10 +108,11 @@ public boolean equals(Object o) { * {@inheritDoc} */ @Override + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") public int hashCode() { int result = host != null ? host.hashCode() : 0; result = 31 * result + Arrays.hashCode(ips); - result = 31 * result + (int) (expiration ^ (expiration >>> 32)); + result = 31 * result + Long.hashCode(expiration); return result; } } diff --git a/library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java b/library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java index 4e703373..27bf6737 100644 --- a/library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java +++ b/library/src/main/java/com/alibaba/dcm/DnsCacheManipulator.java @@ -1,13 +1,12 @@ package com.alibaba.dcm; import com.alibaba.dcm.internal.InetAddressCacheUtilCommons; -import com.alibaba.dcm.internal.InetAddressCacheUtilForJava8; -import com.alibaba.dcm.internal.InetAddressCacheUtilForJava9Plus; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; +import com.alibaba.dcm.internal.InetAddressCacheUtilForNew; +import com.alibaba.dcm.internal.InetAddressCacheUtilForOld; import sun.net.InetAddressCachePolicy; import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; +import java.io.FileInputStream; import java.io.InputStream; import java.util.Arrays; import java.util.List; @@ -16,7 +15,7 @@ import java.util.regex.Pattern; import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.NEVER_EXPIRATION; -import static com.alibaba.dcm.internal.JavaVersionUtil.isJavaVersionAtMost8; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.isNewInetAddressImpl; /** @@ -29,8 +28,7 @@ * @see DnsCacheEntry * @see DnsCacheManipulatorException */ -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault +@SuppressWarnings("JavadocReference") public final class DnsCacheManipulator { /** * Set a never expired dns cache entry. @@ -42,10 +40,10 @@ public final class DnsCacheManipulator { */ public static void setDnsCache(String host, String... ips) { try { - if (isJavaVersionAtMost8()) { - InetAddressCacheUtilForJava8.setInetAddressCache(host, ips, NEVER_EXPIRATION); + if (isNewInetAddressImpl()) { + InetAddressCacheUtilForNew.setInetAddressCache(host, ips, NEVER_EXPIRATION); } else { - InetAddressCacheUtilForJava9Plus.setInetAddressCache(host, ips, NEVER_EXPIRATION); + InetAddressCacheUtilForOld.setInetAddressCache(host, ips, NEVER_EXPIRATION); } } catch (Exception e) { final String message = String.format("Fail to setDnsCache for host %s ip %s, cause: %s", @@ -64,10 +62,10 @@ public static void setDnsCache(String host, String... ips) { */ public static void setDnsCache(long expireMillis, String host, String... ips) { try { - if (isJavaVersionAtMost8()) { - InetAddressCacheUtilForJava8.setInetAddressCache(host, ips, expireMillis); + if (isNewInetAddressImpl()) { + InetAddressCacheUtilForNew.setInetAddressCache(host, ips, expireMillis); } else { - InetAddressCacheUtilForJava9Plus.setInetAddressCache(host, ips, expireMillis); + InetAddressCacheUtilForOld.setInetAddressCache(host, ips, expireMillis); } } catch (Exception e) { final String message = String.format("Fail to setDnsCache for host %s ip %s expireMillis %s, cause: %s", @@ -143,6 +141,27 @@ public static void loadDnsCacheConfig(String propertiesFileName) { } } + /** + * Load dns config from the specified properties file in filesystem, then set dns cache. + * + * @param propertiesFileName specified properties file name in filesystem. + * @throws DnsCacheManipulatorException Operation fail + * @see DnsCacheManipulator#setDnsCache(java.util.Properties) + */ + public static void loadDnsCacheConfigFromFileSystem(String propertiesFileName) { + try { + InputStream inputStream = new FileInputStream(propertiesFileName); + Properties properties = new Properties(); + properties.load(inputStream); + inputStream.close(); + setDnsCache(properties); + } catch (Exception e) { + final String message = String.format("Fail to loadDnsCacheConfig from %s, cause: %s", + propertiesFileName, e); + throw new DnsCacheManipulatorException(message, e); + } + } + /** * Get a dns cache entry by {@code host}. * @@ -152,10 +171,10 @@ public static void loadDnsCacheConfig(String propertiesFileName) { @Nullable public static DnsCacheEntry getDnsCache(String host) { try { - if (isJavaVersionAtMost8()) { - return InetAddressCacheUtilForJava8.getInetAddressCache(host); + if (isNewInetAddressImpl()) { + return InetAddressCacheUtilForNew.getInetAddressCache(host); } else { - return InetAddressCacheUtilForJava9Plus.getInetAddressCache(host); + return InetAddressCacheUtilForOld.getInetAddressCache(host); } } catch (Exception e) { throw new DnsCacheManipulatorException("Fail to getDnsCache, cause: " + e, e); @@ -174,10 +193,10 @@ public static DnsCacheEntry getDnsCache(String host) { */ public static DnsCache getWholeDnsCache() { try { - if (isJavaVersionAtMost8()) { - return InetAddressCacheUtilForJava8.listInetAddressCache(); + if (isNewInetAddressImpl()) { + return InetAddressCacheUtilForNew.listInetAddressCache(); } else { - return InetAddressCacheUtilForJava9Plus.listInetAddressCache(); + return InetAddressCacheUtilForOld.listInetAddressCache(); } } catch (Exception e) { throw new DnsCacheManipulatorException("Fail to getWholeDnsCache, cause: " + e, e); @@ -235,10 +254,10 @@ public static List listDnsNegativeCache() { */ public static void removeDnsCache(String host) { try { - if (isJavaVersionAtMost8()) { - InetAddressCacheUtilForJava8.removeInetAddressCache(host); + if (isNewInetAddressImpl()) { + InetAddressCacheUtilForNew.removeInetAddressCache(host); } else { - InetAddressCacheUtilForJava9Plus.removeInetAddressCache(host); + InetAddressCacheUtilForOld.removeInetAddressCache(host); } } catch (Exception e) { final String message = String.format("Fail to removeDnsCache for host %s, cause: %s", host, e); @@ -253,10 +272,10 @@ public static void removeDnsCache(String host) { */ public static void clearDnsCache() { try { - if (isJavaVersionAtMost8()) { - InetAddressCacheUtilForJava8.clearInetAddressCache(); + if (isNewInetAddressImpl()) { + InetAddressCacheUtilForNew.clearInetAddressCache(); } else { - InetAddressCacheUtilForJava9Plus.clearInetAddressCache(); + InetAddressCacheUtilForOld.clearInetAddressCache(); } } catch (Exception e) { throw new DnsCacheManipulatorException("Fail to clearDnsCache, cause: " + e, e); diff --git a/library/src/main/java/com/alibaba/dcm/agent/DcmAgent.java b/library/src/main/java/com/alibaba/dcm/agent/DcmAgent.java index 69a75b68..f0cbb238 100644 --- a/library/src/main/java/com/alibaba/dcm/agent/DcmAgent.java +++ b/library/src/main/java/com/alibaba/dcm/agent/DcmAgent.java @@ -38,7 +38,14 @@ public class DcmAgent { static final String DCM_AGENT_SUCCESS_MARK_LINE = "!!DCM SUCCESS!!"; /** - * Entrance method of DCM Java Agent. + * Entrance method of DCM Java Agent when used through a jvm command line option. + */ + public static void premain(@Nonnull String agentArgument) throws Exception { + agentmain(agentArgument); + } + + /** + * Entrance method of DCM Java Agent when connecting to a running jvm. */ @SuppressFBWarnings("THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION") public static void agentmain(@Nonnull String agentArgument) throws Exception { @@ -163,7 +170,7 @@ private static boolean isDcmAgentSuppressExceptionStack() { if (suppressException == null) return false; suppressException = suppressException.trim(); - if (suppressException.length() == 0) return false; + if (suppressException.isEmpty()) return false; return "true".equalsIgnoreCase(suppressException); } @@ -264,6 +271,8 @@ private static synchronized void initAction2Method() throws NoSuchMethodExceptio map.put("ls", DnsCacheManipulator.class.getMethod("getWholeDnsCache")); map.put("clear", DnsCacheManipulator.class.getMethod("clearDnsCache")); + map.put("load", DnsCacheManipulator.class.getMethod("loadDnsCacheConfigFromFileSystem", String.class)); + map.put("setPolicy", DnsCacheManipulator.class.getMethod("setDnsCachePolicy", int.class)); map.put("getPolicy", DnsCacheManipulator.class.getMethod("getDnsCachePolicy")); map.put("setNegativePolicy", DnsCacheManipulator.class.getMethod("setDnsNegativeCachePolicy", int.class)); @@ -300,7 +309,7 @@ public static List getActionList() { @Nullable private static String getConfig(@Nonnull String name) { String var = System.getenv(name); - if (var == null || var.trim().length() == 0) { + if (var == null || var.trim().isEmpty()) { var = System.getProperty(name); } return var; diff --git a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java index 3eabefe8..ce41082a 100644 --- a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java +++ b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilCommons.java @@ -1,10 +1,9 @@ package com.alibaba.dcm.internal; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; +import org.jetbrains.annotations.ApiStatus; import sun.net.InetAddressCachePolicy; import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; import java.lang.reflect.Field; import java.net.InetAddress; import java.net.UnknownHostException; @@ -15,8 +14,8 @@ * @author Jerry Lee (oldratlee at gmail dot com) * @since 1.6.0 */ -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault +@ApiStatus.Internal +@SuppressWarnings("JavadocReference") public final class InetAddressCacheUtilCommons { /** * We never really have "never". @@ -181,6 +180,30 @@ private static void initFieldsOfInetAddressCachePolicy() throws NoSuchFieldExcep } } + private static volatile Boolean isNew; + + /** + * Check the new or old implementation of {@link InetAddress} + * by whether the field {@link InetAddress.expirySet} is existed or not. + */ + public static boolean isNewInetAddressImpl() { + if (isNew != null) return isNew; + + synchronized (InetAddressCacheUtilCommons.class) { + // double check + if (isNew != null) return isNew; + + try { + InetAddress.class.getDeclaredField("expirySet"); + isNew = true; + } catch (NoSuchFieldException e) { + isNew = false; + } + + return isNew; + } + } + private InetAddressCacheUtilCommons() { } } diff --git a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava9Plus.java b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForNew.java similarity index 87% rename from library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava9Plus.java rename to library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForNew.java index 9c3f41c1..3e98682d 100644 --- a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava9Plus.java +++ b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForNew.java @@ -2,10 +2,9 @@ import com.alibaba.dcm.DnsCache; import com.alibaba.dcm.DnsCacheEntry; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; +import org.jetbrains.annotations.ApiStatus; import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -18,12 +17,14 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentSkipListSet; -import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.*; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.NEVER_EXPIRATION; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.getIpFromInetAddress; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.toInetAddressArray; import static com.alibaba.dcm.internal.TimeUtil.convertNanoTimeToTimeMillis; import static com.alibaba.dcm.internal.TimeUtil.getNanoTimeAfterMs; /** - * Util class to manipulate dns cache for {@code JDK 9+}. + * Util class to manipulate dns cache for new {@code JDK 9+}. *

* dns cache is {@link InetAddress#cache}. * @@ -31,9 +32,9 @@ * @author Jerry Lee (oldratlee at gmail dot com) * @since 1.6.0 */ -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault -public final class InetAddressCacheUtilForJava9Plus { +@ApiStatus.Internal +@SuppressWarnings("JavadocReference") +public final class InetAddressCacheUtilForNew { /** * {@link InetAddress.CachedAddresses} *

@@ -77,7 +78,15 @@ private static Object newCachedAddresses(String host, String[] ips, long expirat // double check if (constructorOfInetAddress$CachedAddresses != null) return constructorOfInetAddress$CachedAddresses; - final Class clazz = Class.forName(inetAddress$CachedAddresses_ClassName); + Class clazz; + + try { + clazz = Class.forName(inetAddress$CachedAddresses_ClassName); + } catch (ClassNotFoundException e) { + // jdk 21 support + // due to https://github.com/openjdk/jdk/commit/8b127262a3dff9c4420945e902f6a688f8d05e2e + clazz = Class.forName(inetAddress$CachedLookup_ClassName); + } // InetAddress.CacheEntry has only one constructor: // @@ -86,6 +95,8 @@ private static Object newCachedAddresses(String host, String[] ips, long expirat // https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/share/classes/java/net/InetAddress.java#l783 // code in jdk 11: // https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/java/net/InetAddress.java#l787 + // code in jdk 21: + // https://github.com/openjdk/jdk/blob/jdk-21-ga/src/java.base/share/classes/java/net/InetAddress.java#L979 final Constructor constructor = clazz.getDeclaredConstructors()[0]; constructor.setAccessible(true); @@ -120,7 +131,7 @@ private static void removeHostFromExpirySetOfInetAddress(String host) private static String getHostOfInetAddress$CacheAddress(Object cachedAddresses) throws NoSuchFieldException, IllegalAccessException { if (hostFieldOfInetAddress$CacheAddress == null) { - synchronized (InetAddressCacheUtilForJava9Plus.class) { + synchronized (InetAddressCacheUtilForNew.class) { if (hostFieldOfInetAddress$CacheAddress == null) { // double check final Field f = cachedAddresses.getClass().getDeclaredField("host"); f.setAccessible(true); @@ -169,7 +180,7 @@ private static Object[] getCacheAndExpirySetOfInetAddress0() throws NoSuchFieldException, IllegalAccessException { if (ADDRESS_CACHE_AND_EXPIRY_SET != null) return ADDRESS_CACHE_AND_EXPIRY_SET; - synchronized (InetAddressCacheUtilForJava9Plus.class) { + synchronized (InetAddressCacheUtilForNew.class) { if (ADDRESS_CACHE_AND_EXPIRY_SET != null) return ADDRESS_CACHE_AND_EXPIRY_SET; final Field cacheField = InetAddress.class.getDeclaredField("cache"); @@ -232,7 +243,10 @@ public static DnsCache listInetAddressCache() final InetAddress[] inetAddresses; final long expiration; - if (addressesClassName.equals(inetAddress$CachedAddresses_ClassName)) { + if (addressesClassName.equals(inetAddress$CachedAddresses_ClassName) + // jdk 21 support + || addressesClassName.equals(inetAddress$CachedLookup_ClassName)) { + inetAddresses = (InetAddress[]) inetAddressesFieldOfInetAddress$CacheAddress.get(addresses); long expiryTimeNanos = expiryTimeFieldOfInetAddress$CacheAddress.getLong(addresses); @@ -251,6 +265,7 @@ public static DnsCache listInetAddressCache() } private static final String inetAddress$CachedAddresses_ClassName = "java.net.InetAddress$CachedAddresses"; + private static final String inetAddress$CachedLookup_ClassName = "java.net.InetAddress$CachedLookup"; private static final String inetAddress$NameServiceAddresses_ClassName = "java.net.InetAddress$NameServiceAddresses"; // Fields of InetAddress$CachedAddresses @@ -266,13 +281,20 @@ public static DnsCache listInetAddressCache() private static void initFieldsOfAddresses() throws ClassNotFoundException, NoSuchFieldException { if (inetAddressesFieldOfInetAddress$CacheAddress != null) return; - synchronized (InetAddressCacheUtilForJava9Plus.class) { + synchronized (InetAddressCacheUtilForNew.class) { if (inetAddressesFieldOfInetAddress$CacheAddress != null) return; /////////////////////////////////////////////// // Fields of InetAddress$CachedAddresses /////////////////////////////////////////////// - final Class cachedAddresses_Class = Class.forName(inetAddress$CachedAddresses_ClassName); + Class cachedAddresses_Class; + + try { + cachedAddresses_Class = Class.forName(inetAddress$CachedAddresses_ClassName); + } catch (ClassNotFoundException e) { + // jdk 21 support + cachedAddresses_Class = Class.forName(inetAddress$CachedLookup_ClassName); + } final Field inetAddressesFiled = cachedAddresses_Class.getDeclaredField("inetAddresses"); inetAddressesFiled.setAccessible(true); @@ -289,6 +311,6 @@ public static void clearInetAddressCache() throws NoSuchFieldException, IllegalA getCacheOfInetAddress().clear(); } - private InetAddressCacheUtilForJava9Plus() { + private InetAddressCacheUtilForNew() { } } diff --git a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8.java b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java similarity index 94% rename from library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8.java rename to library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java index 3e420a19..9bc9f808 100644 --- a/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForJava8.java +++ b/library/src/main/java/com/alibaba/dcm/internal/InetAddressCacheUtilForOld.java @@ -2,10 +2,9 @@ import com.alibaba.dcm.DnsCache; import com.alibaba.dcm.DnsCacheEntry; -import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; +import org.jetbrains.annotations.ApiStatus; import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.GuardedBy; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -17,10 +16,12 @@ import java.util.List; import java.util.Map; -import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.*; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.NEVER_EXPIRATION; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.getIpFromInetAddress; +import static com.alibaba.dcm.internal.InetAddressCacheUtilCommons.toInetAddressArray; /** - * Util class to manipulate dns cache for {@code JDK 8-}. + * Util class to manipulate dns cache for old {@code JDK 8-}. *

* dns cache is {@link InetAddress.Cache#cache} in {@link InetAddress#addressCache}. *

@@ -37,9 +38,9 @@ * @see InetAddress#cacheInitIfNeeded() * @see InetAddress#cacheAddresses(String, InetAddress[], boolean) */ -@ParametersAreNonnullByDefault -@ReturnValuesAreNonnullByDefault -public final class InetAddressCacheUtilForJava8 { +@ApiStatus.Internal +@SuppressWarnings("JavadocReference") +public final class InetAddressCacheUtilForOld { /** * Need convert host to lowercase, see {@link InetAddress#cacheAddresses(String, InetAddress[], boolean)}. */ @@ -134,7 +135,7 @@ private static Map getNegativeCache() private static Map getCacheOfInetAddress$Cache0(Object inetAddressCache) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { if (cacheMapFieldOfInetAddress$Cache == null) { - synchronized (InetAddressCacheUtilForJava8.class) { + synchronized (InetAddressCacheUtilForOld.class) { if (cacheMapFieldOfInetAddress$Cache == null) { // double check final Class clazz = Class.forName("java.net.InetAddress$Cache"); final Field f = clazz.getDeclaredField("cache"); @@ -168,11 +169,12 @@ private static Object getNegativeCacheOfInetAddress() /** * @return {@link InetAddress#addressCache} and {@link InetAddress#negativeCache} */ + @SuppressWarnings("JavaReflectionMemberAccess") private static Object[] getAddressCacheAndNegativeCacheOfInetAddress0() throws NoSuchFieldException, IllegalAccessException { if (ADDRESS_CACHE_AND_NEGATIVE_CACHE != null) return ADDRESS_CACHE_AND_NEGATIVE_CACHE; - synchronized (InetAddressCacheUtilForJava8.class) { + synchronized (InetAddressCacheUtilForOld.class) { // double check if (ADDRESS_CACHE_AND_NEGATIVE_CACHE != null) return ADDRESS_CACHE_AND_NEGATIVE_CACHE; @@ -262,7 +264,7 @@ private static List convert(Map cache) private static void initFieldsOfInetAddress$CacheEntry() throws ClassNotFoundException, NoSuchFieldException { if (expirationFieldOfInetAddress$CacheEntry != null && addressesFieldOfInetAddress$CacheEntry != null) return; - synchronized (InetAddressCacheUtilForJava8.class) { + synchronized (InetAddressCacheUtilForOld.class) { final Class cacheEntryClass = Class.forName("java.net.InetAddress$CacheEntry"); // double check if (expirationFieldOfInetAddress$CacheEntry != null && addressesFieldOfInetAddress$CacheEntry != null) @@ -297,6 +299,6 @@ public static void clearInetAddressCache() } } - private InetAddressCacheUtilForJava8() { + private InetAddressCacheUtilForOld() { } } diff --git a/library/src/main/java/com/alibaba/dcm/internal/IpParserUtil.java b/library/src/main/java/com/alibaba/dcm/internal/IpParserUtil.java index b95b8b3f..f7e4d6c7 100644 --- a/library/src/main/java/com/alibaba/dcm/internal/IpParserUtil.java +++ b/library/src/main/java/com/alibaba/dcm/internal/IpParserUtil.java @@ -10,6 +10,7 @@ final class IpParserUtil { /** * source code is dug from {@link java.net.InetAddress#getAllByName(java.lang.String, java.net.InetAddress)} */ + @SuppressWarnings("JavadocReference") static byte[] ip2ByteArray(String ip) { boolean ipv6Expected = false; if (ip.charAt(0) == '[') { diff --git a/library/src/main/java/com/alibaba/dcm/internal/JavaVersion.java b/library/src/main/java/com/alibaba/dcm/internal/JavaVersion.java deleted file mode 100644 index 1c38ddb1..00000000 --- a/library/src/main/java/com/alibaba/dcm/internal/JavaVersion.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.alibaba.dcm.internal; - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// This source code file is copied and small adopted from commons-lang-3.12.0: -// -// https://github.com/apache/commons-lang/blob/rel/commons-lang-3.12.0/src/main/java/org/apache/commons/lang3/JavaVersion.java -// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - -/** - *

An enum representing all the versions of the Java specification. - * This is intended to mirror available values from the - * java.specification.version System property.

- * - * @since 3.0 - */ -@SuppressWarnings({"unused", "SameParameterValue"}) -enum JavaVersion { - - /** - * The Java version reported by Android. This is not an official Java version number. - */ - JAVA_0_9(1.5f, "0.9"), - - /** - * Java 1.1. - */ - JAVA_1_1(1.1f, "1.1"), - - /** - * Java 1.2. - */ - JAVA_1_2(1.2f, "1.2"), - - /** - * Java 1.3. - */ - JAVA_1_3(1.3f, "1.3"), - - /** - * Java 1.4. - */ - JAVA_1_4(1.4f, "1.4"), - - /** - * Java 1.5. - */ - JAVA_1_5(1.5f, "1.5"), - - /** - * Java 1.6. - */ - JAVA_1_6(1.6f, "1.6"), - - /** - * Java 1.7. - */ - JAVA_1_7(1.7f, "1.7"), - - /** - * Java 1.8. - */ - JAVA_1_8(1.8f, "1.8"), - - /** - * Java 1.9. - * - * @deprecated As of release 3.5, replaced by {@link #JAVA_9} - */ - @Deprecated - JAVA_1_9(9.0f, "9"), - - /** - * Java 9. - * - * @since 3.5 - */ - JAVA_9(9.0f, "9"), - - /** - * Java 10. - * - * @since 3.7 - */ - JAVA_10(10.0f, "10"), - - /** - * Java 11. - * - * @since 3.8 - */ - JAVA_11(11.0f, "11"), - - /** - * Java 12. - * - * @since 3.9 - */ - JAVA_12(12.0f, "12"), - - /** - * Java 13. - * - * @since 3.9 - */ - JAVA_13(13.0f, "13"), - - /** - * Java 14. - * - * @since 3.11 - */ - JAVA_14(14.0f, "14"), - - /** - * Java 15. - * - * @since 3.11 - */ - JAVA_15(15.0f, "15"), - - /** - * Java 16. - * - * @since 3.11 - */ - JAVA_16(16.0f, "16"), - - /** - * Java 17. - * - * @since 3.12.0 - */ - JAVA_17(17.0f, "17"), - - /** - * The most recent java version. Mainly introduced to avoid to break when a new version of Java is used. - */ - JAVA_RECENT(maxVersion(), Float.toString(maxVersion())); - - /** - * The float value. - */ - private final float value; - - /** - * The standard name. - */ - private final String name; - - /** - * Constructor. - * - * @param value the float value - * @param name the standard name, not null - */ - JavaVersion(final float value, final String name) { - this.value = value; - this.name = name; - } - - //----------------------------------------------------------------------- - - /** - *

Whether this version of Java is at least the version of Java passed in.

- * - *

For example:
- * {@code myVersion.atLeast(JavaVersion.JAVA_1_4)}

- * - * @param requiredVersion the version to check against, not null - * @return true if this version is equal to or greater than the specified version - */ - public boolean atLeast(final JavaVersion requiredVersion) { - return this.value >= requiredVersion.value; - } - - //----------------------------------------------------------------------- - - /** - *

Whether this version of Java is at most the version of Java passed in.

- * - *

For example:
- * {@code myVersion.atMost(JavaVersion.JAVA_1_4)}

- * - * @param requiredVersion the version to check against, not null - * @return true if this version is equal to or greater than the specified version - * @since 3.9 - */ - public boolean atMost(final JavaVersion requiredVersion) { - return this.value <= requiredVersion.value; - } - - /** - * Transforms the given string with a Java version number to the - * corresponding constant of this enumeration class. This method is used - * internally. - * - * @param nom the Java version as string - * @return the corresponding enumeration constant or null if the - * version is unknown - */ - // helper for static importing - static JavaVersion getJavaVersion(final String nom) { - return get(nom); - } - - /** - * Transforms the given string with a Java version number to the - * corresponding constant of this enumeration class. This method is used - * internally. - * - * @param versionStr the Java version as string - * @return the corresponding enumeration constant or null if the - * version is unknown - */ - static JavaVersion get(final String versionStr) { - if (versionStr == null) { - return null; - } - switch (versionStr) { - case "0.9": - return JAVA_0_9; - case "1.1": - return JAVA_1_1; - case "1.2": - return JAVA_1_2; - case "1.3": - return JAVA_1_3; - case "1.4": - return JAVA_1_4; - case "1.5": - return JAVA_1_5; - case "1.6": - return JAVA_1_6; - case "1.7": - return JAVA_1_7; - case "1.8": - return JAVA_1_8; - case "9": - return JAVA_9; - case "10": - return JAVA_10; - case "11": - return JAVA_11; - case "12": - return JAVA_12; - case "13": - return JAVA_13; - case "14": - return JAVA_14; - case "15": - return JAVA_15; - case "16": - return JAVA_16; - case "17": - return JAVA_17; - } - final float v = toFloatVersion(versionStr); - if ((v - 1.) < 1.) { // then we need to check decimals > .9 - final int firstComma = Math.max(versionStr.indexOf('.'), versionStr.indexOf(',')); - final int end = Math.max(versionStr.length(), versionStr.indexOf(',', firstComma)); - if (Float.parseFloat(versionStr.substring(firstComma + 1, end)) > .9f) { - return JAVA_RECENT; - } - } else if (v > 10) { - return JAVA_RECENT; - } - return null; - } - - //----------------------------------------------------------------------- - - /** - *

The string value is overridden to return the standard name.

- * - *

For example, {@code "1.5"}.

- * - * @return the name, not null - */ - @Override - public String toString() { - return name; - } - - /** - * Gets the Java Version from the system or 99.0 if the {@code java.specification.version} system property is not set. - * - * @return the value of {@code java.specification.version} system property or 99.0 if it is not set. - */ - private static float maxVersion() { - final float v = toFloatVersion(System.getProperty("java.specification.version", "99.0")); - if (v > 0) { - return v; - } - return 99f; - } - - /** - * Parses a float value from a String. - * - * @param value the String to parse. - * @return the float value represented by the string or -1 if the given String can not be parsed. - */ - private static float toFloatVersion(final String value) { - final int defaultReturnValue = -1; - if (value.contains(".")) { - final String[] toParse = value.split("\\."); - if (toParse.length >= 2) { - return toFloat(toParse[0] + '.' + toParse[1], defaultReturnValue); - } - } else { - return toFloat(value, defaultReturnValue); - } - return defaultReturnValue; - } - - /** - *

Convert a {@code String} to a {@code float}, returning a - * default value if the conversion fails.

- * - *

If the string {@code str} is {@code null}, the default - * value is returned.

- * - *
-     *   NumberUtils.toFloat(null, 1.1f)   = 1.0f
-     *   NumberUtils.toFloat("", 1.1f)     = 1.1f
-     *   NumberUtils.toFloat("1.5", 0.0f)  = 1.5f
-     * 
- * - * @param str the string to convert, may be {@code null} - * @param defaultValue the default value - * @return the float represented by the string, or defaultValue - * if conversion fails - * @since 2.1 - */ - private static float toFloat(final String str, final float defaultValue) { - if (str == null) { - return defaultValue; - } - try { - return Float.parseFloat(str); - } catch (final NumberFormatException nfe) { - return defaultValue; - } - } -} diff --git a/library/src/main/java/com/alibaba/dcm/internal/JavaVersionUtil.java b/library/src/main/java/com/alibaba/dcm/internal/JavaVersionUtil.java deleted file mode 100644 index 2c2a62c4..00000000 --- a/library/src/main/java/com/alibaba/dcm/internal/JavaVersionUtil.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.alibaba.dcm.internal; - -/** - * @author antfling (ding_zhengang at hithinksoft dot com) - * @author Jerry Lee (oldratlee at gmail dot com) - * @since 1.6.0 - */ -public final class JavaVersionUtil { - public static boolean isJavaVersionAtMost8() { - return JAVA_SPECIFICATION_VERSION_AS_ENUM.atMost(JavaVersion.JAVA_1_8); - } - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // Blow source code is copied from commons-lang-3.12.0: - // - // https://github.com/apache/commons-lang/blob/rel/commons-lang-3.12.0/src/main/java/org/apache/commons/lang3/SystemUtils.java - // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - private static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version"); - private static final JavaVersion JAVA_SPECIFICATION_VERSION_AS_ENUM = JavaVersion.get(JAVA_SPECIFICATION_VERSION); - - @SuppressWarnings({"CommentedOutCode", "SameParameterValue"}) - private static String getSystemProperty(final String property) { - try { - return System.getProperty(property); - } catch (final SecurityException ex) { - // we are not allowed to look at this property - // System.err.println("Caught a SecurityException reading the system property '" + property - // + "'; the SystemUtils property value will default to null."); - return null; - } - } - - private JavaVersionUtil() { - } -} diff --git a/library/src/main/java/com/alibaba/dcm/package-info.java b/library/src/main/java/com/alibaba/dcm/package-info.java index 59b37239..9e84aa65 100644 --- a/library/src/main/java/com/alibaba/dcm/package-info.java +++ b/library/src/main/java/com/alibaba/dcm/package-info.java @@ -4,4 +4,13 @@ * @author Jerry Lee (oldratlee at gmail dot com) * @see com.alibaba.dcm.DnsCacheManipulator */ +@DefaultAnnotation(NonNull.class) +@ParametersAreNonnullByDefault +@ReturnValuesAreNonnullByDefault package com.alibaba.dcm; + +import edu.umd.cs.findbugs.annotations.DefaultAnnotation; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/library/src/test/java/com/alibaba/dcm/DnsCacheManipulatorTests.kt b/library/src/test/java/com/alibaba/dcm/DnsCacheManipulatorTests.kt index b160a6de..cfa58e6f 100644 --- a/library/src/test/java/com/alibaba/dcm/DnsCacheManipulatorTests.kt +++ b/library/src/test/java/com/alibaba/dcm/DnsCacheManipulatorTests.kt @@ -1,17 +1,14 @@ package com.alibaba.dcm -import com.alibaba.dcm.internal.JavaVersionUtil +import com.alibaba.dcm.internal.InetAddressCacheUtilCommons.isNewInetAddressImpl import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.AnnotationSpec -import io.kotest.matchers.collections.shouldBeEmpty -import io.kotest.matchers.collections.shouldContainExactly -import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder -import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.collections.* import io.kotest.matchers.longs.shouldBeBetween import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.shouldBe import io.kotest.matchers.types.shouldNotBeSameInstanceAs - +import kotlin.io.path.writeText private const val IP1 = "42.42.42.1" private const val IP2 = "42.42.42.2" @@ -31,9 +28,11 @@ class DnsCacheManipulatorTests : AnnotationSpec() { // System Properties // https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") - System.out.printf("Env info:%njava home: %s%njdk version: %s%n", - System.getProperty("java.home"), - System.getProperty("java.version")) + System.out.printf( + "Env info:%njava home: %s%njdk version: %s%n", + System.getProperty("java.home"), + System.getProperty("java.version") + ) println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") } @@ -237,10 +236,10 @@ class DnsCacheManipulatorTests : AnnotationSpec() { // 3. touch dns cache with external other host operation ////////////////////////////////////////////////// EXISTED_DOMAIN.lookupIpByName() - if (JavaVersionUtil.isJavaVersionAtMost8()) { - shouldContainOnlyOneNegativeCacheWitchExpirationBetween(tick, tick + 1020) - } else { + if (isNewInetAddressImpl()) { DnsCacheManipulator.listDnsNegativeCache().shouldBeEmpty() + } else { + shouldContainOnlyOneNegativeCacheWitchExpirationBetween(tick, tick + 1020) } ////////////////////////////////////////////////// @@ -274,13 +273,13 @@ class DnsCacheManipulatorTests : AnnotationSpec() { } @Test - fun test_loadDnsCacheConfig_fromMyConfig() { + fun test_loadDnsCacheConfig_fromMyConfigClassPath() { DnsCacheManipulator.loadDnsCacheConfig("my-dns-cache.properties") "www.hello2.com".lookupIpByName() shouldBe IP2 } @Test - fun test_multi_ips_in_config_file() { + fun test_multi_ips_in_config_file_classpath() { DnsCacheManipulator.loadDnsCacheConfig("dns-cache-multi-ips.properties") val host = "www.hello-multi-ips.com" @@ -297,11 +296,32 @@ class DnsCacheManipulatorTests : AnnotationSpec() { } @Test - fun test_configNotFound() { + fun test_configNotFound_classpath() { val ex = shouldThrow { DnsCacheManipulator.loadDnsCacheConfig("not-existed.properties") } ex.message shouldBe "Fail to find not-existed.properties on classpath!" } + + @Test + fun test_loadDnsCacheConfig_fromMyConfigFileSystem() { + val tempFile = kotlin.io.path.createTempFile("dns-cache-test", ".properties") + tempFile.writeText("www.hello2.com $IP2") + tempFile.toFile().deleteOnExit() + + DnsCacheManipulator.loadDnsCacheConfigFromFileSystem(tempFile.toAbsolutePath().toString()) + "www.hello2.com".lookupIpByName() shouldBe IP2 + } + + @Test + fun test_configNotFound_fileSystem() { + val ex = shouldThrow { + DnsCacheManipulator.loadDnsCacheConfigFromFileSystem("not-existed.properties") + } + + ex.message shouldBeIn arrayOf( + "Fail to loadDnsCacheConfig from not-existed.properties, cause: java.io.FileNotFoundException: not-existed.properties (No such file or directory)", + "Fail to loadDnsCacheConfig from not-existed.properties, cause: java.io.FileNotFoundException: not-existed.properties (The system cannot find the file specified)") + } } diff --git a/library/src/test/java/com/alibaba/dcm/Util.kt b/library/src/test/java/com/alibaba/dcm/Util.kt index afa8ef7a..26904099 100644 --- a/library/src/test/java/com/alibaba/dcm/Util.kt +++ b/library/src/test/java/com/alibaba/dcm/Util.kt @@ -1,6 +1,6 @@ package com.alibaba.dcm -import com.alibaba.dcm.internal.JavaVersionUtil.isJavaVersionAtMost8 +import com.alibaba.dcm.internal.InetAddressCacheUtilCommons.isNewInetAddressImpl import com.alibaba.dcm.internal.TestTimeUtil.NEVER_EXPIRATION_NANO_TIME_TO_TIME_MILLIS import io.kotest.assertions.fail import io.kotest.assertions.throwables.shouldThrow @@ -54,22 +54,22 @@ infix fun DnsCacheEntry?.shouldBeEqual(expected: DnsCacheEntry?) { } infix fun String.shouldBeEqualAsHostName(expected: String) { - if (isJavaVersionAtMost8()) { - // hard-coded test logic for jdk 8- + if (isNewInetAddressImpl()) { + this shouldBe expected + } else { + // hard-coded test logic for old jdk 8- // host name is unified to lower case by InetAddress this shouldBeEqualIgnoringCase expected - } else { - this shouldBe expected } } private infix fun Long.shouldBeEqualAsExpiration(expected: Long) { if (expected == Long.MAX_VALUE) { - if (isJavaVersionAtMost8()) { - this shouldBe expected - } else { - // hard-coded test logic for jdk 9+ + if (isNewInetAddressImpl()) { + // hard-coded test logic for new jdk 9+ this.shouldBeEqualsWithTolerance(NEVER_EXPIRATION_NANO_TIME_TO_TIME_MILLIS, 5) + } else { + this shouldBe expected } } else { this shouldBe expected diff --git a/library/src/test/java/com/alibaba/dcm/internal/JavaVersionUtilTests.kt b/library/src/test/java/com/alibaba/dcm/internal/JavaVersionUtilTests.kt deleted file mode 100644 index 7fa50881..00000000 --- a/library/src/test/java/com/alibaba/dcm/internal/JavaVersionUtilTests.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.alibaba.dcm.internal - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.shouldBe -import org.apache.commons.lang3.JavaVersion -import org.apache.commons.lang3.SystemUtils - -class JavaVersionUtilTests : FunSpec({ - test("JavaVersionUtil.isJavaVersionAtMost8") { - JavaVersionUtil.isJavaVersionAtMost8() shouldBe SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_1_8) - } -}) diff --git a/mvnw b/mvnw index 41c0f0c2..bd8896bf 100755 --- a/mvnw +++ b/mvnw @@ -19,292 +19,277 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.3.4 # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac -fi +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 fi fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" +} - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" done + printf %x\\n $h +} - saveddir=`pwd` +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - M2_HOME=`dirname "$PRG"`/.. +die() { + printf %s\\n "$1" >&2 + exit 1 +} - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" fi -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi +mkdir -p -- "${MAVEN_HOME%/*}" -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; fi -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi fi -########################################################################################## -# End of extension -########################################################################################## -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f fi -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 86115719..92450f93 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,3 +1,4 @@ +<# : batch portion @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @@ -18,165 +19,171 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir +@REM Apache Maven Wrapper startup batch script, version 3.3.4 @REM @REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output @REM ---------------------------------------------------------------------------- -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) ) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index 3b497b28..f4434823 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.alibaba dns-cache-manipulator-parent - 1.8.0-SNAPSHOT + 1.x-SNAPSHOT pom ${project.artifactId} 🌏 A tiny lib/tool for setting/viewing java dns. @@ -56,13 +56,15 @@ 1.8 ${maven.compiler.source} UTF-8 + + - 1.7.10 + 2.3.0 ${maven.compiler.source} - 5.9.0 - 5.4.2 + 5.14.1 + 5.8.0 @@ -77,6 +79,12 @@ jsr305 true + + + org.jetbrains + annotations + true + @@ -118,22 +126,22 @@ commons-cli commons-cli - 1.5.0 + 1.11.0 commons-io commons-io - 2.11.0 + 2.21.0 org.apache.commons commons-lang3 - 3.12.0 + 3.20.0 org.apache.maven maven-artifact - 3.8.6 + 3.9.12 + org.jetbrains + annotations + 26.0.2-1 + true + + @@ -200,7 +216,6 @@ org.jetbrains.kotlin kotlin-maven-plugin - ${kotlin.version} compile @@ -227,6 +242,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -258,7 +274,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true ossrh @@ -269,12 +285,13 @@ + org.apache.maven.plugins maven-enforcer-plugin - 3.1.0 + 3.6.2 enforce-maven @@ -292,66 +309,103 @@ + + enforce-property + + enforce + + + + + + project.version + ^\d\.\d+\.\d+(-(Alpha|Beta|RC)\d+)?$|^\d(\.\d+)?\.(\d+|x)-SNAPSHOT$ + "Project version(${project.version}) format is invalid!" + + + true + + - - - org.codehaus.mojo - versions-maven-plugin - 2.12.0 - - file://${maven.multiModuleProjectDirectory}/library/src/versions-rules.xml - false - -
+ org.apache.maven.plugins maven-clean-plugin - 3.2.0 + 3.5.0 + org.apache.maven.plugins maven-resources-plugin - 3.3.0 + 3.4.0 + org.apache.maven.plugins maven-jar-plugin - 3.2.2 + 3.5.0 + org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.4.0 + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + -Werror + -Xjsr305=warn + + + + + org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.14.1 + + + + -Xlint:unchecked + -J-Duser.language=en_us + + + org.apache.maven.plugins maven-javadoc-plugin - 3.4.1 + 3.12.0 + org.apache.maven.plugins maven-surefire-plugin - 2.22.2 + 3.5.4 + + @{argLine} -Duser.language=en -Duser.country=US + + org.apache.maven.plugins maven-assembly-plugin - 3.4.2 + 3.8.0 + org.apache.maven.plugins maven-site-plugin - 3.12.1 + 3.21.0 + org.apache.maven.plugins maven-install-plugin - 3.0.1 + 3.1.4 + org.apache.maven.plugins maven-deploy-plugin - 3.0.0 + 3.1.4 @@ -369,6 +423,7 @@ + org.apache.maven.plugins maven-source-plugin @@ -398,6 +453,7 @@ + org.apache.maven.plugins maven-javadoc-plugin 8 @@ -407,7 +463,6 @@ UTF-8 ${javadoc.default.exclude.packages} - src/api/overview.html all,-missing - - - javax.xml.bind - jaxb-api - 2.3.1 - - - org.jacoco jacoco-maven-plugin - 0.8.8 + 0.8.14 @@ -628,6 +668,7 @@ https://stackoverflow.com/a/18420462/922688 --> + org.apache.maven.plugins maven-enforcer-plugin diff --git a/scripts/.gitignore b/scripts/.gitignore deleted file mode 100644 index 6ca64d9b..00000000 --- a/scripts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -appveyor_token.ps1 diff --git a/scripts/bash-buddy b/scripts/bash-buddy index eb0cb6fc..d4782c9e 160000 --- a/scripts/bash-buddy +++ b/scripts/bash-buddy @@ -1 +1 @@ -Subproject commit eb0cb6fc995ec14ba20b9fca5a7779937212c31f +Subproject commit d4782c9e2d333df1c4ebea050f7423a8fd060811 diff --git a/scripts/clear_appveyor_cache b/scripts/clear_appveyor_cache deleted file mode 100755 index d616eba1..00000000 --- a/scripts/clear_appveyor_cache +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env pwsh - -$appveyor_project = "oldratlee/java-dns-cache-manipulator" - -# https://stackoverflow.com/questions/24649019/how-to-use-confirm-in-powershell -$confirmation = Read-Host "Are you Sure You Want To Clear cache of appveyor project $appveyor_project [y/N]" -if ($confirmation -ne 'y') -{ - Write-Output "do nothing and exit" - exit -} - -# PowerShell: Run command from script's directory - Stack Overflow -# https://stackoverflow.com/questions/4724290 -# $script_path = $MyInvocation.MyCommand.Path -# $script_dir = Split-Path $script_path - -# Equivalent of bash's `source` command in Powershell? - Super User -# https://superuser.com/questions/71446 -# Script scope and dot sourcing - PowerShell | Microsoft Docs -# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scripts#script-scope-and-dot-sourcing -# PowerShell: How to quickly switch to your home directory -# https://sid-500.com/2017/08/03/powershell-how-to-quickly-switch-to-your-home-directory/ -. "$home\.appveyor_token.ps1" -# file appveyor_token.ps1 provide appveyor token. content sample: -# $appveyor_token = xxx - -# https://www.appveyor.com/docs/build-cache/#remove-cache-entry-from-build-config -# https://www.appveyor.com/docs/api/#authentication - -$headers = @{ } -$headers['Authorization'] = "Bearer $appveyor_token" -$headers["Content-type"] = "application/json" -$uri = "https://ci.appveyor.com/api/projects/$appveyor_project/buildcache" - -Invoke-RestMethod -Uri $uri -Headers $headers -Method Delete diff --git a/scripts/codecov b/scripts/codecov deleted file mode 100755 index a236692c..00000000 --- a/scripts/codecov +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -set -eEuo pipefail -cd "$(dirname "$(readlink -f "$0")")" - -source bash-buddy/lib/trap_error_info.sh -source bash-buddy/lib/common_utils.sh - -################################################################################ -# prepare -################################################################################ - -source bash-buddy/lib/prepare_jdks.sh -source bash-buddy/lib/java_build_utils.sh - -################################################################################ -# codecov logic -################################################################################ - -cd .. - -export DCM_AGENT_SUPPRESS_EXCEPTION_STACK=true - -prepare_jdks::switch_to_jdk 11 - -if [ "${1:-}" = "-s" ]; then - jvb::mvn_cmd -Pgen-code-cov jacoco:prepare-agent surefire:test jacoco:report -else - jvb::mvn_cmd -Pgen-code-cov clean test -fi - -prepare_jdks::switch_to_jdk 8 -jvb::mvn_cmd -Pgen-code-cov jacoco:prepare-agent surefire:test jacoco:report coveralls:report - -bash <(curl -s https://codecov.io/bash) diff --git a/scripts/integration_test b/scripts/integration_test index ea39be2f..d836e9f8 100755 --- a/scripts/integration_test +++ b/scripts/integration_test @@ -1,28 +1,64 @@ #!/bin/bash set -eEuo pipefail -cd "$(dirname "$(readlink -f "$0")")" - -source bash-buddy/lib/trap_error_info.sh -source bash-buddy/lib/common_utils.sh +# the canonical path of this script +SELF_PATH=$(realpath -- "$0") +readonly SELF_PATH SELF_DIR=${SELF_PATH%/*} +# cd to script dir +cd "$SELF_DIR" + +readonly BASH_BUDDY_ROOT="$SELF_DIR/bash-buddy" +# shellcheck disable=SC1091 +source "$BASH_BUDDY_ROOT/lib/trap_error_info.sh" +# shellcheck disable=SC1091 +source "$BASH_BUDDY_ROOT/lib/common_utils.sh" +# shellcheck disable=SC1091 +source "$BASH_BUDDY_ROOT/lib/java_utils.sh" +# shellcheck disable=SC1091 +source "$BASH_BUDDY_ROOT/lib/maven_utils.sh" ################################################################################ -# prepare +# ci build logic ################################################################################ +_findJdk8_0_345() { + local JDK_8_LATEST + + # GITHUB_ACTIONS + # Always set to true when GitHub Actions is running the workflow. + # You can use this variable to differentiate when tests are being run locally or by GitHub Actions. + # https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables + if [ true = "${GITHUB_ACTIONS:-}" ]; then + JAVA8_0_345_HOME="$( + d="$(echo /opt/hostedtoolcache/*/8.0.345*/x64)" || cu::die "Fail to get java home of v8.0.345!" + cd "$d" || cu::die "Fail to cd java home of v8.0.345($d)!" + pwd + )" + + JDK_8_LATEST="$(echo /usr/lib/jvm/*-8-jdk-*)" + [ "$JDK_8_LATEST" != "$JAVA8_0_345_HOME" ] || cu::die "JDK_8_LATEST($JDK_8_LATEST) is same as JAVA8_0_345_HOME($JAVA8_0_345_HOME), NOT newer java 8 version!" + export JAVA8_HOME="$JDK_8_LATEST" + else + JAVA8_0_345_HOME=$( + cd "$JAVA8_HOME/.."/8.0.345* + pwd + ) + fi + export JAVA8_0_345_HOME +} +_findJdk8_0_345 + readonly default_build_jdk_version=11 # shellcheck disable=SC2034 -readonly PREPARE_JDKS_INSTALL_BY_SDKMAN=( +readonly CI_JDKS=( + "$JAVA8_0_345_HOME" 8 "$default_build_jdk_version" 17 - 18 + 21 + 23 ) -source bash-buddy/lib/prepare_jdks.sh - -source bash-buddy/lib/java_build_utils.sh - # here use `install` and `-D performRelease` intended # to check release operations. # @@ -30,39 +66,48 @@ source bash-buddy/lib/java_build_utils.sh # https://stackoverflow.com/questions/25201430 # # shellcheck disable=SC2034 -JVB_MVN_OPTS=( - "${JVB_DEFAULT_MVN_OPTS[@]}" - -DperformRelease -P'!gen-sign' +readonly MVU_MVN_OPTS=( + "${MVU_DEFAULT_MVN_OPTS[@]}" + -DperformRelease -P'!gen-sign' -Pgen-code-cov + # Maven Plugin Validation + # https://maven.apache.org/guides/plugins/validation/index.html + -Dmaven.plugin.validation=NONE + ${CI_MORE_MVN_OPTS:+${CI_MORE_MVN_OPTS}} ) -################################################################################ -# ci build logic -################################################################################ - cd .. ######################################## -# default jdk 11, do build and test +# build and test by default version jdk ######################################## export CI_TEST_MODE=true export DCM_AGENT_SUPPRESS_EXCEPTION_STACK=true -prepare_jdks::switch_to_jdk "$default_build_jdk_version" +jvu::switch_to_jdk "$default_build_jdk_version" -cu::head_line_echo "build and test with Java: $JAVA_HOME" -jvb::mvn_cmd clean install +# shellcheck disable=SC2153 +cu::head_line_echo "build and test with Java $default_build_jdk_version: $JAVA_HOME" +mvu::mvn_cmd clean install ######################################## -# test multi-version java +# test by multi-version jdk ######################################## -for jdk in "${PREPARE_JDKS_INSTALL_BY_SDKMAN[@]}"; do + +SUREFIRE_TEST_GOAL=(surefire:test) +# about CI env var +# https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables +[ "${CI:-}" = true ] && SUREFIRE_TEST_GOAL=(jacoco:prepare-agent "${SUREFIRE_TEST_GOAL[@]}" jacoco:report) +readonly SUREFIRE_TEST_GOAL + +for jdk in "${CI_JDKS[@]}"; do # already tested by above `mvn install` - [ "$default_build_jdk_version" = "$jdk" ] && continue + [ "$jdk" = "$default_build_jdk_version" ] && continue - prepare_jdks::switch_to_jdk "$jdk" + jvu::switch_to_jdk "$jdk" cu::head_line_echo "test with Java: $JAVA_HOME" # just test without build - jvb::mvn_cmd surefire:test + # shellcheck disable=SC2086 + mvu::mvn_cmd "${SUREFIRE_TEST_GOAL[@]}" done diff --git a/tool/pom.xml b/tool/pom.xml index b7c84606..80b11848 100644 --- a/tool/pom.xml +++ b/tool/pom.xml @@ -4,7 +4,7 @@ com.alibaba dns-cache-manipulator-parent - 1.8.0-SNAPSHOT + 1.x-SNAPSHOT ../pom.xml @@ -13,7 +13,7 @@ Java Dns Cache Manipulator(DCM) Tool 🌏 a tiny tool for setting/viewing dns of running JVM process. - support Java 8/11/17/18/19, support IPv6. + support Java 8~21, support IPv6. https://github.com/alibaba/java-dns-cache-manipulator 2015 @@ -92,8 +92,8 @@ https://maven.apache.org/plugins/maven-assembly-plugin/usage.html https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html --> + org.apache.maven.plugins maven-assembly-plugin - 3.4.2 dcm-${project.version} false diff --git a/tool/src/assembly/assembly.xml b/tool/src/assembly/assembly.xml index 025c4568..6964eda6 100644 --- a/tool/src/assembly/assembly.xml +++ b/tool/src/assembly/assembly.xml @@ -12,6 +12,7 @@ com.github.spotbugs:* com.google.code.findbugs:* + org.jetbrains:annotations:* dependencies diff --git a/tool/src/api/overview.html b/tool/src/javadoc/overview.html similarity index 100% rename from tool/src/api/overview.html rename to tool/src/javadoc/overview.html diff --git a/tool/src/main/java/com/alibaba/dcm/tool/DcmTool.java b/tool/src/main/java/com/alibaba/dcm/tool/DcmTool.java index 0daa7b2d..b85b07f0 100644 --- a/tool/src/main/java/com/alibaba/dcm/tool/DcmTool.java +++ b/tool/src/main/java/com/alibaba/dcm/tool/DcmTool.java @@ -133,10 +133,10 @@ private static boolean printDcmResult(@Nonnull String tmpFile) throws IOExceptio @Nonnull private static String getConfig(@Nonnull String name) { String var = System.getenv(name); - if (var == null || var.trim().length() == 0) { + if (var == null || var.trim().isEmpty()) { var = System.getProperty(name); } - if (var == null || var.trim().length() == 0) { + if (var == null || var.trim().isEmpty()) { throw new IllegalStateException("fail to var " + name + ", is absent or blank string!"); } diff --git a/tool/src/test/java/com/alibaba/dcm/tool/DcmToolTests.kt b/tool/src/test/java/com/alibaba/dcm/tool/DcmToolTests.kt index cb38dd43..38642ce6 100644 --- a/tool/src/test/java/com/alibaba/dcm/tool/DcmToolTests.kt +++ b/tool/src/test/java/com/alibaba/dcm/tool/DcmToolTests.kt @@ -19,7 +19,7 @@ class DcmToolTests : AnnotationSpec() { // Ignore "attach to current VM" test for jdk 9+, since java 9+ does not support // "java.io.IOException: Can not attach to current VM" - @Suppress("OverridingDeprecatedMember") + @Suppress("OVERRIDE_DEPRECATION") override fun defaultTestCaseConfig(): TestCaseConfig = TestCaseConfig(enabled = SystemUtils.IS_JAVA_1_8)