diff --git a/build.gradle b/build.gradle
index ec45db35..2540fb8a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -50,12 +50,13 @@ subprojects {
version = rootProject.version
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
}
compileJava {
if (javaCompiler.get().metadata.languageVersion.canCompileOrRun(10)) {
- options.release = 8
+ options.release = 11
}
}
diff --git a/ci/checkstyle/checkstyle.xml b/ci/checkstyle/checkstyle.xml
deleted file mode 100644
index 92b99a49..00000000
--- a/ci/checkstyle/checkstyle.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ci/checkstyle/java-copyright-header.txt b/ci/checkstyle/java-copyright-header.txt
deleted file mode 100644
index 5bc18a3d..00000000
--- a/ci/checkstyle/java-copyright-header.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-^/\*$
-^ \* Copyright \d\d\d\d .*? All Rights Reserved\.$
-^ \*$
-^ \* SPDX-License-Identifier: Apache-2\.0$
-^ \*/$
\ No newline at end of file
diff --git a/fabric-chaincode-docker/Dockerfile b/fabric-chaincode-docker/Dockerfile
index 144af895..25fbde49 100644
--- a/fabric-chaincode-docker/Dockerfile
+++ b/fabric-chaincode-docker/Dockerfile
@@ -40,8 +40,8 @@ RUN gradle \
fabric-chaincode-shim:publishToMavenLocal \
-x javadoc \
-x test \
- -x checkstyleMain \
- -x checkstyleTest
+ -x pmdMain \
+ -x pmdTest
WORKDIR /root/chaincode-java
# Run the Gradle and Maven commands to generate the wrapper variants
diff --git a/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle b/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle
index 4162e3ae..42a075f9 100644
--- a/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle
+++ b/fabric-chaincode-integration-test/src/contracts/bare-gradle/build.gradle
@@ -7,7 +7,12 @@ group 'org.hyperledger.fabric-chaincode-java'
version '1.0-SNAPSHOT'
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
+
+compileJava {
+ options.compilerArgs.addAll(['--release', '11'])
}
repositories {
diff --git a/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml b/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml
index fc475a98..9740748d 100644
--- a/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml
+++ b/fabric-chaincode-integration-test/src/contracts/bare-maven/pom.xml
@@ -7,7 +7,7 @@
- 8
+ 11UTF-8UTF-8
diff --git a/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle b/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle
index 7d5ec564..a4d9619d 100644
--- a/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle
+++ b/fabric-chaincode-integration-test/src/contracts/fabric-ledger-api/build.gradle
@@ -7,13 +7,12 @@ group 'org.hyperledger.fabric-chaincode-java'
version '1.0-SNAPSHOT'
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
}
compileJava {
- if (javaCompiler.get().metadata.languageVersion.canCompileOrRun(10)) {
- options.release = 8
- }
+ options.compilerArgs.addAll(['--release', '11'])
}
repositories {
diff --git a/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle b/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle
index a57bef8b..79ef721a 100644
--- a/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle
+++ b/fabric-chaincode-integration-test/src/contracts/fabric-shim-api/build.gradle
@@ -7,13 +7,12 @@ group 'org.hyperledger.fabric-chaincode-java'
version '1.0-SNAPSHOT'
java {
- sourceCompatibility = JavaVersion.VERSION_1_8
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
}
compileJava {
- if (javaCompiler.get().metadata.languageVersion.canCompileOrRun(10)) {
- options.release = 8
- }
+ options.compilerArgs.addAll(['--release', '11'])
}
repositories {
diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.jar b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.jar
index bf82ff01..7967f30d 100644
Binary files a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.jar and b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.properties b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.properties
index dc3affce..9548abd8 100644
--- a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.properties
+++ b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/.mvn/wrapper/maven-wrapper.properties
@@ -6,7 +6,7 @@
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# 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
@@ -14,5 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-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/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
+wrapperVersion=3.3.2
+distributionType=bin
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar
diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw
index 41c0f0c2..5e9618ca 100755
--- a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw
+++ b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw
@@ -19,7 +19,7 @@
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
-# Maven Start Up Batch script
+# Apache Maven Wrapper startup batch script, version 3.3.2
#
# Required ENV vars:
# ------------------
@@ -27,284 +27,306 @@
#
# 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
# ----------------------------------------------------------------------------
-if [ -z "$MAVEN_SKIP_RC" ] ; then
+if [ -z "$MAVEN_SKIP_RC" ]; then
- if [ -f /etc/mavenrc ] ; then
+ if [ -f /usr/local/etc/mavenrc ]; then
+ . /usr/local/etc/mavenrc
+ fi
+
+ if [ -f /etc/mavenrc ]; then
. /etc/mavenrc
fi
- if [ -f "$HOME/.mavenrc" ] ; then
+ if [ -f "$HOME/.mavenrc" ]; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
-cygwin=false;
-darwin=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"
- fi
+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
+ JAVA_HOME="$(/usr/libexec/java_home)"
+ export JAVA_HOME
+ else
+ JAVA_HOME="/Library/Java/Home"
+ export JAVA_HOME
fi
- ;;
+ fi
+ ;;
esac
-if [ -z "$JAVA_HOME" ] ; then
- if [ -r /etc/gentoo-release ] ; then
- JAVA_HOME=`java-config --jre-home`
+if [ -z "$JAVA_HOME" ]; then
+ if [ -r /etc/gentoo-release ]; then
+ JAVA_HOME=$(java-config --jre-home)
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
- done
-
- saveddir=`pwd`
-
- M2_HOME=`dirname "$PRG"`/..
-
- # make it fully qualified
- M2_HOME=`cd "$M2_HOME" && pwd`
-
- cd "$saveddir"
- # echo Using m2 at $M2_HOME
-fi
-
# 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"`
+if $cygwin; then
+ [ -n "$JAVA_HOME" ] \
+ && JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
+ [ -n "$CLASSPATH" ] \
+ && CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# 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 $mingw; then
+ [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \
+ && JAVA_HOME="$(
+ cd "$JAVA_HOME" || (
+ echo "cannot cd into $JAVA_HOME." >&2
+ exit 1
+ )
+ pwd
+ )"
fi
if [ -z "$JAVA_HOME" ]; then
- javaExecutable="`which javac`"
- if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; 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"
+ 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\"`"
+ javaExecutable="$(readlink -f "$javaExecutable")"
fi
- javaHome="`dirname \"$javaExecutable\"`"
- javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ javaHome="$(dirname "$javaExecutable")"
+ javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
-if [ -z "$JAVACMD" ] ; then
- if [ -n "$JAVA_HOME" ] ; then
- if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+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`"
+ JAVACMD="$(
+ \unset -f command 2>/dev/null
+ \command -v java
+ )"
fi
fi
-if [ ! -x "$JAVACMD" ] ; then
+if [ ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
-if [ -z "$JAVA_HOME" ] ; then
- echo "Warning: JAVA_HOME environment variable is not set."
+if [ -z "$JAVA_HOME" ]; then
+ echo "Warning: JAVA_HOME environment variable is not set." >&2
fi
-CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
-
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
-
- if [ -z "$1" ]
- then
- echo "Path not specified to find_maven_basedir"
+ if [ -z "$1" ]; then
+ echo "Path not specified to find_maven_basedir" >&2
return 1
fi
basedir="$1"
wdir="$1"
- while [ "$wdir" != '/' ] ; do
- if [ -d "$wdir"/.mvn ] ; then
+ while [ "$wdir" != '/' ]; do
+ if [ -d "$wdir"/.mvn ]; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
- wdir=`cd "$wdir/.."; pwd`
+ wdir=$(
+ cd "$wdir/.." || exit 1
+ pwd
+ )
fi
# end of workaround
done
- echo "${basedir}"
+ printf '%s' "$(
+ cd "$basedir" || exit 1
+ pwd
+ )"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
- echo "$(tr -s '\n' ' ' < "$1")"
+ # Remove \r in case we run on Windows within Git Bash
+ # and check out the repository with auto CRLF management
+ # enabled. Otherwise, we may read lines that are delimited with
+ # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+ # splitting rules.
+ tr -s '\r\n' ' ' <"$1"
+ fi
+}
+
+log() {
+ if [ "$MVNW_VERBOSE" = true ]; then
+ printf '%s\n' "$1"
fi
}
-BASE_DIR=`find_maven_basedir "$(pwd)"`
+BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
- exit 1;
+ exit 1
fi
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
+export MAVEN_PROJECTBASEDIR
+log "$MAVEN_PROJECTBASEDIR"
+
##########################################################################################
# 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
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+ log "Found $wrapperJarPath"
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"
+ log "Couldn't find $wrapperJarPath, downloading it ..."
+
+ if [ -n "$MVNW_REPOURL" ]; then
+ wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+ else
+ wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+ fi
+ while IFS="=" read -r key value; do
+ # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+ safeValue=$(echo "$value" | tr -d '\r')
+ case "$key" in wrapperUrl)
+ wrapperUrl="$safeValue"
+ break
+ ;;
+ esac
+ done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+ log "Downloading from: $wrapperUrl"
+
+ if $cygwin; then
+ wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+ fi
+
+ if command -v wget >/dev/null; then
+ log "Found wget ... using wget"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
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"
+ elif command -v curl >/dev/null; then
+ log "Found curl ... using curl"
+ [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+ else
+ curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
- wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ else
+ log "Falling back to using Java to download"
+ javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
+ # For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
- wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ javaSource=$(cygpath --path --windows "$javaSource")
+ javaClass=$(cygpath --path --windows "$javaClass")
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
-
- 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
+ if [ -e "$javaSource" ]; then
+ if [ ! -e "$javaClass" ]; then
+ log " - Compiling MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/javac" "$javaSource")
+ fi
+ if [ -e "$javaClass" ]; then
+ log " - Running MavenWrapperDownloader.java ..."
+ ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+ fi
fi
+ fi
fi
##########################################################################################
# End of extension
##########################################################################################
-export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-if [ "$MVNW_VERBOSE" = true ]; then
- echo $MAVEN_PROJECTBASEDIR
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+ case "$key" in wrapperSha256Sum)
+ wrapperSha256Sum=$value
+ break
+ ;;
+ esac
+done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+ wrapperSha256Result=false
+ if command -v sha256sum >/dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ elif command -v shasum >/dev/null; then
+ if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then
+ wrapperSha256Result=true
+ fi
+ else
+ echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
+ echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2
+ exit 1
+ fi
+ if [ $wrapperSha256Result = false ]; then
+ echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+ echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+ echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+ exit 1
+ fi
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"`
+ [ -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")
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 $@"
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw.cmd b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw.cmd
index 86115719..1204076a 100644
--- a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw.cmd
+++ b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/mvnw.cmd
@@ -1,182 +1,206 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@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 ----------------------------------------------------------------------------
-
-@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%
- )
-)
-@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%
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Apache Maven Wrapper startup batch script, version 3.3.2
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@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 ----------------------------------------------------------------------------
+
+@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 "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\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. >&2
+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. >&2
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo. >&2
+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. >&2
+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 WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET WRAPPER_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 WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
+ )
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Couldn't find %WRAPPER_JAR%, downloading it ...
+ echo Downloading from: %WRAPPER_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('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
+ "}"
+ if "%MVNW_VERBOSE%" == "true" (
+ echo Finished downloading %WRAPPER_JAR%
+ )
+)
+@REM End of extension
+
+@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
+SET WRAPPER_SHA_256_SUM=""
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
+)
+IF NOT %WRAPPER_SHA_256_SUM%=="" (
+ powershell -Command "&{"^
+ "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^
+ "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
+ "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
+ " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
+ " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
+ " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
+ " exit 1;"^
+ "}"^
+ "}"
+ if ERRORLEVEL 1 goto error
+)
+
+@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 "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\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%
+
+cmd /C exit /B %ERROR_CODE%
diff --git a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml
index e70ceed1..f9e59238 100644
--- a/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml
+++ b/fabric-chaincode-integration-test/src/contracts/wrapper-maven/pom.xml
@@ -7,7 +7,7 @@
- 8
+ 11UTF-8UTF-8
diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java
index b05dbf81..f63dc8b6 100644
--- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java
+++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/contractinstall/ContractInstallTest.java
@@ -22,7 +22,7 @@ public static void setUp() throws Exception {
}
@Test
- public void TestInstall() {
+ public void testInstall() {
InvokeHelper helper = InvokeHelper.newHelper("baregradlecc", "sachannel");
String text = helper.invoke("org1", "whoami");
diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java
index ad856978..815ab88c 100644
--- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java
+++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/ledgertests/LedgerIntegrationTest.java
@@ -23,7 +23,7 @@ public static void setUp() throws Exception {
}
@Test
- public void TestLedgers() {
+ public void testLedgers() {
InvokeHelper helper = InvokeHelper.newHelper("ledgercc", "sachannel");
String text = helper.invoke("org1", "accessLedgers");
diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java
index 94ebb378..93923ac6 100644
--- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java
+++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SACCIntegrationTest.java
@@ -22,7 +22,7 @@ public static void setUp() throws Exception {
}
@Test
- public void TestLedger() {
+ public void testLedger() {
InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel");
String text = helper.invoke("org1", "putBulkStates");
diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java
index 32e8ec56..02ffb16c 100644
--- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java
+++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/shimtests/SBECCIntegrationTest.java
@@ -22,7 +22,7 @@ public static void setUp() throws Exception {
}
@Test
- public void RunSBE_pub_setget() {
+ public void runSBE_pub_setget() {
final String mode = "pub";
final InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel");
@@ -85,7 +85,7 @@ public void RunSBE_pub_setget() {
}
@Test
- public void RunSBE_priv() {
+ public void runSBE_priv() {
final String mode = "priv";
final InvokeHelper helper = InvokeHelper.newHelper("shimcc", "sachannel");
diff --git a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java
index 8483446e..916f31ea 100644
--- a/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java
+++ b/fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/util/FabricState.java
@@ -9,19 +9,13 @@
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.Semaphore;
import org.hyperleder.fabric.shim.integration.util.Bash.BashBuilder;
public final class FabricState {
private static FabricState state;
- private static final Map channelStarted = new HashMap<>();
-
- // sempaphore to protect access
- private static final Semaphore flag = new Semaphore(1);
-
- public static FabricState getState() {
+ public static synchronized FabricState getState() {
if (state == null) {
state = new FabricState();
}
diff --git a/fabric-chaincode-shim/build.gradle b/fabric-chaincode-shim/build.gradle
index b4c50500..5a42b332 100644
--- a/fabric-chaincode-shim/build.gradle
+++ b/fabric-chaincode-shim/build.gradle
@@ -8,22 +8,18 @@ plugins {
id 'maven-publish'
id 'jacoco'
id 'signing'
- id 'checkstyle'
+ id 'pmd'
}
-checkstyle {
- toolVersion '10.18.1'
- configFile file("../ci/checkstyle/checkstyle.xml")
- configProperties = [root_dir: file("..") ]
-}
-checkstyleMain {
- source ='src/main/java'
-}
-checkstyleMain.exclude("**/ChaincodeServerProperties.**")
-checkstyleTest {
- source ='src/test/java'
+pmd {
+ toolVersion = '7.7.0'
+ ruleSetFiles = files('../pmd-ruleset.xml')
+ ruleSets = [] // explicitly set to empty to avoid using the default configuration
+ ignoreFailures = false
}
+pmdTest.enabled = false
+
configurations {
runtimeClasspath {
resolutionStrategy.activateDependencyLocking()
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java
index e1a55c90..35720635 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logger.java
@@ -18,7 +18,7 @@ protected Logger(final String name) {
super(name, null);
// ensure that the parent logger is set
- this.setParent(java.util.logging.Logger.getLogger("org.hyperledger.fabric"));
+ super.setParent(java.util.logging.Logger.getLogger("org.hyperledger.fabric"));
}
/**
@@ -45,9 +45,9 @@ public void debug(final String msg) {
*/
public static Logger getLogger(final Class> class1) {
// important to add the logger to the log manager
- final Logger l = Logger.getLogger(class1.getName());
- LogManager.getLogManager().addLogger(l);
- return l;
+ final Logger result = Logger.getLogger(class1.getName());
+ LogManager.getLogManager().addLogger(result);
+ return result;
}
/** @param message */
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java
index 1d26eaf4..0901d75e 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/Logging.java
@@ -7,8 +7,9 @@
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.LogManager;
@@ -50,7 +51,7 @@ public static String formatError(final Throwable throwable) {
final Throwable cause = throwable.getCause();
if (cause != null) {
buffer.append(".. caused by ..").append(System.lineSeparator());
- buffer.append(Logging.formatError(cause));
+ buffer.append(formatError(cause));
}
return buffer.toString();
@@ -67,11 +68,11 @@ public static void setLogLevel(final String newLevel) {
final LogManager logManager = LogManager.getLogManager();
// slightly cumbersome approach - but the loggers don't have a 'get children'
// so find those that have the correct stem.
- final ArrayList allLoggers = Collections.list(logManager.getLoggerNames());
+ final List allLoggers = Collections.list(logManager.getLoggerNames());
allLoggers.add("org.hyperledger");
allLoggers.stream()
.filter(name -> name.startsWith("org.hyperledger"))
- .map(name -> logManager.getLogger(name))
+ .map(logManager::getLogger)
.forEach(logger -> {
if (logger != null) {
logger.setLevel(l);
@@ -81,7 +82,7 @@ public static void setLogLevel(final String newLevel) {
private static Level mapLevel(final String level) {
if (level != null) {
- switch (level.toUpperCase().trim()) {
+ switch (level.toUpperCase(Locale.getDefault()).trim()) {
case "ERROR":
case "CRITICAL":
return Level.SEVERE;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java
index 4c10f704..2ce5cbbc 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ClientIdentity.java
@@ -30,11 +30,11 @@
* and attributes. Such information is useful in enforcing access control by the chaincode.
*/
public final class ClientIdentity {
- private static Logger logger = Logger.getLogger(ContractRouter.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(ContractRouter.class.getName());
private final String mspId;
private final X509Certificate cert;
- private Map attrs;
+ private final Map attrs;
private final String id;
// special OID used by Fabric to save attributes in x.509 certificates
private static final String FABRIC_CERT_ATTR_OID = "1.2.3.4.5.6.7.8.1";
@@ -47,7 +47,7 @@ public final class ClientIdentity {
* @throws JSONException
* @throws IOException
*/
- public ClientIdentity(final ChaincodeStub stub) throws CertificateException, JSONException, IOException {
+ public ClientIdentity(final ChaincodeStub stub) throws CertificateException, IOException {
final byte[] signingId = stub.getCreator();
// Create a Serialized Identity protobuf
@@ -60,11 +60,12 @@ public ClientIdentity(final ChaincodeStub stub) throws CertificateException, JSO
CertificateFactory.getInstance("X509").generateCertificate(new ByteArrayInputStream(idBytes));
this.cert = cert;
- this.attrs = new HashMap();
// Get the extension where the identity attributes are stored
final byte[] extensionValue = cert.getExtensionValue(FABRIC_CERT_ATTR_OID);
if (extensionValue != null) {
this.attrs = parseAttributes(extensionValue);
+ } else {
+ this.attrs = new HashMap<>();
}
// Populate identity
@@ -100,7 +101,7 @@ public String getMSPID() {
*/
private Map parseAttributes(final byte[] extensionValue) throws IOException {
- final Map attrMap = new HashMap();
+ final Map attrMap = new HashMap<>();
// Create ASN1InputStream from extensionValue
try (ByteArrayInputStream inStream = new ByteArrayInputStream(extensionValue);
@@ -126,7 +127,7 @@ private Map parseAttributes(final byte[] extensionValue) throws
} catch (final JSONException error) {
// creating a JSON object failed
// decoded extensionValue is not a string containing JSON
- logger.error(() -> logger.formatError(error));
+ LOGGER.error(() -> LOGGER.formatError(error));
// return empty map
}
return attrMap;
@@ -142,11 +143,7 @@ private Map parseAttributes(final byte[] extensionValue) throws
* @return {String | null} Value of the attribute or null if the invoking identity does not possess the attribute.
*/
public String getAttributeValue(final String attrName) {
- if (this.attrs.containsKey(attrName)) {
- return this.attrs.get(attrName);
- } else {
- return null;
- }
+ return this.attrs.getOrDefault(attrName, null);
}
/**
@@ -160,11 +157,7 @@ public String getAttributeValue(final String attrName) {
* expected value. Otherwise, returns false.
*/
public boolean assertAttributeValue(final String attrName, final String attrValue) {
- if (!this.attrs.containsKey(attrName)) {
- return false;
- } else {
- return attrValue.equals(this.attrs.get(attrName));
- }
+ return this.attrs.containsKey(attrName) && attrValue.equals(this.attrs.get(attrName));
}
/**
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java
index 64e12a1b..68514adb 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContextFactory.java
@@ -10,14 +10,11 @@
/** Factory to create {@link Context} from {@link ChaincodeStub} by wrapping stub with dynamic proxy. */
public final class ContextFactory {
- private static ContextFactory cf;
+ private static final ContextFactory INSTANCE = new ContextFactory();
/** @return ContextFactory */
- public static synchronized ContextFactory getInstance() {
- if (cf == null) {
- cf = new ContextFactory();
- }
- return cf;
+ public static ContextFactory getInstance() {
+ return INSTANCE;
}
/**
@@ -25,7 +22,6 @@ public static synchronized ContextFactory getInstance() {
* @return Context
*/
public Context createContext(final ChaincodeStub stub) {
- final Context newContext = new Context(stub);
- return newContext;
+ return new Context(stub);
}
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java
index c9bea5fc..e1db9de4 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractInterface.java
@@ -75,7 +75,9 @@ default void unknownTransaction(final Context ctx) {
*
* @param ctx the context as created by {@link #createContext(ChaincodeStub)}.
*/
- default void beforeTransaction(final Context ctx) {}
+ default void beforeTransaction(final Context ctx) {
+ // Nothing by default
+ }
/**
* Invoked once after each transaction.
@@ -86,5 +88,7 @@ default void beforeTransaction(final Context ctx) {}
* @param result The object returned from the transaction function if any. As this is a Java object and therefore
* pass-by-reference it is possible to modify this object.
*/
- default void afterTransaction(final Context ctx, final Object result) {}
+ default void afterTransaction(final Context ctx, final Object result) {
+ // Nothing by default
+ }
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java
index 0219f71d..d7b6f9e5 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRouter.java
@@ -35,7 +35,7 @@
* @see ContractInterface
*/
public final class ContractRouter extends ChaincodeBase {
- private static Logger logger = Logger.getLogger(ContractRouter.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(ContractRouter.class.getName());
private final RoutingRegistry registry;
private final TypeRegistry typeRegistry;
@@ -53,6 +53,7 @@ public final class ContractRouter extends ChaincodeBase {
* @param args
*/
public ContractRouter(final String[] args) {
+ super();
super.initializeLogging();
super.processEnvironmentOptions();
super.processCommandLineOptions(args);
@@ -62,7 +63,7 @@ public ContractRouter(final String[] args) {
Metrics.initialize(props);
Traces.initialize(props);
- logger.fine("ContractRouter");
+ LOGGER.fine("ContractRouter");
registry = new RoutingRegistryImpl();
typeRegistry = TypeRegistry.getRegistry();
@@ -72,15 +73,15 @@ public ContractRouter(final String[] args) {
serializers.findAndSetContents();
} catch (InstantiationException | IllegalAccessException e) {
final ContractRuntimeException cre = new ContractRuntimeException("Unable to locate Serializers", e);
- logger.severe(() -> Logging.formatError(cre));
- throw new RuntimeException(cre);
+ LOGGER.severe(() -> Logging.formatError(cre));
+ throw cre;
}
executor = ExecutionFactory.getInstance().createExecutionService(serializers);
}
/** Locate all the contracts that are available on the classpath. */
- protected void findAllContracts() {
+ void findAllContracts() {
registry.findAndSetContracts(this.typeRegistry);
}
@@ -91,28 +92,29 @@ protected void findAllContracts() {
*
* @throws Exception
*/
+ @SuppressWarnings("PMD.AvoidCatchingGenericException")
void startRouting() {
try {
super.connectToPeer();
} catch (final Exception e) {
- logger.severe(() -> Logging.formatError(e));
- final ContractRuntimeException cre = new ContractRuntimeException("Unable to start routing", e);
- throw cre;
+ LOGGER.severe(() -> Logging.formatError(e));
+ throw new ContractRuntimeException("Unable to start routing", e);
}
}
+ @SuppressWarnings("PMD.AvoidCatchingThrowable")
private Response processRequest(final ChaincodeStub stub) {
- logger.info(() -> "Got invoke routing request");
+ LOGGER.info(() -> "Got invoke routing request");
try {
- if (stub.getStringArgs().size() > 0) {
- logger.info(() -> "Got the invoke request for:" + stub.getFunction() + " " + stub.getParameters());
- final InvocationRequest request = ExecutionFactory.getInstance().createRequest(stub);
- final TxFunction txFn = getRouting(request);
- logger.info(() -> "Got routing:" + txFn.getRouting());
- return executor.executeRequest(txFn, request, stub);
- } else {
+ if (stub.getStringArgs().isEmpty()) {
return ResponseUtils.newSuccessResponse();
}
+
+ LOGGER.info(() -> "Got the invoke request for:" + stub.getFunction() + " " + stub.getParameters());
+ final InvocationRequest request = ExecutionFactory.getInstance().createRequest(stub);
+ final TxFunction txFn = getRouting(request);
+ LOGGER.info(() -> "Got routing:" + txFn.getRouting());
+ return executor.executeRequest(txFn, request, stub);
} catch (final Throwable throwable) {
return ResponseUtils.newErrorResponse(throwable);
}
@@ -139,7 +141,7 @@ TxFunction getRouting(final InvocationRequest request) {
if (registry.containsRoute(request)) {
return registry.getTxFn(request);
} else {
- logger.fine(() -> "Namespace is " + request);
+ LOGGER.fine(() -> "Namespace is " + request);
final ContractDefinition contract = registry.getContract(request.getNamespace());
return contract.getUnknownRoute();
}
@@ -150,34 +152,35 @@ TxFunction getRouting(final InvocationRequest request) {
*
* @param args
*/
+ @SuppressWarnings("PMD.SignatureDeclareThrowsException")
public static void main(final String[] args) throws Exception {
final ContractRouter cfc = new ContractRouter(args);
cfc.findAllContracts();
- logger.fine(cfc.getRoutingRegistry().toString());
+ LOGGER.fine(() -> cfc.getRoutingRegistry().toString());
// Create the Metadata ahead of time rather than have to produce every
// time
MetadataBuilder.initialize(cfc.getRoutingRegistry(), cfc.getTypeRegistry());
- logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString());
+ LOGGER.info(() -> "Metadata follows:" + MetadataBuilder.debugString());
// check if this should be running in client or server mode
if (cfc.isServer()) {
- logger.info("Starting chaincode as server");
+ LOGGER.info("Starting chaincode as server");
ChaincodeServer chaincodeServer = new NettyChaincodeServer(cfc, cfc.getChaincodeServerConfig());
chaincodeServer.start();
} else {
- logger.info("Starting chaincode as client");
+ LOGGER.info("Starting chaincode as client");
cfc.startRouting();
}
}
- protected TypeRegistry getTypeRegistry() {
+ TypeRegistry getTypeRegistry() {
return this.typeRegistry;
}
- protected RoutingRegistry getRoutingRegistry() {
+ RoutingRegistry getRoutingRegistry() {
return this.registry;
}
@@ -189,10 +192,10 @@ protected RoutingRegistry getRoutingRegistry() {
public void startRouterWithChaincodeServer(final ChaincodeServer chaincodeServer)
throws IOException, InterruptedException {
findAllContracts();
- logger.fine(getRoutingRegistry().toString());
+ LOGGER.fine(() -> getRoutingRegistry().toString());
MetadataBuilder.initialize(getRoutingRegistry(), getTypeRegistry());
- logger.info(() -> "Metadata follows:" + MetadataBuilder.debugString());
+ LOGGER.info(() -> "Metadata follows:" + MetadataBuilder.debugString());
chaincodeServer.start();
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java
index b51c218f..78d559a2 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/ContractRuntimeException.java
@@ -14,6 +14,8 @@
*
FUTURE At some future point we wish to add more diagnostic information into this, for example current tx id
*/
public class ContractRuntimeException extends ChaincodeException {
+ /** Generated serial version id. */
+ private static final long serialVersionUID = -884373036398750450L;
/** @param string */
public ContractRuntimeException(final String string) {
@@ -32,7 +34,4 @@ public ContractRuntimeException(final String string, final Throwable cause) {
public ContractRuntimeException(final Throwable cause) {
super(cause);
}
-
- /** Generated serial version id. */
- private static final long serialVersionUID = -884373036398750450L;
}
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java
index fee47eb1..3cd7a5fc 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/ExecutionFactory.java
@@ -12,14 +12,11 @@
import org.hyperledger.fabric.shim.ChaincodeStub;
public class ExecutionFactory {
- private static ExecutionFactory rf;
+ private static final ExecutionFactory INSTANCE = new ExecutionFactory();
/** @return ExecutionFactory */
public static ExecutionFactory getInstance() {
- if (rf == null) {
- rf = new ExecutionFactory();
- }
- return rf;
+ return INSTANCE;
}
/**
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java
index c1c99591..ac2e33b9 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java
@@ -11,8 +11,6 @@
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
-import java.nio.charset.StandardCharsets;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.hyperledger.fabric.Logger;
@@ -26,15 +24,13 @@
import org.json.JSONException;
import org.json.JSONObject;
-/** Used as a the default serialisation for transmission from SDK to Contract. */
+/** Used as the default serialisation for transmission from SDK to Contract. */
@Serializer()
+@SuppressWarnings({"PMD.GodClass", "PMD.AvoidLiteralsInIfCondition", "PMD.AvoidDuplicateLiterals"})
public class JSONTransactionSerializer implements SerializerInterface {
- private static Logger logger = Logger.getLogger(JSONTransactionSerializer.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(JSONTransactionSerializer.class.getName());
private final TypeRegistry typeRegistry = TypeRegistry.getRegistry();
- /** Create a new serialiser. */
- public JSONTransactionSerializer() {}
-
/**
* Convert the value supplied to a byte array, according to the TypeSchema.
*
@@ -44,7 +40,7 @@ public JSONTransactionSerializer() {}
*/
@Override
public byte[] toBuffer(final Object value, final TypeSchema ts) {
- logger.debug(() -> "Schema to convert is " + ts);
+ LOGGER.debug(() -> "Schema to convert is " + ts);
byte[] buffer = null;
if (value != null) {
final String type = ts.getType();
@@ -56,7 +52,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) {
break;
case "string":
final String format = ts.getFormat();
- if (format != null && format.contentEquals("uint16")) {
+ if ("utin16".equals(format)) {
buffer = Character.valueOf((char) value).toString().getBytes(UTF_8);
} else {
buffer = ((String) value).getBytes(UTF_8);
@@ -66,7 +62,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) {
case "integer":
case "boolean":
default:
- buffer = (value).toString().getBytes(UTF_8);
+ buffer = value.toString().getBytes(UTF_8);
}
} else {
// at this point we can assert that the value is
@@ -76,7 +72,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) {
// it should have
final DataTypeDefinition dtd = this.typeRegistry.getDataType(ts);
final Set keySet = dtd.getProperties().keySet();
- final String[] propNames = keySet.toArray(new String[keySet.size()]);
+ final String[] propNames = keySet.toArray(new String[0]);
// Note: whilst the current JSON library does pretty much
// everything is required, this part is hard.
@@ -105,6 +101,7 @@ public byte[] toBuffer(final Object value, final TypeSchema ts) {
* @param ts Schema to normalise to
* @return JSONArray
*/
+ @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts) {
JSONArray normalizedArray;
@@ -112,22 +109,12 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts)
final TypeSchema items = ts.getItems();
final String type = items.getType();
- if (type != null && type != "array") {
- // primitive - can return this directly
- normalizedArray = jsonArray;
- } else if (type != null && type == "array") {
- // nested arrays, get the type of what it makes up
- // Need to loop over all elements and normalize each one
- normalizedArray = new JSONArray();
- for (int i = 0; i < jsonArray.length(); i++) {
- normalizedArray.put(i, normalizeArray(jsonArray.getJSONArray(i), items));
- }
- } else {
+ if (null == type) {
// get the permitted propeties in the type,
// then loop over the array and ensure they are correct
final DataTypeDefinition dtd = this.typeRegistry.getDataType(items);
final Set keySet = dtd.getProperties().keySet();
- final String[] propNames = keySet.toArray(new String[keySet.size()]);
+ final String[] propNames = keySet.toArray(new String[0]);
normalizedArray = new JSONArray();
// array of objects
@@ -136,7 +123,18 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts)
final JSONObject obj = new JSONObject(jsonArray.getJSONObject(i), propNames);
normalizedArray.put(i, obj);
}
+ } else if ("array".equals(type)) {
+ // nested arrays, get the type of what it makes up
+ // Need to loop over all elements and normalize each one
+ normalizedArray = new JSONArray();
+ for (int i = 0; i < jsonArray.length(); i++) {
+ normalizedArray.put(i, normalizeArray(jsonArray.getJSONArray(i), items));
+ }
+ } else {
+ // primitive - can return this directly
+ normalizedArray = jsonArray;
}
+
return normalizedArray;
}
@@ -150,15 +148,10 @@ private JSONArray normalizeArray(final JSONArray jsonArray, final TypeSchema ts)
@Override
public Object fromBuffer(final byte[] buffer, final TypeSchema ts) {
try {
- final String stringData = new String(buffer, StandardCharsets.UTF_8);
- Object value = null;
-
- value = convert(stringData, ts);
-
- return value;
+ final String stringData = new String(buffer, UTF_8);
+ return convert(stringData, ts);
} catch (InstantiationException | IllegalAccessException e) {
- final ContractRuntimeException cre = new ContractRuntimeException(e);
- throw cre;
+ throw new ContractRuntimeException(e);
}
}
@@ -172,102 +165,136 @@ public Object fromBuffer(final byte[] buffer, final TypeSchema ts) {
* @return Class for the Object variant
*/
private Class> mapPrimitive(final Class> primitive) {
- String primitiveType;
- final boolean isArray = primitive.isArray();
- if (isArray) {
- primitiveType = primitive.getComponentType().getName();
- } else {
- primitiveType = primitive.getName();
+ if (primitive.isArray()) {
+ return mapArrayPrimitive(primitive);
}
- switch (primitiveType) {
+ return mapBasicPrimitive(primitive);
+ }
+
+ private Class> mapArrayPrimitive(final Class> primitive) {
+ switch (primitive.getComponentType().getName()) {
case "int":
- return isArray ? Integer[].class : Integer.class;
+ return Integer[].class;
case "long":
- return isArray ? Long[].class : Long.class;
+ return Long[].class;
case "float":
- return isArray ? Float[].class : Float.class;
+ return Float[].class;
case "double":
- return isArray ? Double[].class : Double.class;
+ return Double[].class;
case "short":
- return isArray ? Short[].class : Short.class;
+ return Short[].class;
case "byte":
- return isArray ? Byte[].class : Byte.class;
+ return Byte[].class;
case "char":
- return isArray ? Character[].class : Character.class;
+ return Character[].class;
case "boolean":
- return isArray ? Boolean[].class : Boolean.class;
+ return Boolean[].class;
default:
return primitive;
}
}
- /*
- * Internal method to do the conversion
- */
+ private Class> mapBasicPrimitive(final Class> primitive) {
+ switch (primitive.getName()) {
+ case "int":
+ return Integer.class;
+ case "long":
+ return Long.class;
+ case "float":
+ return Float.class;
+ case "double":
+ return Double.class;
+ case "short":
+ return Short.class;
+ case "byte":
+ return Byte.class;
+ case "char":
+ return Character.class;
+ case "boolean":
+ return Boolean.class;
+ default:
+ return primitive;
+ }
+ }
+
+ /** Internal method to do the conversion */
private Object convert(final String stringData, final TypeSchema ts)
- throws IllegalArgumentException, IllegalAccessException, InstantiationException {
- logger.debug(() -> "Schema to convert is " + ts);
+ throws IllegalAccessException, InstantiationException {
+ LOGGER.debug(() -> "Schema to convert is " + ts);
+
String type = ts.getType();
+
String format = null;
- Object value = null;
if (type == null) {
type = "object";
final String ref = ts.getRef();
- format = ref.substring(ref.lastIndexOf("/") + 1);
+ format = ref.substring(ref.lastIndexOf('/') + 1);
}
- if (type.contentEquals("string")) {
- final String strformat = ts.getFormat();
- if (strformat != null && strformat.contentEquals("uint16")) {
- value = stringData.charAt(0);
- } else {
- value = stringData;
- }
- } else if (type.contentEquals("integer")) {
- final String intFormat = ts.getFormat();
- switch (intFormat) {
- case "int32":
- value = Integer.parseInt(stringData);
- break;
- case "int8":
- value = Byte.parseByte(stringData);
- break;
- case "int16":
- value = Short.parseShort(stringData);
- break;
- case "int64":
- value = Long.parseLong(stringData);
- break;
- default:
- throw new RuntimeException("Unknown format for integer " + intFormat);
- }
+ switch (type) {
+ case "string":
+ return convertString(stringData, ts);
+ case "integer":
+ return convertInteger(stringData, ts);
+ case "number":
+ return convertNumber(stringData, ts);
+ case "boolean":
+ return Boolean.parseBoolean(stringData);
+ case "object":
+ return createComponentInstance(format, stringData, ts);
+ case "array":
+ return convertArray(stringData, ts);
+ default:
+ return null;
+ }
+ }
- } else if (type.contentEquals("number")) {
- final String numFormat = ts.getFormat();
- if (numFormat.contentEquals("float")) {
- value = Float.parseFloat(stringData);
- } else {
- value = Double.parseDouble(stringData);
- }
- } else if (type.contentEquals("boolean")) {
- value = Boolean.parseBoolean(stringData);
- } else if (type.contentEquals("object")) {
- value = createComponentInstance(format, stringData, ts);
- } else if (type.contentEquals("array")) {
- final JSONArray jsonArray = new JSONArray(stringData);
- final TypeSchema itemSchema = ts.getItems();
-
- // note here that the type has to be converted in the case of primitives
- final Object[] data = (Object[])
- Array.newInstance(mapPrimitive(itemSchema.getTypeClass(this.typeRegistry)), jsonArray.length());
- for (int i = 0; i < jsonArray.length(); i++) {
- final Object convertedData = convert(jsonArray.get(i).toString(), itemSchema);
- data[i] = convertedData;
- }
- value = data;
+ private Object convertArray(final String stringData, final TypeSchema ts)
+ throws IllegalAccessException, InstantiationException {
+ final JSONArray jsonArray = new JSONArray(stringData);
+ final TypeSchema itemSchema = ts.getItems();
+
+ // note here that the type has to be converted in the case of primitives
+ final Object[] data = (Object[])
+ Array.newInstance(mapPrimitive(itemSchema.getTypeClass(this.typeRegistry)), jsonArray.length());
+ for (int i = 0; i < jsonArray.length(); i++) {
+ final Object convertedData = convert(jsonArray.get(i).toString(), itemSchema);
+ data[i] = convertedData;
+ }
+
+ return data;
+ }
+
+ private Object convertNumber(final String stringData, final TypeSchema ts) {
+ if ("float".equals(ts.getFormat())) {
+ return Float.parseFloat(stringData);
+ }
+
+ return Double.parseDouble(stringData);
+ }
+
+ private Object convertInteger(final String stringData, final TypeSchema ts) {
+ switch (ts.getFormat()) {
+ case "int32":
+ return Integer.parseInt(stringData);
+ case "int8":
+ return Byte.parseByte(stringData);
+ case "int16":
+ return Short.parseShort(stringData);
+ case "int64":
+ return Long.parseLong(stringData);
+ default:
+ throw new IllegalArgumentException("Unknown format for integer " + ts.getFormat());
+ }
+ }
+
+ private Object convertString(final String stringData, final TypeSchema ts) {
+ if ("uint16".equals(ts.getFormat())) {
+ return stringData.charAt(0);
}
- return value;
+
+ return stringData;
}
/**
@@ -278,6 +305,7 @@ private Object convert(final String stringData, final TypeSchema ts)
* @param ts TypeSchema
* @return new object
*/
+ @SuppressWarnings("PMD.AvoidAccessibilityAlteration")
Object createComponentInstance(final String format, final String jsonString, final TypeSchema ts) {
final DataTypeDefinition dtd = this.typeRegistry.getDataType(format);
@@ -296,9 +324,7 @@ Object createComponentInstance(final String format, final String jsonString, fin
ts.validate(json);
try {
final Map fields = dtd.getProperties();
- for (final Iterator iterator = fields.values().iterator(); iterator.hasNext(); ) {
- final PropertyDefinition prop = iterator.next();
-
+ for (final PropertyDefinition prop : fields.values()) {
final Field f = prop.getField();
f.setAccessible(true);
final Object newValue = convert(json.get(prop.getName()).toString(), prop.getSchema());
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java
index b8803269..509f60d9 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java
@@ -28,7 +28,7 @@
public class ContractExecutionService implements ExecutionService {
- private static Logger logger = Logger.getLogger(ContractExecutionService.class.getName());
+ private static final Logger LOGGER = Logger.getLogger(ContractExecutionService.class.getName());
private final SerializerRegistryImpl serializers;
@@ -41,7 +41,7 @@ public ContractExecutionService(final SerializerRegistryImpl serializers) {
@Override
public Chaincode.Response executeRequest(
final TxFunction txFn, final InvocationRequest req, final ChaincodeStub stub) {
- logger.fine(() -> "Routing Request" + txFn);
+ LOGGER.fine(() -> "Routing Request" + txFn);
final TxFunction.Routing rd = txFn.getRouting();
Chaincode.Response response;
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java
index a63d2ffc..7a3e0ff3 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractInvocationRequest.java
@@ -6,27 +6,36 @@
package org.hyperledger.fabric.contract.execution.impl;
-import java.util.Collections;
+import java.nio.charset.StandardCharsets;
import java.util.List;
-import java.util.stream.Collectors;
+import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperledger.fabric.contract.execution.InvocationRequest;
import org.hyperledger.fabric.shim.ChaincodeStub;
-public class ContractInvocationRequest implements InvocationRequest {
- private String namespace;
- private String method;
- private List args = Collections.emptyList();
+public final class ContractInvocationRequest implements InvocationRequest {
+ @SuppressWarnings("PMD.ProperLogger") // PMD 7.7.0 gives a false positive here
+ private static final Log LOGGER = LogFactory.getLog(ContractInvocationRequest.class);
- private static Log logger = LogFactory.getLog(ContractInvocationRequest.class);
+ private static final Pattern NS_REGEX = Pattern.compile(":");
+
+ private final String namespace;
+ private final String method;
+ private final List args;
/** @param context */
+ @SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
public ContractInvocationRequest(final ChaincodeStub context) {
- final String func =
- context.getStringArgs().size() > 0 ? context.getStringArgs().get(0) : null;
- final String[] funcParts = func.split(":");
- logger.debug(func);
+ List funcAndArgs = context.getArgs();
+ if (funcAndArgs.isEmpty()) {
+ throw new IllegalArgumentException("Missing function name");
+ }
+
+ final String func = new String(funcAndArgs.get(0), StandardCharsets.UTF_8);
+ LOGGER.debug(func);
+
+ final String[] funcParts = NS_REGEX.split(func);
if (funcParts.length == 2) {
namespace = funcParts[0];
method = funcParts[1];
@@ -35,8 +44,10 @@ public ContractInvocationRequest(final ChaincodeStub context) {
method = funcParts[0];
}
- args = context.getArgs().stream().skip(1).collect(Collectors.toList());
- logger.debug(namespace + " " + method + " " + args);
+ args = funcAndArgs.subList(1, funcAndArgs.size());
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(namespace + " " + method + " " + args);
+ }
}
/** */
diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java
index c7b5d0c0..e444efa7 100644
--- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java
+++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/metadata/MetadataBuilder.java
@@ -8,6 +8,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
+import java.io.UncheckedIOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
@@ -40,16 +41,26 @@
*
This class is used to build up the JSON structure to be returned as the metadata It is not a store of information,
* rather a set of functional data to process to and from metadata json to the internal data structure
*/
+@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public final class MetadataBuilder {
- private static Logger logger = Logger.getLogger(MetadataBuilder.class);
+ private static final Logger LOGGER = Logger.getLogger(MetadataBuilder.class);
- private MetadataBuilder() {}
+ private static final int PADDING = 3;
- @SuppressWarnings("serial")
- static class MetadataMap extends HashMap {
+ // Metadata is composed of three primary sections
+ // each of which is stored in a map
+ private static Map> contractMap = new HashMap<>();
+ private static Map overallInfoMap = new HashMap<>();
+ private static Map componentMap = new HashMap<>();
+
+ // The schema client used to load any other referenced schemas
+ private static SchemaClient schemaClient = new DefaultSchemaClient();
+
+ static final class MetadataMap extends HashMap {
+ private static final long serialVersionUID = 1L;
V putIfNotNull(final K key, final V value) {
- logger.info(key + " " + value);
+ LOGGER.info(() -> key + " " + value);
if (value != null && !value.toString().isEmpty()) {
return put(key, value);
} else {
@@ -58,14 +69,7 @@ V putIfNotNull(final K key, final V value) {
}
}
- // Metadata is composed of three primary sections
- // each of which is stored in a map
- private static Map> contractMap = new HashMap<>();
- private static Map overallInfoMap = new HashMap();
- private static Map componentMap = new HashMap();
-
- // The schema client used to load any other referenced schemas
- private static SchemaClient schemaClient = new DefaultSchemaClient();
+ private MetadataBuilder() {}
/**
* Validation method.
@@ -73,7 +77,7 @@ V putIfNotNull(final K key, final V value) {
* @throws ValidationException if the metadata is not valid
*/
public static void validate() {
- logger.info("Running schema test validation");
+ LOGGER.info("Running schema test validation");
final ClassLoader cl = MetadataBuilder.class.getClassLoader();
try (InputStream contractSchemaInputStream = cl.getResourceAsStream("contract-schema.json");
InputStream jsonSchemaInputStream = cl.getResourceAsStream("json-schema-draft-04-schema.json")) {
@@ -88,13 +92,13 @@ public static void validate() {
schema.validate(metadata());
} catch (final IOException e) {
- throw new RuntimeException(e);
+ throw new UncheckedIOException(e);
} catch (final ValidationException e) {
- logger.error(e.getMessage());
+ LOGGER.error(e::getMessage);
e.getCausingExceptions().stream()
.map(ValidationException::getMessage)
- .forEach(logger::info);
- logger.error(debugString());
+ .forEach(LOGGER::info);
+ LOGGER.error(MetadataBuilder::debugString);
throw e;
}
}
@@ -115,8 +119,8 @@ public static void initialize(final RoutingRegistry registry, final TypeRegistry
// need to validate that the metadata that has been created is really valid
// it should be as it's been created by code, but this is a valuable double
// check
- logger.info("Validating schema created");
- MetadataBuilder.validate();
+ LOGGER.info("Validating schema created");
+ validate();
}
/**
@@ -133,7 +137,7 @@ public static void addComponent(final DataTypeDefinition datatype) {
component.put("additionalProperties", false);
final Map propertiesMap = datatype.getProperties().entrySet().stream()
- .collect(Collectors.toMap(Entry::getKey, e -> (e.getValue().getSchema())));
+ .collect(Collectors.toMap(Entry::getKey, e -> e.getValue().getSchema()));
component.put("properties", propertiesMap);
componentMap.put(datatype.getSimpleName(), component);
@@ -145,7 +149,7 @@ public static void addComponent(final DataTypeDefinition datatype) {
* @param contractDefinition Class of the object to use as a contract
* @return the key that the contract class is referred to in the metadata
*/
- @SuppressWarnings("serial")
+ @SuppressWarnings("PMD.LooseCoupling")
public static String addContract(final ContractDefinition contractDefinition) {
final String key = contractDefinition.getName();
@@ -153,40 +157,34 @@ public static String addContract(final ContractDefinition contractDefinition) {
final Contract annotation = contractDefinition.getAnnotation();
final Info info = annotation.info();
- final HashMap infoMap = new HashMap();
+ final HashMap infoMap = new HashMap<>();
infoMap.put("title", info.title());
infoMap.put("description", info.description());
infoMap.put("termsOfService", info.termsOfService());
- infoMap.put("contact", new MetadataMap() {
- {
- putIfNotNull("email", info.contact().email());
- putIfNotNull("name", info.contact().name());
- putIfNotNull("url", info.contact().url());
- }
- });
- infoMap.put("license", new MetadataMap() {
- {
- put("name", info.license().name());
- putIfNotNull("url", info.license().url());
- }
- });
+
+ MetadataMap contact = new MetadataMap<>();
+ contact.putIfNotNull("email", info.contact().email());
+ contact.putIfNotNull("name", info.contact().name());
+ contact.putIfNotNull("url", info.contact().url());
+ infoMap.put("contact", contact);
+
+ MetadataMap license = new MetadataMap<>();
+ license.put("name", info.license().name());
+ license.putIfNotNull("url", info.license().url());
+ infoMap.put("license", license);
+
infoMap.put("version", info.version());
- final HashMap contract = new HashMap();
+ final HashMap contract = new HashMap<>();
contract.put("name", key);
- contract.put("transactions", new ArrayList