diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f05a1a..d899896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Normalized logging and error messages using Keyple coding standards. ## [2.6.1] - 2026-02-06 ### Changed @@ -12,7 +14,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `MIFARE_CLASSIC_1K` with ATR pattern `3B8F8001804F0CA000000306030001.*` (card type 0001) - `MIFARE_CLASSIC_4K` with ATR pattern `3B8F8001804F0CA000000306030002.*` (card type 0002) - Added `MIFARE_CLASSIC_1K` and `MIFARE_CLASSIC_4K` to the default enabled protocols in `PcscPluginAdapter`. -- Normalize logging. ### Upgraded - `keyple-common-java-api` from `2.0.1` to `2.0.2` - `keyple-plugin-java-api` from `2.3.1` to `2.3.2` diff --git a/build.gradle.kts b/build.gradle.kts index 4266981..55084bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,12 +14,12 @@ plugins { /////////////////////////////////////////////////////////////////////////////// dependencies { + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation("org.eclipse.keyple:keyple-common-java-api:2.0.2") implementation("org.eclipse.keyple:keyple-plugin-java-api:2.3.2") implementation("org.eclipse.keyple:keyple-util-java-lib:2.4.1") implementation("net.java.dev.jna:jna:5.15.0") compileOnly("org.slf4j:slf4j-api:1.7.36") - implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) } tasks { diff --git a/gradle.properties b/gradle.properties index d34594a..2bf642d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ group = org.eclipse.keyple title = Keyple Plugin PCSC Java Lib description = Keyple add-on to manage PC/SC readers -version = 2.6.1-SNAPSHOT +version = 2.6.2-SNAPSHOT # Java Configuration javaSourceLevel = 1.8 diff --git a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginAdapter.java b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginAdapter.java index 9768b3b..4dc57bd 100644 --- a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginAdapter.java +++ b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginAdapter.java @@ -220,7 +220,7 @@ private List getCardTerminalList() throws PluginIOException { // the CardTerminals object is no more valid isCardTerminalsInitialized = false; } else if (e.getMessage().contains("SCARD_F_COMM_ERROR")) { - logger.error("Reader communication error"); + logger.error("Reader communication error occurred"); } else { throw new PluginIOException("Could not access terminals list", e); } @@ -236,18 +236,18 @@ private List getCardTerminalList() throws PluginIOException { @Override public ReaderSpi searchReader(String readerName) throws PluginIOException { if (logger.isTraceEnabled()) { - logger.trace("Plugin [{}]: search reader [{}]", getName(), readerName); + logger.trace("Searching reader [reader={}]", readerName); } for (CardTerminal terminal : getCardTerminalList()) { if (readerName.equals(terminal.getName())) { if (logger.isTraceEnabled()) { - logger.trace("Plugin [{}]: reader found", getName()); + logger.trace("Reader found"); } return createReader(terminal); } } if (logger.isTraceEnabled()) { - logger.trace("Plugin [{}]: reader not found", getName()); + logger.trace("Reader not found"); } return null; } @@ -303,11 +303,9 @@ PcscPluginAdapter setContactlessReaderIdentificationFilterPattern( PcscPluginAdapter addProtocolRulesMap(Map protocolRulesMap) { if (!protocolRulesMap.isEmpty()) { logger.info( - "Plugin [{}]: add protocol identification rules: {}", - getName(), - JsonUtil.toJson(protocolRulesMap)); + "Adding protocol identification rules [rules={}]", JsonUtil.toJson(protocolRulesMap)); } else { - logger.info("Plugin [{}]: use default protocol identification rules", getName()); + logger.info("Using default protocol identification rules"); } PcscPluginAdapter.protocolRulesMap.putAll(protocolRulesMap); return this; diff --git a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginFactoryBuilder.java b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginFactoryBuilder.java index 15ed866..3af57e0 100644 --- a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginFactoryBuilder.java +++ b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginFactoryBuilder.java @@ -120,7 +120,7 @@ public Builder useContactlessReaderIdentificationFilter( this.contactlessReaderIdentificationFilterPattern = Pattern.compile(contactlessReaderIdentificationFilter); } catch (Exception e) { - throw new IllegalArgumentException("Bad regular expression.", e); + throw new IllegalArgumentException("Bad regular expression", e); } return this; } diff --git a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscReaderAdapter.java b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscReaderAdapter.java index 7ed6f38..81ed3e7 100644 --- a/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscReaderAdapter.java +++ b/src/main/java/org/eclipse/keyple/plugin/pcsc/PcscReaderAdapter.java @@ -107,7 +107,7 @@ private CardTerminal createMonitoringTerminal(String terminalName) { if (t.getName().equals(terminalName)) { if (logger.isDebugEnabled()) { logger.debug( - "[{}] creating separate monitoring context for improved Linux compatibility", + "[readerExt={}] Separate monitoring context created to improve Linux compatibility", terminalName); } return t; @@ -116,14 +116,14 @@ private CardTerminal createMonitoringTerminal(String terminalName) { // Terminal not found in new context, fall back to same terminal logger.warn( - "[{}] could not find terminal in separate context, using shared context (may cause issues on Linux)", + "[readerExt={}] Could not find terminal in separate context, using shared context (may cause issues on Linux)", terminalName); return communicationTerminal; } catch (Exception e) { // Failed to create separate context, fall back to same terminal logger.warn( - "[{}] could not create separate monitoring context [reason={}], using shared context (may cause issues on Linux)", + "[readerExt={}] Could not create separate monitoring context [reason={}], using shared context (may cause issues on Linux)", terminalName, e.getMessage()); return communicationTerminal; @@ -140,7 +140,7 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti if (logger.isTraceEnabled()) { logger.trace( - "[{}] start waiting card insertion (loop latency: {} ms)...", + "[readerExt={}] Starting waiting card insertion [loopLatencyMs={}]", getName(), cardMonitoringCycleDuration); } @@ -153,7 +153,7 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti if (monitoringTerminal.waitForCardPresent(cardMonitoringCycleDuration)) { // card inserted if (logger.isTraceEnabled()) { - logger.trace("[{}] card inserted", getName()); + logger.trace("[readerExt={}] Card inserted", getName()); } return; } @@ -162,15 +162,14 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti } } if (logger.isTraceEnabled()) { - logger.trace("[{}] waiting card insertion stopped", getName()); + logger.trace("[readerExt={}] Waiting card insertion stopped", getName()); } } catch (CardException e) { // here, it is a communication failure with the reader - throw new ReaderIOException( - name + ": an error occurred while waiting for a card insertion", e); + throw new ReaderIOException("Failed to wait for a card insertion. Reader: " + name, e); } throw new TaskCanceledException( - name + ": the wait for a card insertion task has been cancelled"); + "The wait for a card insertion task has been cancelled. Reader: " + name); } /** @@ -201,7 +200,10 @@ public boolean isProtocolSupported(String readerProtocol) { @Override public void activateProtocol(String readerProtocol) { if (logger.isTraceEnabled()) { - logger.trace("[{}] activating protocol [{}] takes no action", getName(), readerProtocol); + logger.trace( + "[readerExt={}] Activating protocol takes no action [protocol={}]", + getName(), + readerProtocol); } } @@ -213,7 +215,10 @@ public void activateProtocol(String readerProtocol) { @Override public void deactivateProtocol(String readerProtocol) { if (logger.isTraceEnabled()) { - logger.trace("[{}] de-activating protocol [{}] takes no action", getName(), readerProtocol); + logger.trace( + "[readerExt={}] de-activating protocol takes no action [protocol={}]", + getName(), + readerProtocol); } } @@ -278,24 +283,25 @@ public void openPhysicalChannel() throws ReaderIOException, CardIOException { /* init of the card physical channel: if not yet established, opening of a new physical channel */ try { if (logger.isDebugEnabled()) { - logger.debug("[{}] opening card physical channel for protocol [{}]", getName(), protocol); + logger.debug( + "[readerExt={}] Opening card physical channel [protocol={}]", getName(), protocol); } card = this.communicationTerminal.connect(protocol); if (isModeExclusive) { card.beginExclusive(); if (logger.isDebugEnabled()) { - logger.debug("[{}] card physical channel opened in EXCLUSIVE mode", getName()); + logger.debug("[readerExt={}] Card physical channel opened [mode=EXCLUSIVE]", getName()); } } else { if (logger.isDebugEnabled()) { - logger.debug("[{}] card physical channel opened in SHARED mode", getName()); + logger.debug("[readerExt={}] Card physical channel opened [mode=SHARED]", getName()); } } channel = card.getBasicChannel(); } catch (CardNotPresentException e) { - throw new CardIOException(getName() + ": Card removed", e); + throw new CardIOException("Card removed. Reader: " + name, e); } catch (CardException e) { - throw new ReaderIOException(getName() + ": Error while opening Physical Channel", e); + throw new ReaderIOException("Failed to open the physical channel. Reader: " + name, e); } } @@ -341,7 +347,7 @@ private void disconnect() throws ReaderIOException { } } } catch (CardException e) { - throw new ReaderIOException("Error while closing physical channel", e); + throw new ReaderIOException("Failed to close the physical channel. Reader: " + name, e); } finally { resetContext(); } @@ -408,7 +414,7 @@ public boolean checkCardPresence() throws ReaderIOException { closePhysicalChannelSafely(); return isCardPresent; } catch (CardException e) { - throw new ReaderIOException("Exception occurred in isCardPresent", e); + throw new ReaderIOException("Failed to check card presence. Reader: " + name, e); } } @@ -447,22 +453,28 @@ public byte[] transmitApdu(byte[] apduCommandData) throws ReaderIOException, Car try { apduResponseData = channel.transmit(new CommandAPDU(apduCommandData)).getBytes(); } catch (CardNotPresentException e) { - throw new CardIOException(name + ": " + e.getMessage(), e); + throw new CardIOException( + "Card is not present. Unable to transmit APDU. Reader: " + name, e); } catch (CardException e) { if (e.getMessage().contains("CARD") || e.getMessage().contains("NOT_TRANSACTED") || e.getMessage().contains("INVALID_ATR")) { - throw new CardIOException(name + ": " + e.getMessage(), e); + throw new CardIOException( + "Failed to communicate with card. Unable to transmit APDU. Reader: " + name, e); } else { - throw new ReaderIOException(name + ": " + e.getMessage(), e); + throw new ReaderIOException( + "Failed to communicate with card reader. Unable to transmit APDU. Reader: " + name, + e); } } catch (IllegalStateException | IllegalArgumentException e) { // card could have been removed prematurely - throw new CardIOException(name + ": " + e.getMessage(), e); + throw new CardIOException( + "Card could have been removed prematurely. Unable to transmit APDU. Reader: " + name, + e); } } else { // could occur if the card was removed - throw new CardIOException(name + ": null channel."); + throw new CardIOException("Card channel is null. Unable to transmit APDU. Reader: " + name); } return apduResponseData; } @@ -521,7 +533,7 @@ public void stopCardPresenceMonitoringDuringProcessing() { @Override public void waitForCardRemoval() throws ReaderIOException, TaskCanceledException { if (logger.isTraceEnabled()) { - logger.trace("[{}] start waiting card removal)", name); + logger.trace("[readerExt={}] Starting waiting card removal", name); } loopWaitCardRemoval.set(true); try { @@ -535,19 +547,21 @@ public void waitForCardRemoval() throws ReaderIOException, TaskCanceledException disconnect(); } catch (Exception e) { logger.warn( - "[{}] error while disconnecting card during card removal: {}", name, e.getMessage()); + "[readerExt={}] Failed to disconnect card during card removal sequence [reason={}]", + name, + e.getMessage()); } } if (logger.isTraceEnabled()) { if (!loopWaitCardRemoval.get()) { - logger.trace("[{}] waiting card removal stopped", name); + logger.trace("[readerExt={}] Waiting card removal stopped", name); } else { - logger.trace("[{}] card removed", name); + logger.trace("[readerExt={}] Card removed", name); } } if (!loopWaitCardRemoval.get()) { throw new TaskCanceledException( - name + ": the wait for the card removal task has been cancelled."); + "The wait for the card removal task has been cancelled. Reader: " + name); } } @@ -561,9 +575,19 @@ private void waitForCardRemovalByPolling() { } } } catch (CardIOException | ReaderIOException e) { - logger.trace("Expected IOException while waiting for card removal: {}", e.getMessage()); + if (logger.isTraceEnabled()) { + logger.trace( + "[readerExt={}] Expected IOException received while waiting for card removal [reason={}]", + getName(), + e.getMessage()); + } } catch (InterruptedException e) { - logger.trace("InterruptedException while waiting for card removal: {}", e.getMessage()); + if (logger.isTraceEnabled()) { + logger.trace( + "[readerExt={}] InterruptedException received while waiting for card removal: {}", + getName(), + e.getMessage()); + } Thread.currentThread().interrupt(); } } @@ -579,8 +603,7 @@ private void waitForCardRemovalStandard() throws ReaderIOException { } } } catch (CardException e) { - throw new ReaderIOException( - name + ": an error occurred while waiting for the card removal.", e); + throw new ReaderIOException("Failed to wait for the card removal. Reader: " + name, e); } } @@ -604,14 +627,14 @@ public void stopWaitForCardRemoval() { @Override public PcscReader setSharingMode(SharingMode sharingMode) { Assert.getInstance().notNull(sharingMode, "sharingMode"); - logger.info("[{}] set sharing mode [newValue={}]", getName(), sharingMode.name()); + logger.info("[readerExt={}] Set sharing mode [value={}]", getName(), sharingMode.name()); if (sharingMode == SharingMode.SHARED) { // if a card is present, change the mode immediately if (card != null) { try { card.endExclusive(); } catch (CardException e) { - throw new IllegalStateException("Couldn't disable exclusive mode", e); + throw new IllegalStateException("Failed to disable exclusive mode. Reader: " + name, e); } } isModeExclusive = false; @@ -628,7 +651,7 @@ public PcscReader setSharingMode(SharingMode sharingMode) { */ @Override public PcscReader setContactless(boolean contactless) { - logger.info("[{}] set contactless type [newValue={}]", getName(), contactless); + logger.info("[readerExt={}] Set contactless type [value={}]", getName(), contactless); this.isContactless = contactless; return this; } @@ -642,7 +665,7 @@ public PcscReader setContactless(boolean contactless) { public PcscReader setIsoProtocol(IsoProtocol isoProtocol) { Assert.getInstance().notNull(isoProtocol, "isoProtocol"); logger.info( - "[{}] set ISO protocol [protocolName={}, newValue={}]", + "[readerExt={}] Set ISO protocol [protocol={}, value={}]", getName(), isoProtocol.name(), isoProtocol.getValue()); @@ -658,7 +681,8 @@ public PcscReader setIsoProtocol(IsoProtocol isoProtocol) { @Override public PcscReader setDisconnectionMode(DisconnectionMode disconnectionMode) { Assert.getInstance().notNull(disconnectionMode, "disconnectionMode"); - logger.info("[{}] set disconnection mode [newValue={}]", getName(), disconnectionMode.name()); + logger.info( + "[readerExt={}] Set disconnection mode [value={}]", getName(), disconnectionMode.name()); this.disconnectionMode = disconnectionMode; return this; } @@ -682,7 +706,7 @@ public byte[] transmitControlCommand(int commandId, byte[] command) { virtualCard.disconnect(false); } } catch (CardException e) { - throw new IllegalStateException("Reader failure.", e); + throw new IllegalStateException("Failed to transmit control command. Reader: " + name, e); } return response; }