diff --git a/.local/deploy_to_pod.sh b/.local/deploy_to_pod.sh new file mode 100755 index 0000000000000000000000000000000000000000..09a43e12b0b36698641676f8060200130c21e07a --- /dev/null +++ b/.local/deploy_to_pod.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set JAVA_HOME=/usr/lib/jvm/java-8-oracle +CESIUM_PLUS_POD_DIR="${HOME}/git/duniter/cesium-plus-pod" +DEPLOY_DIR="${CESIUM_PLUS_POD_DIR}/cesium-plus-pod-assembly/target/es-run-home/plugins/cesium-plus-pod-core" + +# Go to project root +cd .. + +echo "***************************************" +echo " Compiling duniter4j.core-client... " + +# Remove old JAR +rm duniter4j-core-client/target/*.jar + +# Compile the core-client +mvn install -pl duniter4j-core-client --quiet -DskipTests +if [[ $? -ne 0 ]]; then + exit 1 +fi +echo " Successfully compiled ! " + +echo "***************************************" +echo " Installing into Cesium+ pod (target assembly)... " + +# Copy jar +mkdir -p ${DEPLOY_DIR} +if [[ $? -ne 0 ]]; then + exit 1 +fi + +rm -f "${DEPLOY_DIR}/duniter4j-core-client-*.jar" +if [[ $? -ne 0 ]]; then + exit 1 +fi + +cd duniter4j-core-client/target/ +JAR_FILE=`ls *.jar` +cp -v ${JAR_FILE} ${DEPLOY_DIR}/ +if [[ $? -ne 0 ]]; then + exit 1 +fi + +echo " Successfully deployed !" +echo "************************" diff --git a/duniter4j-client/pom.xml b/duniter4j-client/pom.xml index 03c1ac35621b2c794ef5c0bc2f91b366decdf1d3..49ff083c0b5f1f1874274864d9a9eb9757b4ef10 100644 --- a/duniter4j-client/pom.xml +++ b/duniter4j-client/pom.xml @@ -48,6 +48,10 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> diff --git a/duniter4j-core-client/pom.xml b/duniter4j-core-client/pom.xml index e7abaaa5c2702e745f70b633fb68af9e902381c7..1dfab6037e91885625b3461f58f8f719e3bc100c 100644 --- a/duniter4j-core-client/pom.xml +++ b/duniter4j-core-client/pom.xml @@ -93,6 +93,11 @@ <artifactId>slf4j-log4j12</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java index 810727218960574e25b826a11781551f29b29526..b8d51266cbe19f8d06ed24c5359ee5533e2bc9ba 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/PeerDao.java @@ -69,7 +69,7 @@ public interface PeerDao extends EntityDao<String, Peer> { Long getMaxLastUpTime(String currencyId); - void updatePeersAsDown(String currencyId, long upTimeLimitInSec, Collection<String> endpointApis); + void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> endpointApis); boolean hasPeersUpWithApi(String currencyId, Set<EndpointApi> endpointApis); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java index e284fcb84d4a9e630422b18b0a84505a6f16ae88..d1d6841f7ee883760931ade740bc66a1103872c7 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/dao/mem/MemoryPeerDaoImpl.java @@ -158,9 +158,9 @@ public class MemoryPeerDaoImpl implements PeerDao { } @Override - public void updatePeersAsDown(String currencyId, long upTimeLimitInSec, Collection<String> endpointApis) { + public void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> endpointApis) { - long firstDownTime = System.currentTimeMillis(); + long firstDownTimeInMs = System.currentTimeMillis(); getPeersByCurrencyId(currencyId).stream() .filter(peer -> @@ -168,13 +168,13 @@ public class MemoryPeerDaoImpl implements PeerDao { && peer.getStats().isReacheable() && ( peer.getStats().getLastUpTime() == null - || peer.getStats().getLastUpTime() < upTimeLimitInSec + || peer.getStats().getLastUpTime() < minUpTimeInMs ) && (endpointApis == null || endpointApis.contains(peer.getApi())) ) .forEach(peer -> { peer.getStats().setStatus(Peer.PeerStatus.DOWN); - peer.getStats().setFirstDownTime(firstDownTime); + peer.getStats().setFirstDownTime(firstDownTimeInMs); }); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java index 9d5b972fb66c83a128cabbb5939d563f9f8d9d0a..38838e3c7090f78cbe7ba29c9093f740cb2901c7 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeering.java @@ -28,12 +28,13 @@ import org.duniter.core.util.StringUtils; import java.io.Serializable; import java.util.Objects; +import java.util.StringJoiner; /** * Created by eis on 05/02/15. */ public class NetworkPeering implements Serializable { - private String version; + private Integer version; private String currency; private String block; private String signature; @@ -44,11 +45,11 @@ public class NetworkPeering implements Serializable { public Endpoint[] endpoints; - public String getVersion() { + public Integer getVersion() { return version; } - public void setVersion(String version) { + public void setVersion(Integer version) { this.version = version; } @@ -201,35 +202,37 @@ public class NetworkPeering implements Serializable { @Override public String toString() { - StringBuilder sb = new StringBuilder(); + StringJoiner joiner = new StringJoiner(" "); // API - sb.append(api.name()); + if (api != null) { + joiner.add(api.name()); + } // Id (use for WS2P) if (StringUtils.isNotBlank(id)) { - sb.append(" ").append(id); + joiner.add(id); } // DNS if (StringUtils.isNotBlank(dns)) { - sb.append(" ").append(dns); + joiner.add(dns); } // IPv4 if (StringUtils.isNotBlank(ipv4)) { - sb.append(" ").append(ipv4); + joiner.add(ipv4); } // IPv6 if (StringUtils.isNotBlank(ipv6)) { - sb.append(" ").append(ipv6); + joiner.add(ipv6); } // Port if (port != null) { - sb.append(" ").append(port); + joiner.add(String.valueOf(port)); } // path if (StringUtils.isNotBlank(path)) { - sb.append(" ").append(path); + joiner.add(path); } - return sb.toString(); + return joiner.toString(); } @Override diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java index 77420cdb154f458ae33cc65883286dd9a85ad827..417ae26bec30517c9d155203715c0c1a699a3877 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeerings.java @@ -52,14 +52,18 @@ public class NetworkPeerings { String[] lines = document.trim().split("\n"); - Preconditions.checkArgument(lines.length >= 7, "Invalid document"); + Preconditions.checkArgument(lines.length >= 7, String.format("Invalid document. Only %s lines found (at least 7 expected)", lines.length)); int i = 0; String line; for (; i < 5; ) { line = lines[i++].trim(); if (line.startsWith("Version: ")) { - result.setVersion(line.substring(9)); + String version = line.substring(9).trim(); + if (!Protocol.PEER_VERSION.equals(version)) { + Preconditions.checkArgument(false, String.format("Unknown peer document version. Expected %s, but found %s", Protocol.PEER_VERSION)); + } + result.setVersion(Integer.parseInt(version)); } else if (line.startsWith("Type: ")) { String type = line.substring(6); Preconditions.checkArgument(Protocol.TYPE_PEER.equals(type), "Invalid type found in document. Expected: " + Protocol.TYPE_PEER); diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeers.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeers.java index b91b546c86ffd611dc6641c611d9e2be2633bbf2..480b8d49e7103e96f94d48f0c164d6d07c4f3c9c 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeers.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/NetworkPeers.java @@ -25,6 +25,7 @@ package org.duniter.core.client.model.bma; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonSetter; +import com.google.common.base.Joiner; import java.io.Serializable; @@ -36,11 +37,7 @@ public class NetworkPeers implements Serializable { public Peer[] peers; public String toString() { - String s = ""; - for(Peer peer : peers) { - s += peer.toString() + "\n"; - } - return s; + return Joiner.on(",").join(peers); } public static class Peer extends NetworkPeering implements Serializable { @@ -66,28 +63,5 @@ public class NetworkPeers implements Serializable { public void setLastTry(Long lastTry) { this.lastTry = lastTry; } - - public NetworkPeering.Endpoint[] getEndpoints() { - return endpoints; - } - - public void setEndpoints(NetworkPeering.Endpoint[] endpoints) { - this.endpoints = endpoints; - } - - @Override - public String toString() { - String s = "version=" + getVersion() + "\n" + - "currency=" + getCurrency() + "\n" + - "pubkey=" + getPubkey() + "\n" + - "status=" + getStatus() + "\n" + - "block=" + getBlock() + "\n"; - for(NetworkPeering.Endpoint endpoint: endpoints) { - if (endpoint != null) { - s += endpoint.toString() + "\n"; - } - } - return s; - } } } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java index 07cf3a2cbcd8499fa55f4aa67e415b2ef25be42c..6b0bf628988fd221b5ad7a57819c9a4c91d6e9d8 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java @@ -31,6 +31,8 @@ public interface Protocol { String TX_VERSION = "10"; + String PEER_VERSION = "10"; + String TYPE_IDENTITY = "Identity"; String TYPE_MEMBERSHIP = "Membership"; diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java index 955d8f273c9bb57493d8de078abd624daf44eacd..ab7efccf9d863f2ac09b1c57ac74972ead349460 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peer.java @@ -27,7 +27,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.base.Joiner; import org.duniter.core.client.model.bma.EndpointApi; import org.duniter.core.client.model.bma.NetworkPeering; -import org.duniter.core.client.model.bma.NetworkPeerings; import org.duniter.core.util.Preconditions; import org.duniter.core.util.StringUtils; import org.duniter.core.util.http.InetAddressUtils; @@ -506,17 +505,17 @@ public class Peer implements LocalEntity<String>, Serializable { public static final String PROPERTY_BLOCK_HASH = "blockHash"; public static final String PROPERTY_RAW = "raw"; - private String version; + private Integer version; private String signature; private Integer blockNumber; private String blockHash; private String raw; - public String getVersion() { + public Integer getVersion() { return version; } - public void setVersion(String version) { + public void setVersion(Integer version) { this.version = version; } @@ -681,6 +680,10 @@ public class Peer implements LocalEntity<String>, Serializable { this.uid = uid; } + /** + * Last time the peer was UP (in millisecond) + * @return + */ public Long getLastUpTime() { return lastUpTime; } @@ -689,6 +692,10 @@ public class Peer implements LocalEntity<String>, Serializable { this.lastUpTime = lastUpTime; } + /** + * First time the peer was DOWN (in millisecond) + * @return + */ public Long getFirstDownTime() { return firstDownTime; } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java index b3da103f441d40f26ab6e4ddd242ee4ddbc82291..8e81c093297b2670b60bb97b3591a74b4cfd7f30 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/local/Peers.java @@ -118,27 +118,31 @@ public final class Peers { processedPubkeys.add(pubkey); // Get the first endpoint found for this pubkey - Peer peer = groupByPeering.get(peeringKey).iterator().next(); - NetworkPeers.Peer result = new NetworkPeers.Peer(); - - // Fill BMA peer, using the raw document - try { - NetworkPeerings.parse(peer.getPeering().getRaw(), result); - } catch (IOException e) { - log.error("Unable to parse raw document found in: " + peer.toString()); - return null; - } + for (Peer peer: groupByPeering.get(peeringKey)) { + NetworkPeers.Peer result = new NetworkPeers.Peer(); + + try { + // Fill BMA peer, using the raw document + NetworkPeerings.parse(peer.getPeering().getRaw(), result); + // Override the status, last_try and first_down, using stats + Peer.PeerStatus status = getStatus(peer).orElse(Peer.PeerStatus.DOWN); + result.setStatus(status.name()); + if (status == Peer.PeerStatus.UP) { + result.setLastTry(getLastUpTime(peer).get()); + } else { + result.setFirstDown(getFirstDownTime(peer).get()); + } + return result; + + } catch (IOException e) { + log.error("Unable to parse peering raw document found in: " + e.getMessage()); + // Continue to next endpoint + } + - // Override the status, last_try and first_down, using stats - Peer.PeerStatus status = getStatus(peer).orElse(Peer.PeerStatus.DOWN); - result.setStatus(status.name()); - if (status == Peer.PeerStatus.UP) { - result.setLastTry(getLastUpTime(peer).get()); - } - else { - result.setFirstDown(getFirstDownTime(peer).get()); } - return result; + + return null; }) // Remove skipped items .filter(Objects::nonNull) diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java index 4dce83170e714f75ad944375cdb20f18064ae545..2a104b5213d94ee86d3bf1a7016b9cdd32901a0e 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/NetworkServiceImpl.java @@ -38,6 +38,7 @@ import org.duniter.core.client.service.bma.WotRemoteService; import org.duniter.core.client.service.exception.HttpConnectException; import org.duniter.core.client.service.exception.HttpNotFoundException; import org.duniter.core.exception.TechnicalException; +import org.duniter.core.service.CryptoService; import org.duniter.core.util.*; import org.duniter.core.util.CollectionUtils; import org.duniter.core.util.concurrent.CompletableFutures; @@ -400,7 +401,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network final Predicate<Peer> peerFilter = peerFilter(filter); final Comparator<Peer> peerComparator = peerComparator(sort); final ExecutorService pool = (executor != null) ? executor : ForkJoinPool.commonPool(); - final int peerDownTimeoutMs = config.getPeerUpMaxAge(); + final int peerUpMaxAgeInMs = config.getPeerUpMaxAge(); // Refreshing one peer (e.g. received from WS) Consumer<List<Peer>> updateKnownBlocks = (updatedPeers) -> @@ -416,7 +417,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network List<Peer> result = getPeers(mainPeer, filter, sort, pool); // Mark old peers as DOWN - long maxUpTimeInSec = Math.round((System.currentTimeMillis() - peerDownTimeoutMs) / 1000); + long minUpTimeInMs = (System.currentTimeMillis() - peerUpMaxAgeInMs); knownBlocks.clear(); updateKnownBlocks.accept(result); @@ -425,7 +426,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network peerService.save(currency, result); // Set old peers as DOWN (with a delay) - peerService.updatePeersAsDown(currency, maxUpTimeInSec, filter.filterEndpoints); + peerService.updatePeersAsDown(currency, minUpTimeInMs, filter.filterEndpoints); long duration = System.currentTimeMillis() - now; @@ -571,9 +572,10 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network protected List<Peer> loadPeerLeafs(Peer peer, List<String> filterEndpoints) { List<String> leaves = networkRemoteService.getPeersLeaves(peer); - if (CollectionUtils.isEmpty(leaves)) return new ArrayList<>(); // should never occur + if (CollectionUtils.isEmpty(leaves)) return Lists.newArrayList(); // should never occur - List<Peer> result = new ArrayList<>(); + List<Peer> result = Lists.newArrayList(); + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); // If less than 100 node, get it in ONE call if (leaves.size() <= 2000) { @@ -585,7 +587,7 @@ public class NetworkServiceImpl extends BaseRemoteServiceImpl implements Network if (CollectionUtils.isEmpty(filterEndpoints) || StringUtils.isBlank(peerEp.getApi()) || filterEndpoints.contains(peerEp.getApi())) { - String hash = ServiceLocator.instance().getCryptoService().hash(peerEp.computeKey()); // compute the hash + String hash = cryptoService.hash(peerEp.computeKey()); // compute the hash peerEp.setHash(hash); result.add(peerEp); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerService.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerService.java index 2d5ba99f919d7a998572da65fbfe261c8ba09d3d..632fb2b245e26bd338d4d8e602fbaee2a99db899 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerService.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerService.java @@ -60,7 +60,7 @@ public interface PeerService extends Service { void updatePeersAsDown(String currencyId, Collection<String> filterApis); - void updatePeersAsDown(String currencyId, long maxUpTimeInSec, Collection<String> filterApis); + void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> filterApis); boolean isExists(String currencyId, String peerId); } diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java index a58d5723595a573a1ee0965961a4e9f2791723e6..41d69f0cd42fe45b1ef59905271cddf9a5a2b511 100644 --- a/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java +++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/service/local/PeerServiceImpl.java @@ -217,17 +217,17 @@ public class PeerServiceImpl implements PeerService, InitializingBean { int peerDownTimeoutMs = config.getPeerUpMaxAge(); // Mark old peers as DOWN if (peerDownTimeoutMs >0) { - long maxUpTimeInSec = Math.round((System.currentTimeMillis() - peerDownTimeoutMs) / 1000); + long maxUpTimeInSec = Math.round((System.currentTimeMillis() - peerDownTimeoutMs*1000)); updatePeersAsDown(currencyId, maxUpTimeInSec, filterApis); } } @Override - public void updatePeersAsDown(String currencyId, long maxUpTimeInSec, Collection<String> filterApis) { + public void updatePeersAsDown(String currencyId, long minUpTimeInMs, Collection<String> filterApis) { if (log.isDebugEnabled()) { - log.debug(String.format("[%s] %s Setting peers as DOWN, if older than [%s]...", currencyId, filterApis, new Date(maxUpTimeInSec*1000))); + log.debug(String.format("[%s] %s Setting peers as DOWN, if older than [%s]...", currencyId, filterApis, new Date(minUpTimeInMs *1000))); } - peerDao.updatePeersAsDown(currencyId, maxUpTimeInSec, filterApis); + peerDao.updatePeersAsDown(currencyId, minUpTimeInMs, filterApis); } protected Peer loadDefaultPeer(String currencyId) { diff --git a/duniter4j-core-shared/pom.xml b/duniter4j-core-shared/pom.xml index 342ae208ca24770445e8b478e0b82d07ab6dafd2..7b8e02fe482628fb28d099fe738d208fcd10ce06 100644 --- a/duniter4j-core-shared/pom.xml +++ b/duniter4j-core-shared/pom.xml @@ -64,6 +64,7 @@ <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> + </dependency> <dependency> <groupId>javax.mail</groupId> @@ -82,6 +83,11 @@ <artifactId>slf4j-log4j12</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> diff --git a/pom.xml b/pom.xml index 97068cecfb7551b28820cb96f8ec7ad6c5939623..653b8190d0ae41a4ce4ca6557d4350755662accc 100644 --- a/pom.xml +++ b/pom.xml @@ -170,6 +170,11 @@ <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <version>${slf4j.version}</version> + </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> @@ -230,21 +235,45 @@ <groupId>org.nuiton</groupId> <artifactId>nuiton-config</artifactId> <version>${nuitonConfigVersion}</version> + <exclusions> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-version</artifactId> <version>${nuitonVersionVersion}</version> + <exclusions> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> <version>${nuitonI18nVersion}</version> + <exclusions> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.6</version> + <exclusions> + <exclusion> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId>