diff --git a/CHANGELOG.md b/CHANGELOG.md index dc55f1f..3306149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.6 ## + +* Upgraded Java SDK version +* Fixed Int6/Int16 auto detecting +* Fixed standard transaction levels + ## 2.0.5 ## * Extended usage of standard JDBC exception classes diff --git a/README.md b/README.md index e326d5b..6e927d7 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,14 @@ Specify the YDB JDBC driver in the dependencies: tech.ydb.jdbc ydb-jdbc-driver - 2.0.5 + 2.0.6 tech.ydb.jdbc ydb-jdbc-driver-shaded - 2.0.5 + 2.0.6 ``` diff --git a/jdbc-shaded/pom.xml b/jdbc-shaded/pom.xml index 6bd64d5..2c70443 100644 --- a/jdbc-shaded/pom.xml +++ b/jdbc-shaded/pom.xml @@ -6,7 +6,7 @@ tech.ydb.jdbc ydb-jdbc-driver-parent - 2.0.5 + 2.0.6 ydb-jdbc-driver-shaded diff --git a/jdbc/pom.xml b/jdbc/pom.xml index 865d71b..bd9bee2 100644 --- a/jdbc/pom.xml +++ b/jdbc/pom.xml @@ -6,7 +6,7 @@ tech.ydb.jdbc ydb-jdbc-driver-parent - 2.0.5 + 2.0.6 ydb-jdbc-driver diff --git a/jdbc/src/main/java/tech/ydb/jdbc/YdbConst.java b/jdbc/src/main/java/tech/ydb/jdbc/YdbConst.java index 8cb31b8..b53b3fe 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/YdbConst.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/YdbConst.java @@ -1,7 +1,5 @@ package tech.ydb.jdbc; -import java.sql.Connection; - public final class YdbConst { // SQL types @@ -107,33 +105,25 @@ public final class YdbConst { public static final String MISSING_REQUIRED_VALUE = "Missing required value for parameter: "; public static final String INVALID_PARAMETER_TYPE = "Cannot cast parameter [%s] from [%s] to [%s]"; - // Transaction levels - // See details in https://cloud.yandex.ru/docs/ydb/concepts/transactions - - // Please note: - // Serializable transaction (RW) always uses "for-share" row-level locks before filter stage! + // Custom transaction levels + // See details in https://ydb.tech/docs/en/concepts/transactions#modes - /** - * All transactions are serialized one-by-one. If the DB detects a write collision among - * several concurrent transactions, only the first one is committed. - * This is the strongest level. And the only level at which data changes are possible. - */ - public static final int TRANSACTION_SERIALIZABLE_READ_WRITE = Connection.TRANSACTION_SERIALIZABLE; /** * The most recent consistent state of the database. Read only. */ - public static final int ONLINE_CONSISTENT_READ_ONLY = Connection.TRANSACTION_REPEATABLE_READ; + public static final int ONLINE_CONSISTENT_READ_ONLY = 16; /** * The most recent inconsistent state of the database. Read only. * A phantom read may occurs when, in the course of a transaction, some new rows are added * by another transaction to the records being read. This is the weakest level. */ - public static final int ONLINE_INCONSISTENT_READ_ONLY = Connection.TRANSACTION_READ_COMMITTED; + public static final int ONLINE_INCONSISTENT_READ_ONLY = ONLINE_CONSISTENT_READ_ONLY + 1; + /** * An almost recent consistent state of the database. Read only. * This level is faster then {@code ONLINE_CONSISTENT_READ_ONLY}, but may return stale data. */ - public static final int STALE_CONSISTENT_READ_ONLY = 3; // TODO: verify if we can do that + public static final int STALE_CONSISTENT_READ_ONLY = 32; // Processing queries public static final String EXPLAIN_COLUMN_AST = "AST"; diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbTxState.java b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbTxState.java index 45231e8..602dbb6 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/YdbTxState.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/YdbTxState.java @@ -1,5 +1,6 @@ package tech.ydb.jdbc.context; +import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; @@ -12,68 +13,90 @@ * @author Aleksandr Gorshenin */ public class YdbTxState { + private final int transactionLevel; + private final boolean isReadOnly; + private final boolean isAutoCommit; + private final TxControl txControl; - protected final int transactionLevel; - protected YdbTxState(TxControl tx, int level) { - this.txControl = tx; + protected YdbTxState(TxControl txControl, int level, boolean isReadOnly, boolean isAutoCommit) { this.transactionLevel = level; + this.isReadOnly = isReadOnly; + this.isAutoCommit = isAutoCommit; + this.txControl = txControl; + } + + protected YdbTxState(TxControl txControl, YdbTxState other) { + this.transactionLevel = other.transactionLevel; + this.isReadOnly = other.isReadOnly; + this.isAutoCommit = other.isAutoCommit; + this.txControl = txControl; } @Override public String toString() { - return "NoTx" + transactionLevel; + return "NoTx"; } public String txID() { return null; } + public boolean isInsideTransaction() { + return false; + } + public TxControl txControl() { return txControl; } public boolean isAutoCommit() { - return txControl.isCommitTx(); + return isAutoCommit; } public boolean isReadOnly() { - return transactionLevel != YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE; + return isReadOnly; } - public boolean isInsideTransaction() { - return false; - } - - public int transactionLevel() throws SQLException { + public int transactionLevel() { return transactionLevel; } public YdbTxState withAutoCommit(boolean newAutoCommit) throws SQLException { - if (newAutoCommit == isAutoCommit()) { + if (newAutoCommit == isAutoCommit) { return this; } - return create(transactionLevel(), newAutoCommit); + + if (isInsideTransaction()) { + throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX); + } + + return emptyTx(transactionLevel, isReadOnly, newAutoCommit); } - public YdbTxState withReadOnly(boolean readOnly) throws SQLException { - if (readOnly == isReadOnly()) { + public YdbTxState withReadOnly(boolean newReadOnly) throws SQLException { + if (newReadOnly == isReadOnly()) { return this; } - if (readOnly) { - return create(YdbConst.ONLINE_CONSISTENT_READ_ONLY, isAutoCommit()); - } else { - return create(YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE, isAutoCommit()); + if (isInsideTransaction()) { + throw new SQLFeatureNotSupportedException(YdbConst.READONLY_INSIDE_TRANSACTION); } + + return emptyTx(transactionLevel, newReadOnly, isAutoCommit); } public YdbTxState withTransactionLevel(int newTransactionLevel) throws SQLException { - if (newTransactionLevel == transactionLevel()) { + if (newTransactionLevel == transactionLevel) { return this; } - return create(newTransactionLevel, isAutoCommit()); + if (isInsideTransaction()) { + throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX); + } + + boolean newReadOnly = isReadOnly || newTransactionLevel != Connection.TRANSACTION_SERIALIZABLE; + return emptyTx(newTransactionLevel, newReadOnly, isAutoCommit); } public YdbTxState withCommit(Session session) { @@ -93,7 +116,7 @@ public YdbTxState withKeepAlive(Session session) { public YdbTxState withDataQuery(Session session, String txID) { if (txID != null && !txID.isEmpty()) { - return new TransactionInProgress(txID, session, isAutoCommit()); + return new TransactionInProgress(txID, session, this); } session.close(); @@ -104,88 +127,59 @@ public Session getSession(YdbContext ctx, YdbExecutor executor) throws SQLExcept return executor.createSession(ctx); } - public static YdbTxState create(int level, boolean autoCommit) throws SQLException { - return create(null, null, level, autoCommit); - } + private static TxControl txControl(int level, boolean isReadOnly, boolean isAutoCommit) throws SQLException { + if (!isReadOnly) { + // YDB support only one RW mode + if (level != Connection.TRANSACTION_SERIALIZABLE) { + throw new SQLException(YdbConst.UNSUPPORTED_TRANSACTION_LEVEL + level); + } + + return TxControl.serializableRw().setCommitTx(isAutoCommit); + } - private static YdbTxState create(Session session, String txId, int level, boolean autoCommit) - throws SQLException { switch (level) { - case YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE: - if (txId != null) { - return new TransactionInProgress(txId, session, autoCommit); - } else { - if (autoCommit) { - return new YdbTxState(TxControl.serializableRw(), level); - } else { - return new EmptyTransaction(); - } - } + case Connection.TRANSACTION_SERIALIZABLE: + return TxControl.snapshotRo().setCommitTx(isAutoCommit); case YdbConst.ONLINE_CONSISTENT_READ_ONLY: - return new YdbTxState(TxControl.onlineRo(), level); - case YdbConst.STALE_CONSISTENT_READ_ONLY: - return new YdbTxState(TxControl.staleRo(), level); + return TxControl.onlineRo().setAllowInconsistentReads(false).setCommitTx(isAutoCommit); case YdbConst.ONLINE_INCONSISTENT_READ_ONLY: - return new YdbTxState(TxControl.onlineRo().setAllowInconsistentReads(true), level); + return TxControl.onlineRo().setAllowInconsistentReads(true).setCommitTx(isAutoCommit); + case YdbConst.STALE_CONSISTENT_READ_ONLY: + return TxControl.staleRo().setCommitTx(isAutoCommit); default: throw new SQLException(YdbConst.UNSUPPORTED_TRANSACTION_LEVEL + level); } } - private static class EmptyTransaction extends YdbTxState { - EmptyTransaction() { - super(TxControl.serializableRw().setCommitTx(false), YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE); - } - - @Override - public String toString() { - return "EmptyTx" + transactionLevel; - } - - @Override - public YdbTxState withDataQuery(Session session, String txID) { - if (txID != null && !txID.isEmpty()) { - return new TransactionInProgress(txID, session, isAutoCommit()); - } + private static YdbTxState emptyTx(int level, boolean isReadOnly, boolean isAutoCommit) throws SQLException { + TxControl tx = txControl(level, isReadOnly, isAutoCommit); + return new YdbTxState(tx, level, isReadOnly, isAutoCommit); + } - session.close(); - return this; - } + public static YdbTxState create(int level, boolean isAutoCommit) throws SQLException { + return emptyTx(level, level != Connection.TRANSACTION_SERIALIZABLE, isAutoCommit); } private static class TransactionInProgress extends YdbTxState { - private final String id; + private final String txID; private final Session session; + private final YdbTxState previos; - TransactionInProgress(String id, Session session, boolean autoCommit) { - super(TxControl.id(id).setCommitTx(autoCommit), YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE); - this.id = id; + TransactionInProgress(String id, Session session, YdbTxState previosState) { + super(TxControl.id(id).setCommitTx(previosState.isAutoCommit), previosState); + this.txID = id; this.session = session; + this.previos = previosState; } @Override public String toString() { - return "InTx" + transactionLevel + "[" + id + "]"; + return "InTx" + transactionLevel() + "[" + txID + "]"; } @Override public String txID() { - return id; - } - - @Override - public YdbTxState withAutoCommit(boolean newAutoCommit) throws SQLException { - throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX); - } - - @Override - public YdbTxState withTransactionLevel(int newTransactionLevel) throws SQLException { - throw new SQLFeatureNotSupportedException(YdbConst.CHANGE_ISOLATION_INSIDE_TX); - } - - @Override - public YdbTxState withReadOnly(boolean readOnly) throws SQLException { - throw new SQLFeatureNotSupportedException(YdbConst.READONLY_INSIDE_TRANSACTION); + return txID; } @Override @@ -201,13 +195,13 @@ public Session getSession(YdbContext ctx, YdbExecutor executor) throws SQLExcept @Override public YdbTxState withCommit(Session session) { session.close(); - return new EmptyTransaction(); + return previos; } @Override public YdbTxState withRollback(Session session) { session.close(); - return new EmptyTransaction(); + return previos; } @Override @@ -222,15 +216,15 @@ public YdbTxState withDataQuery(Session session, String txID) { session.close(); } this.session.close(); - return new EmptyTransaction(); + return previos; } - if (this.id.equals(txID)) { + if (txID.equals(txID())) { if (this.session == session) { return this; } this.session.close(); - return new TransactionInProgress(txID, session, isAutoCommit()); + return new TransactionInProgress(txID, session, previos); } session.close(); diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java index 099218f..d445955 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImpl.java @@ -1,5 +1,6 @@ package tech.ydb.jdbc.impl; +import java.sql.Connection; import java.sql.ResultSet; import java.sql.RowIdLifetime; import java.sql.SQLException; @@ -616,7 +617,7 @@ public int getMaxUserNameLength() { @Override public int getDefaultTransactionIsolation() { - return YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE; + return Connection.TRANSACTION_SERIALIZABLE; } @Override @@ -627,7 +628,7 @@ public boolean supportsTransactions() { @Override public boolean supportsTransactionIsolationLevel(int level) { switch (level) { - case YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE: + case Connection.TRANSACTION_SERIALIZABLE: case YdbConst.ONLINE_CONSISTENT_READ_ONLY: case YdbConst.ONLINE_INCONSISTENT_READ_ONLY: case YdbConst.STALE_CONSISTENT_READ_ONLY: diff --git a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java index 440e4bf..4b73728 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/impl/YdbTypesImpl.java @@ -55,8 +55,8 @@ private YdbTypesImpl() { typeBySqlType = new IntObjectHashMap<>(16); typeBySqlType.put(Types.VARCHAR, PrimitiveType.Text); typeBySqlType.put(Types.BIGINT, PrimitiveType.Int64); - typeBySqlType.put(Types.TINYINT, PrimitiveType.Int32); - typeBySqlType.put(Types.SMALLINT, PrimitiveType.Int32); + typeBySqlType.put(Types.TINYINT, PrimitiveType.Int8); + typeBySqlType.put(Types.SMALLINT, PrimitiveType.Int16); typeBySqlType.put(Types.INTEGER, PrimitiveType.Int32); typeBySqlType.put(Types.REAL, PrimitiveType.Float); typeBySqlType.put(Types.FLOAT, PrimitiveType.Float); @@ -77,10 +77,10 @@ private YdbTypesImpl() { typeByClass.put(long.class, PrimitiveType.Int64); typeByClass.put(Long.class, PrimitiveType.Int64); typeByClass.put(BigInteger.class, PrimitiveType.Int64); - typeByClass.put(byte.class, PrimitiveType.Int32); - typeByClass.put(Byte.class, PrimitiveType.Int32); - typeByClass.put(short.class, PrimitiveType.Int32); - typeByClass.put(Short.class, PrimitiveType.Int32); + typeByClass.put(byte.class, PrimitiveType.Int8); + typeByClass.put(Byte.class, PrimitiveType.Int8); + typeByClass.put(short.class, PrimitiveType.Int16); + typeByClass.put(Short.class, PrimitiveType.Int16); typeByClass.put(int.class, PrimitiveType.Int32); typeByClass.put(Integer.class, PrimitiveType.Int32); typeByClass.put(float.class, PrimitiveType.Float); diff --git a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java index 6177a04..2633527 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverProperitesTest.java @@ -366,7 +366,7 @@ static Properties customizedProperties() { properties.setProperty("sessionTimeout", "6s"); properties.setProperty("deadlineTimeout", "1s"); properties.setProperty("autoCommit", "true"); - properties.setProperty("transactionLevel", "4"); + properties.setProperty("transactionLevel", "16"); properties.setProperty("cacheConnectionsInDriver", "false"); properties.setProperty("preparedStatementCacheQueries", "100"); @@ -407,7 +407,7 @@ static DriverPropertyInfo[] customizedPropertyInfo() { YdbOperationProperty.SESSION_TIMEOUT.toDriverPropertyInfo("6s"), YdbOperationProperty.DEADLINE_TIMEOUT.toDriverPropertyInfo("1s"), YdbOperationProperty.AUTOCOMMIT.toDriverPropertyInfo("true"), - YdbOperationProperty.TRANSACTION_LEVEL.toDriverPropertyInfo("4"), + YdbOperationProperty.TRANSACTION_LEVEL.toDriverPropertyInfo("16"), YdbOperationProperty.CACHE_CONNECTIONS_IN_DRIVER.toDriverPropertyInfo("false"), YdbOperationProperty.PREPARED_STATEMENT_CACHE_SIZE.toDriverPropertyInfo("100"), diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java index ea5cfeb..b1f02bd 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbConnectionImplTest.java @@ -536,7 +536,7 @@ public void readOnly() throws SQLException { jdbc.connection().setReadOnly(true); Assertions.assertTrue(jdbc.connection().isReadOnly()); - Assertions.assertEquals(Connection.TRANSACTION_REPEATABLE_READ, jdbc.connection().getTransactionIsolation()); + Assertions.assertEquals(Connection.TRANSACTION_SERIALIZABLE, jdbc.connection().getTransactionIsolation()); jdbc.connection().setReadOnly(false); Assertions.assertFalse(jdbc.connection().isReadOnly()); @@ -559,10 +559,10 @@ public void schema() throws SQLException { @ParameterizedTest(name = "Check supported isolation level {0}") @ValueSource(ints = { - YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE, // 8 - YdbConst.ONLINE_CONSISTENT_READ_ONLY, // 4 - YdbConst.ONLINE_INCONSISTENT_READ_ONLY, // 2 - YdbConst.STALE_CONSISTENT_READ_ONLY // 3 + Connection.TRANSACTION_SERIALIZABLE, // 8 + YdbConst.ONLINE_CONSISTENT_READ_ONLY, // 16 + YdbConst.ONLINE_INCONSISTENT_READ_ONLY, // 17 + YdbConst.STALE_CONSISTENT_READ_ONLY // 32 }) public void supportedTransactionIsolations(int level) throws SQLException { jdbc.connection().setTransactionIsolation(level); @@ -574,7 +574,7 @@ public void supportedTransactionIsolations(int level) throws SQLException { } @ParameterizedTest(name = "Check supported isolation level {0}") - @ValueSource(ints = { 0, 1, /*2, 3, 4,*/ 5, 6, 7, /*8,*/ 9, 10 }) + @ValueSource(ints = { 0, 1, 2, 3, 4, 5, 6, 7, /*8,*/ 9, 10 }) public void unsupportedTransactionIsolations(int level) throws SQLException { ExceptionAssert.sqlException("Unsupported transaction level: " + level, () -> jdbc.connection().setTransactionIsolation(level) diff --git a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImplTest.java b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImplTest.java index 5577590..796d3f2 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImplTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/impl/YdbDatabaseMetaDataImplTest.java @@ -251,11 +251,10 @@ public void metaDataValuesTest() throws SQLException { Assertions.assertEquals(YdbConst.MAX_ELEMENT_NAME_LENGTH, metaData.getMaxTableNameLength()); Assertions.assertEquals(0, metaData.getMaxStatements()); Assertions.assertEquals(YdbConst.MAX_ELEMENT_NAME_LENGTH, metaData.getMaxTableNameLength()); - Assertions.assertEquals( - YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE, metaData.getDefaultTransactionIsolation()); + Assertions.assertEquals(Connection.TRANSACTION_SERIALIZABLE, metaData.getDefaultTransactionIsolation()); Assertions.assertTrue(metaData.supportsTransactions()); - Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(YdbConst.TRANSACTION_SERIALIZABLE_READ_WRITE)); + Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE)); Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(YdbConst.ONLINE_CONSISTENT_READ_ONLY)); Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(YdbConst.ONLINE_INCONSISTENT_READ_ONLY)); Assertions.assertTrue(metaData.supportsTransactionIsolationLevel(YdbConst.STALE_CONSISTENT_READ_ONLY)); diff --git a/jdbc/src/test/resources/sql/upsert/simple.sql b/jdbc/src/test/resources/sql/upsert/simple.sql index 2abe87f..73c240e 100644 --- a/jdbc/src/test/resources/sql/upsert/simple.sql +++ b/jdbc/src/test/resources/sql/upsert/simple.sql @@ -32,8 +32,8 @@ UPSERT INTO #tableName ( ?, -- key ?, -- c_Bool - CAST(? AS Int8), -- c_Int8 - CAST(? AS Int16), -- c_Int16 + ?, -- c_Int8 + ?, -- c_Int16 ?, -- c_Int32 ?, -- c_Int64 diff --git a/pom.xml b/pom.xml index 4e8e272..9706a1b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ tech.ydb.jdbc ydb-jdbc-driver-parent - 2.0.5 + 2.0.6 YDB JDBC Module JDBC Driver over YDB Java SDK @@ -20,7 +20,7 @@ 1.7.36 5.9.3 - 2.1.7 + 2.1.11 @@ -87,7 +87,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.1.0 + 3.2.3 org.apache.maven.plugins @@ -97,7 +97,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 + 3.6.3 8 @@ -113,12 +113,12 @@ org.apache.maven.plugins maven-dependency-plugin - 3.5.0 + 3.6.1 org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 1.8 1.8 @@ -133,7 +133,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.0 attach-sources @@ -146,14 +146,14 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.5.1 org.jacoco jacoco-maven-plugin - 0.8.10 + 0.8.11 jacoco-prepare-agent