From 3328707c42e12fddda55ca702cd5f7cee88e9476 Mon Sep 17 00:00:00 2001 From: Sagi Shumer Date: Sun, 7 Apr 2024 15:21:43 +0300 Subject: [PATCH 1/5] added test file --- .../databind/deser/dos/DeepArrayWrappingForDeser3590Test.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java b/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java new file mode 100644 index 0000000000..e69de29bb2 From 4912a4f40d606de1bc7b21f9d83b33953c2a665c Mon Sep 17 00:00:00 2001 From: Sagi Shumer Date: Sun, 7 Apr 2024 16:10:48 +0300 Subject: [PATCH 2/5] changes --- .../databind/DeserializationContext.java | 19 ++- .../databind/deser/SettableBeanProperty.java | 2 +- .../databind/deser/std/StdDeserializer.java | 59 +++++++-- .../DeepArrayWrappingForDeser3590Test.java | 113 ++++++++++++++++++ 4 files changed, 181 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java index 35c1056017..ddac7710a9 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java @@ -96,6 +96,7 @@ public abstract class DeserializationContext */ protected final int _featureFlags; + protected int _primitiveRecursionDepth; /** * Currently active view, if any. */ @@ -164,6 +165,7 @@ protected DeserializationContext(DeserializerFactory df, } _cache = cache; _featureFlags = 0; + _primitiveRecursionDepth = 0; _config = null; _injectableValues = null; _view = null; @@ -178,6 +180,7 @@ protected DeserializationContext(DeserializationContext src, _config = src._config; _featureFlags = src._featureFlags; + _primitiveRecursionDepth = 0; _view = src._view; _parser = src._parser; _injectableValues = src._injectableValues; @@ -193,9 +196,10 @@ protected DeserializationContext(DeserializationContext src, { _cache = src._cache; _factory = src._factory; - + _config = config; _featureFlags = config.getDeserializationFeatures(); + _primitiveRecursionDepth = 0; _view = config.getActiveView(); _parser = p; _injectableValues = injectableValues; @@ -211,6 +215,7 @@ protected DeserializationContext(DeserializationContext src) { _config = src._config; _featureFlags = src._featureFlags; + _primitiveRecursionDepth = 0; _view = src._view; _injectableValues = null; } @@ -374,6 +379,18 @@ public final boolean hasDeserializationFeatures(int featureMask) { public final boolean hasSomeOfFeatures(int featureMask) { return (_featureFlags & featureMask) != 0; } + + public final int getPrimitiveRecursionDepth(){ + return _primitiveRecursionDepth; + } + + public final void incPrimitiveRecursionDepth() { + _primitiveRecursionDepth += 1; + } + + public final void resetPrimitiveRecursionDepth() { + _primitiveRecursionDepth = 0; + } /** * Method for accessing the currently active parser. diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java index ebfa4e07de..72f409f42c 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/SettableBeanProperty.java @@ -482,7 +482,7 @@ public int getCreatorIndex() { * that should be consumed to produce the value (the only value for * scalars, multiple for Objects and Arrays). */ - public abstract void deserializeAndSet(JsonParser p, + public abstract void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException; /** diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java index dc4f3aef96..a435ff580e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java @@ -33,6 +33,9 @@ public abstract class StdDeserializer implements java.io.Serializable { private static final long serialVersionUID = 1L; + // Legitimate or accidental use of more than one nesting level is + // plausible, but we have to put the line somewhere. + protected static final int maxRecursionDepth = 10; /** * Bitmask that covers {@link DeserializationFeature#USE_BIG_INTEGER_FOR_INTS} @@ -202,8 +205,12 @@ protected final boolean _parseBooleanPrimitive(JsonParser p, DeserializationCont } // [databind#381] if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); + if (p.nextToken() == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (boolean) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final boolean parsed = _parseBooleanPrimitive(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -274,8 +281,12 @@ protected final int _parseIntPrimitive(JsonParser p, DeserializationContext ctxt return 0; case JsonTokenId.ID_START_ARRAY: if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); + if (p.nextToken() == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (int) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final int parsed = _parseIntPrimitive(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -334,8 +345,12 @@ protected final long _parseLongPrimitive(JsonParser p, DeserializationContext ct return 0L; case JsonTokenId.ID_START_ARRAY: if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); + if (p.nextToken() == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (long) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final long parsed = _parseLongPrimitive(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -380,8 +395,12 @@ protected final float _parseFloatPrimitive(JsonParser p, DeserializationContext return 0.0f; case JsonTokenId.ID_START_ARRAY: if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); + if (p.nextToken() == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (float) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final float parsed = _parseFloatPrimitive(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -441,8 +460,12 @@ protected final double _parseDoublePrimitive(JsonParser p, DeserializationContex return 0.0; case JsonTokenId.ID_START_ARRAY: if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { - p.nextToken(); + if (p.nextToken() == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (double) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final double parsed = _parseDoublePrimitive(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -524,7 +547,12 @@ protected java.util.Date _parseDateFromArray(JsonParser p, DeserializationContex } } if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { + if (t == JsonToken.START_ARRAY && ctxt.getPrimitiveRecursionDepth() >= maxRecursionDepth) { + return (java.util.Date) handleNestedArrayForSingle(p, ctxt); + } + ctxt.incPrimitiveRecursionDepth(); final Date parsed = _parseDate(p, ctxt); + ctxt.resetPrimitiveRecursionDepth(); _verifyEndArrayForSingle(p, ctxt); return parsed; } @@ -728,12 +756,8 @@ protected T _deserializeWrappedValue(JsonParser p, DeserializationContext ctxt) // 23-Mar-2017, tatu: Let's specifically block recursive resolution to avoid // either supporting nested arrays, or to cause infinite looping. if (p.hasToken(JsonToken.START_ARRAY)) { - String msg = String.format( -"Cannot deserialize instance of %s out of %s token: nested Arrays not allowed with %s", - ClassUtil.nameOf(_valueClass), JsonToken.START_ARRAY, - "DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS"); @SuppressWarnings("unchecked") - T result = (T) ctxt.handleUnexpectedToken(getValueType(ctxt), p.getCurrentToken(), p, msg); + T result = (T) handleNestedArrayForSingle(p, ctxt); return result; } return (T) deserialize(p, ctxt); @@ -1222,6 +1246,21 @@ protected void handleMissingEndArrayForSingle(JsonParser p, DeserializationConte // but for now just fall through } + /** + * Helper method called when detecting a deep(er) nesting of Arrays when trying + * to unwrap value for {@code DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS}. + * + * @since 2.13.4.1 + */ + protected Object handleNestedArrayForSingle(JsonParser p, DeserializationContext ctxt) throws IOException + { + String msg = String.format( +"Cannot deserialize instance of %s out of %s token: nested Arrays not allowed with %s", + ClassUtil.nameOf(_valueClass), JsonToken.START_ARRAY, + "DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS"); + return ctxt.handleUnexpectedToken(getValueType(ctxt), p.currentToken(), p, msg); + } + protected void _verifyEndArrayForSingle(JsonParser p, DeserializationContext ctxt) throws IOException { JsonToken t = p.nextToken(); diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java b/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java index e69de29bb2..70f086efbe 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java @@ -0,0 +1,113 @@ +package com.fasterxml.jackson.databind.deser.dos; + +import java.util.Date; + +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; + +public class DeepArrayWrappingForDeser3590Test extends BaseMapTest +{ + // 05-Sep-2022, tatu: Before fix, failed with 5000 + private final static int TOO_DEEP_NESTING = 12; + + private final ObjectMapper MAPPER = jsonMapperBuilder() + .enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) + .build(); + + private final static String TOO_DEEP_DOC = _nestedDoc(TOO_DEEP_NESTING, "[ ", "] ", "123"); + + public void testArrayWrappingForBoolean() throws Exception + { + _testArrayWrappingFor(Boolean.class); + _testArrayWrappingFor(Boolean.TYPE); + } + + public void testArrayWrappingForByte() throws Exception + { + _testArrayWrappingFor(Byte.class); + _testArrayWrappingFor(Byte.TYPE); + } + + public void testArrayWrappingForShort() throws Exception + { + _testArrayWrappingFor(Short.class); + _testArrayWrappingFor(Short.TYPE); + } + + public void testArrayWrappingForInt() throws Exception + { + _testArrayWrappingFor(Integer.class); + _testArrayWrappingFor(Integer.TYPE); + } + + public void testArrayWrappingForLong() throws Exception + { + _testArrayWrappingFor(Long.class); + _testArrayWrappingFor(Long.TYPE); + } + + public void testArrayWrappingForFloat() throws Exception + { + _testArrayWrappingFor(Float.class); + _testArrayWrappingFor(Float.TYPE); + } + + public void testArrayWrappingForDouble() throws Exception + { + _testArrayWrappingFor(Double.class); + _testArrayWrappingFor(Double.TYPE); + } + + public void testArrayWrappingForDate() throws Exception + { + _testArrayWrappingFor(Date.class); + } + + public void testArrayWrappingForPoint() throws Exception + { + try { + MAPPER.readValue("[[[[[[{\"x\":[[[[[[[5]]]]]]],\"y\":[[[[[[[[[[[[[3]]]]]]]]]]]]]}]]]]]]", Point.class); + fail("Should not pass"); + } catch (MismatchedInputException e) { + verifyException(e, "Cannot deserialize"); + verifyException(e, "nested Arrays not allowed"); + } + } + public void testArrayWrappingForPointPass() throws Exception + { + try { + MAPPER.readValue("[[[[[[{\"x\":[[[[[[[5]]]]]]],\"y\":[[[[[[[[[3]]]]]]]]]}]]]]]]", Point.class); + } catch (MismatchedInputException e) { + fail("Should not throw exception"); + } + } + private void _testArrayWrappingFor(Class cls) throws Exception + { + try { + MAPPER.readValue(TOO_DEEP_DOC, cls); + fail("Should not pass"); + } catch (MismatchedInputException e) { + verifyException(e, "Cannot deserialize"); + verifyException(e, "nested Arrays not allowed"); + } + } + + private static String _nestedDoc(int nesting, String open, String close, String content) { + StringBuilder sb = new StringBuilder(nesting * (open.length() + close.length())); + for (int i = 0; i < nesting; ++i) { + sb.append(open); + if ((i & 31) == 0) { + sb.append("\n"); + } + } + sb.append("\n").append(content).append("\n"); + for (int i = 0; i < nesting; ++i) { + sb.append(close); + if ((i & 31) == 0) { + sb.append("\n"); + } + } + return sb.toString(); + } + +} From 16eb325181c28f42c868a207f46e9f4ac536a697 Mon Sep 17 00:00:00 2001 From: Sagi Shumer Date: Sun, 7 Apr 2024 16:21:41 +0300 Subject: [PATCH 3/5] removed tests --- .../DeepArrayWrappingForDeser3590Test.java | 113 ------------------ 1 file changed, 113 deletions(-) delete mode 100644 src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java b/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java deleted file mode 100644 index 70f086efbe..0000000000 --- a/src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3590Test.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.fasterxml.jackson.databind.deser.dos; - -import java.util.Date; - -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.exc.MismatchedInputException; - -public class DeepArrayWrappingForDeser3590Test extends BaseMapTest -{ - // 05-Sep-2022, tatu: Before fix, failed with 5000 - private final static int TOO_DEEP_NESTING = 12; - - private final ObjectMapper MAPPER = jsonMapperBuilder() - .enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) - .build(); - - private final static String TOO_DEEP_DOC = _nestedDoc(TOO_DEEP_NESTING, "[ ", "] ", "123"); - - public void testArrayWrappingForBoolean() throws Exception - { - _testArrayWrappingFor(Boolean.class); - _testArrayWrappingFor(Boolean.TYPE); - } - - public void testArrayWrappingForByte() throws Exception - { - _testArrayWrappingFor(Byte.class); - _testArrayWrappingFor(Byte.TYPE); - } - - public void testArrayWrappingForShort() throws Exception - { - _testArrayWrappingFor(Short.class); - _testArrayWrappingFor(Short.TYPE); - } - - public void testArrayWrappingForInt() throws Exception - { - _testArrayWrappingFor(Integer.class); - _testArrayWrappingFor(Integer.TYPE); - } - - public void testArrayWrappingForLong() throws Exception - { - _testArrayWrappingFor(Long.class); - _testArrayWrappingFor(Long.TYPE); - } - - public void testArrayWrappingForFloat() throws Exception - { - _testArrayWrappingFor(Float.class); - _testArrayWrappingFor(Float.TYPE); - } - - public void testArrayWrappingForDouble() throws Exception - { - _testArrayWrappingFor(Double.class); - _testArrayWrappingFor(Double.TYPE); - } - - public void testArrayWrappingForDate() throws Exception - { - _testArrayWrappingFor(Date.class); - } - - public void testArrayWrappingForPoint() throws Exception - { - try { - MAPPER.readValue("[[[[[[{\"x\":[[[[[[[5]]]]]]],\"y\":[[[[[[[[[[[[[3]]]]]]]]]]]]]}]]]]]]", Point.class); - fail("Should not pass"); - } catch (MismatchedInputException e) { - verifyException(e, "Cannot deserialize"); - verifyException(e, "nested Arrays not allowed"); - } - } - public void testArrayWrappingForPointPass() throws Exception - { - try { - MAPPER.readValue("[[[[[[{\"x\":[[[[[[[5]]]]]]],\"y\":[[[[[[[[[3]]]]]]]]]}]]]]]]", Point.class); - } catch (MismatchedInputException e) { - fail("Should not throw exception"); - } - } - private void _testArrayWrappingFor(Class cls) throws Exception - { - try { - MAPPER.readValue(TOO_DEEP_DOC, cls); - fail("Should not pass"); - } catch (MismatchedInputException e) { - verifyException(e, "Cannot deserialize"); - verifyException(e, "nested Arrays not allowed"); - } - } - - private static String _nestedDoc(int nesting, String open, String close, String content) { - StringBuilder sb = new StringBuilder(nesting * (open.length() + close.length())); - for (int i = 0; i < nesting; ++i) { - sb.append(open); - if ((i & 31) == 0) { - sb.append("\n"); - } - } - sb.append("\n").append(content).append("\n"); - for (int i = 0; i < nesting; ++i) { - sb.append(close); - if ((i & 31) == 0) { - sb.append("\n"); - } - } - return sb.toString(); - } - -} From da007fcd8c4986c90cbeecac1c0606a680ee6a5a Mon Sep 17 00:00:00 2001 From: Sagi Shumer Date: Sun, 7 Apr 2024 18:47:58 +0300 Subject: [PATCH 4/5] Dsa --- .github/workflows/main.yml | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..26ec8a8784 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,51 @@ +name: Build and Deploy Snapshot +on: + push: + branches: + - master + - "2.11" + paths-ignore: + - "README.md" + - "release-notes/*" + pull_request: + branches: + - master + - "2.11" + paths-ignore: + - "README.md" + - "release-notes/*" +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + java_version: ['8', '11'] + os: ['ubuntu-20.04'] + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + distribution: "adopt" + java-version: ${{ matrix.java_version }} + server-id: sonatype-nexus-snapshots + server-username: CI_DEPLOY_USERNAME + server-password: CI_DEPLOY_PASSWORD + # See https://github.com/actions/setup-java/blob/v2/docs/advanced-usage.md#Publishing-using-Apache-Maven + # gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import + # gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase + - uses: actions/cache@v2.1.6 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Build + run: ./mvnw -V -B -ff -ntp verify + # - name: Deploy snapshot + # if: github.event_name != 'pull_request' && matrix.java_version == '8' + # env: + # CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} + # CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} + # run: ./mvnw -B -ff -DskipTests -ntp source:jar deploy \ No newline at end of file From 1866861bf4a119b44e38603c1915a554ca7265f4 Mon Sep 17 00:00:00 2001 From: Sagi Shumer Date: Sun, 7 Apr 2024 18:51:27 +0300 Subject: [PATCH 5/5] mvnw --- mvnw | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 mvnw diff --git a/mvnw b/mvnw new file mode 100644 index 0000000000..5b0c9e2431 --- /dev/null +++ b/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# 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 [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + 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; +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 + fi + ;; +esac + +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"` +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)`" +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 + +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="`\\unset -f command; \\command -v java`" + fi +fi + +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." +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" + return 1 + fi + + basedir="$1" + wdir="$1" + 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` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$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 +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/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.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 + + 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" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$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 + 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"` +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 + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" \ No newline at end of file