Skip to content

Commit 61b96c7

Browse files
refactor: normalize log and exception messages (#33)
1 parent 611b03a commit 61b96c7

6 files changed

Lines changed: 73 additions & 50 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Changed
9+
- Normalized logging and error messages using Keyple coding standards.
810

911
## [2.6.1] - 2026-02-06
1012
### Changed
1113
- Split `MIFARE_CLASSIC` into two distinct protocols in `PcscCardCommunicationProtocol`:
1214
- `MIFARE_CLASSIC_1K` with ATR pattern `3B8F8001804F0CA000000306030001.*` (card type 0001)
1315
- `MIFARE_CLASSIC_4K` with ATR pattern `3B8F8001804F0CA000000306030002.*` (card type 0002)
1416
- Added `MIFARE_CLASSIC_1K` and `MIFARE_CLASSIC_4K` to the default enabled protocols in `PcscPluginAdapter`.
15-
- Normalize logging.
1617
### Upgraded
1718
- `keyple-common-java-api` from `2.0.1` to `2.0.2`
1819
- `keyple-plugin-java-api` from `2.3.1` to `2.3.2`

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ plugins {
1414
///////////////////////////////////////////////////////////////////////////////
1515

1616
dependencies {
17+
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
1718
implementation("org.eclipse.keyple:keyple-common-java-api:2.0.2")
1819
implementation("org.eclipse.keyple:keyple-plugin-java-api:2.3.2")
1920
implementation("org.eclipse.keyple:keyple-util-java-lib:2.4.1")
2021
implementation("net.java.dev.jna:jna:5.15.0")
2122
compileOnly("org.slf4j:slf4j-api:1.7.36")
22-
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
2323
}
2424

2525
tasks {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
group = org.eclipse.keyple
33
title = Keyple Plugin PCSC Java Lib
44
description = Keyple add-on to manage PC/SC readers
5-
version = 2.6.1-SNAPSHOT
5+
version = 2.6.2-SNAPSHOT
66

77
# Java Configuration
88
javaSourceLevel = 1.8

src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginAdapter.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ private List<CardTerminal> getCardTerminalList() throws PluginIOException {
220220
// the CardTerminals object is no more valid
221221
isCardTerminalsInitialized = false;
222222
} else if (e.getMessage().contains("SCARD_F_COMM_ERROR")) {
223-
logger.error("Reader communication error");
223+
logger.error("Reader communication error occurred");
224224
} else {
225225
throw new PluginIOException("Could not access terminals list", e);
226226
}
@@ -236,18 +236,18 @@ private List<CardTerminal> getCardTerminalList() throws PluginIOException {
236236
@Override
237237
public ReaderSpi searchReader(String readerName) throws PluginIOException {
238238
if (logger.isTraceEnabled()) {
239-
logger.trace("Plugin [{}]: search reader [{}]", getName(), readerName);
239+
logger.trace("Searching reader [reader={}]", readerName);
240240
}
241241
for (CardTerminal terminal : getCardTerminalList()) {
242242
if (readerName.equals(terminal.getName())) {
243243
if (logger.isTraceEnabled()) {
244-
logger.trace("Plugin [{}]: reader found", getName());
244+
logger.trace("Reader found");
245245
}
246246
return createReader(terminal);
247247
}
248248
}
249249
if (logger.isTraceEnabled()) {
250-
logger.trace("Plugin [{}]: reader not found", getName());
250+
logger.trace("Reader not found");
251251
}
252252
return null;
253253
}
@@ -303,11 +303,9 @@ PcscPluginAdapter setContactlessReaderIdentificationFilterPattern(
303303
PcscPluginAdapter addProtocolRulesMap(Map<String, String> protocolRulesMap) {
304304
if (!protocolRulesMap.isEmpty()) {
305305
logger.info(
306-
"Plugin [{}]: add protocol identification rules: {}",
307-
getName(),
308-
JsonUtil.toJson(protocolRulesMap));
306+
"Adding protocol identification rules [rules={}]", JsonUtil.toJson(protocolRulesMap));
309307
} else {
310-
logger.info("Plugin [{}]: use default protocol identification rules", getName());
308+
logger.info("Using default protocol identification rules");
311309
}
312310
PcscPluginAdapter.protocolRulesMap.putAll(protocolRulesMap);
313311
return this;

src/main/java/org/eclipse/keyple/plugin/pcsc/PcscPluginFactoryBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public Builder useContactlessReaderIdentificationFilter(
120120
this.contactlessReaderIdentificationFilterPattern =
121121
Pattern.compile(contactlessReaderIdentificationFilter);
122122
} catch (Exception e) {
123-
throw new IllegalArgumentException("Bad regular expression.", e);
123+
throw new IllegalArgumentException("Bad regular expression", e);
124124
}
125125
return this;
126126
}

src/main/java/org/eclipse/keyple/plugin/pcsc/PcscReaderAdapter.java

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private CardTerminal createMonitoringTerminal(String terminalName) {
107107
if (t.getName().equals(terminalName)) {
108108
if (logger.isDebugEnabled()) {
109109
logger.debug(
110-
"[{}] creating separate monitoring context for improved Linux compatibility",
110+
"[readerExt={}] Separate monitoring context created to improve Linux compatibility",
111111
terminalName);
112112
}
113113
return t;
@@ -116,14 +116,14 @@ private CardTerminal createMonitoringTerminal(String terminalName) {
116116

117117
// Terminal not found in new context, fall back to same terminal
118118
logger.warn(
119-
"[{}] could not find terminal in separate context, using shared context (may cause issues on Linux)",
119+
"[readerExt={}] Could not find terminal in separate context, using shared context (may cause issues on Linux)",
120120
terminalName);
121121
return communicationTerminal;
122122

123123
} catch (Exception e) {
124124
// Failed to create separate context, fall back to same terminal
125125
logger.warn(
126-
"[{}] could not create separate monitoring context [reason={}], using shared context (may cause issues on Linux)",
126+
"[readerExt={}] Could not create separate monitoring context [reason={}], using shared context (may cause issues on Linux)",
127127
terminalName,
128128
e.getMessage());
129129
return communicationTerminal;
@@ -140,7 +140,7 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti
140140

141141
if (logger.isTraceEnabled()) {
142142
logger.trace(
143-
"[{}] start waiting card insertion (loop latency: {} ms)...",
143+
"[readerExt={}] Starting waiting card insertion [loopLatencyMs={}]",
144144
getName(),
145145
cardMonitoringCycleDuration);
146146
}
@@ -153,7 +153,7 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti
153153
if (monitoringTerminal.waitForCardPresent(cardMonitoringCycleDuration)) {
154154
// card inserted
155155
if (logger.isTraceEnabled()) {
156-
logger.trace("[{}] card inserted", getName());
156+
logger.trace("[readerExt={}] Card inserted", getName());
157157
}
158158
return;
159159
}
@@ -162,15 +162,14 @@ public void waitForCardInsertion() throws TaskCanceledException, ReaderIOExcepti
162162
}
163163
}
164164
if (logger.isTraceEnabled()) {
165-
logger.trace("[{}] waiting card insertion stopped", getName());
165+
logger.trace("[readerExt={}] Waiting card insertion stopped", getName());
166166
}
167167
} catch (CardException e) {
168168
// here, it is a communication failure with the reader
169-
throw new ReaderIOException(
170-
name + ": an error occurred while waiting for a card insertion", e);
169+
throw new ReaderIOException("Failed to wait for a card insertion. Reader: " + name, e);
171170
}
172171
throw new TaskCanceledException(
173-
name + ": the wait for a card insertion task has been cancelled");
172+
"The wait for a card insertion task has been cancelled. Reader: " + name);
174173
}
175174

176175
/**
@@ -201,7 +200,10 @@ public boolean isProtocolSupported(String readerProtocol) {
201200
@Override
202201
public void activateProtocol(String readerProtocol) {
203202
if (logger.isTraceEnabled()) {
204-
logger.trace("[{}] activating protocol [{}] takes no action", getName(), readerProtocol);
203+
logger.trace(
204+
"[readerExt={}] Activating protocol takes no action [protocol={}]",
205+
getName(),
206+
readerProtocol);
205207
}
206208
}
207209

@@ -213,7 +215,10 @@ public void activateProtocol(String readerProtocol) {
213215
@Override
214216
public void deactivateProtocol(String readerProtocol) {
215217
if (logger.isTraceEnabled()) {
216-
logger.trace("[{}] de-activating protocol [{}] takes no action", getName(), readerProtocol);
218+
logger.trace(
219+
"[readerExt={}] de-activating protocol takes no action [protocol={}]",
220+
getName(),
221+
readerProtocol);
217222
}
218223
}
219224

@@ -278,24 +283,25 @@ public void openPhysicalChannel() throws ReaderIOException, CardIOException {
278283
/* init of the card physical channel: if not yet established, opening of a new physical channel */
279284
try {
280285
if (logger.isDebugEnabled()) {
281-
logger.debug("[{}] opening card physical channel for protocol [{}]", getName(), protocol);
286+
logger.debug(
287+
"[readerExt={}] Opening card physical channel [protocol={}]", getName(), protocol);
282288
}
283289
card = this.communicationTerminal.connect(protocol);
284290
if (isModeExclusive) {
285291
card.beginExclusive();
286292
if (logger.isDebugEnabled()) {
287-
logger.debug("[{}] card physical channel opened in EXCLUSIVE mode", getName());
293+
logger.debug("[readerExt={}] Card physical channel opened [mode=EXCLUSIVE]", getName());
288294
}
289295
} else {
290296
if (logger.isDebugEnabled()) {
291-
logger.debug("[{}] card physical channel opened in SHARED mode", getName());
297+
logger.debug("[readerExt={}] Card physical channel opened [mode=SHARED]", getName());
292298
}
293299
}
294300
channel = card.getBasicChannel();
295301
} catch (CardNotPresentException e) {
296-
throw new CardIOException(getName() + ": Card removed", e);
302+
throw new CardIOException("Card removed. Reader: " + name, e);
297303
} catch (CardException e) {
298-
throw new ReaderIOException(getName() + ": Error while opening Physical Channel", e);
304+
throw new ReaderIOException("Failed to open the physical channel. Reader: " + name, e);
299305
}
300306
}
301307

@@ -341,7 +347,7 @@ private void disconnect() throws ReaderIOException {
341347
}
342348
}
343349
} catch (CardException e) {
344-
throw new ReaderIOException("Error while closing physical channel", e);
350+
throw new ReaderIOException("Failed to close the physical channel. Reader: " + name, e);
345351
} finally {
346352
resetContext();
347353
}
@@ -408,7 +414,7 @@ public boolean checkCardPresence() throws ReaderIOException {
408414
closePhysicalChannelSafely();
409415
return isCardPresent;
410416
} catch (CardException e) {
411-
throw new ReaderIOException("Exception occurred in isCardPresent", e);
417+
throw new ReaderIOException("Failed to check card presence. Reader: " + name, e);
412418
}
413419
}
414420

@@ -447,22 +453,28 @@ public byte[] transmitApdu(byte[] apduCommandData) throws ReaderIOException, Car
447453
try {
448454
apduResponseData = channel.transmit(new CommandAPDU(apduCommandData)).getBytes();
449455
} catch (CardNotPresentException e) {
450-
throw new CardIOException(name + ": " + e.getMessage(), e);
456+
throw new CardIOException(
457+
"Card is not present. Unable to transmit APDU. Reader: " + name, e);
451458
} catch (CardException e) {
452459
if (e.getMessage().contains("CARD")
453460
|| e.getMessage().contains("NOT_TRANSACTED")
454461
|| e.getMessage().contains("INVALID_ATR")) {
455-
throw new CardIOException(name + ": " + e.getMessage(), e);
462+
throw new CardIOException(
463+
"Failed to communicate with card. Unable to transmit APDU. Reader: " + name, e);
456464
} else {
457-
throw new ReaderIOException(name + ": " + e.getMessage(), e);
465+
throw new ReaderIOException(
466+
"Failed to communicate with card reader. Unable to transmit APDU. Reader: " + name,
467+
e);
458468
}
459469
} catch (IllegalStateException | IllegalArgumentException e) {
460470
// card could have been removed prematurely
461-
throw new CardIOException(name + ": " + e.getMessage(), e);
471+
throw new CardIOException(
472+
"Card could have been removed prematurely. Unable to transmit APDU. Reader: " + name,
473+
e);
462474
}
463475
} else {
464476
// could occur if the card was removed
465-
throw new CardIOException(name + ": null channel.");
477+
throw new CardIOException("Card channel is null. Unable to transmit APDU. Reader: " + name);
466478
}
467479
return apduResponseData;
468480
}
@@ -521,7 +533,7 @@ public void stopCardPresenceMonitoringDuringProcessing() {
521533
@Override
522534
public void waitForCardRemoval() throws ReaderIOException, TaskCanceledException {
523535
if (logger.isTraceEnabled()) {
524-
logger.trace("[{}] start waiting card removal)", name);
536+
logger.trace("[readerExt={}] Starting waiting card removal", name);
525537
}
526538
loopWaitCardRemoval.set(true);
527539
try {
@@ -535,19 +547,21 @@ public void waitForCardRemoval() throws ReaderIOException, TaskCanceledException
535547
disconnect();
536548
} catch (Exception e) {
537549
logger.warn(
538-
"[{}] error while disconnecting card during card removal: {}", name, e.getMessage());
550+
"[readerExt={}] Failed to disconnect card during card removal sequence [reason={}]",
551+
name,
552+
e.getMessage());
539553
}
540554
}
541555
if (logger.isTraceEnabled()) {
542556
if (!loopWaitCardRemoval.get()) {
543-
logger.trace("[{}] waiting card removal stopped", name);
557+
logger.trace("[readerExt={}] Waiting card removal stopped", name);
544558
} else {
545-
logger.trace("[{}] card removed", name);
559+
logger.trace("[readerExt={}] Card removed", name);
546560
}
547561
}
548562
if (!loopWaitCardRemoval.get()) {
549563
throw new TaskCanceledException(
550-
name + ": the wait for the card removal task has been cancelled.");
564+
"The wait for the card removal task has been cancelled. Reader: " + name);
551565
}
552566
}
553567

@@ -561,9 +575,19 @@ private void waitForCardRemovalByPolling() {
561575
}
562576
}
563577
} catch (CardIOException | ReaderIOException e) {
564-
logger.trace("Expected IOException while waiting for card removal: {}", e.getMessage());
578+
if (logger.isTraceEnabled()) {
579+
logger.trace(
580+
"[readerExt={}] Expected IOException received while waiting for card removal [reason={}]",
581+
getName(),
582+
e.getMessage());
583+
}
565584
} catch (InterruptedException e) {
566-
logger.trace("InterruptedException while waiting for card removal: {}", e.getMessage());
585+
if (logger.isTraceEnabled()) {
586+
logger.trace(
587+
"[readerExt={}] InterruptedException received while waiting for card removal: {}",
588+
getName(),
589+
e.getMessage());
590+
}
567591
Thread.currentThread().interrupt();
568592
}
569593
}
@@ -579,8 +603,7 @@ private void waitForCardRemovalStandard() throws ReaderIOException {
579603
}
580604
}
581605
} catch (CardException e) {
582-
throw new ReaderIOException(
583-
name + ": an error occurred while waiting for the card removal.", e);
606+
throw new ReaderIOException("Failed to wait for the card removal. Reader: " + name, e);
584607
}
585608
}
586609

@@ -604,14 +627,14 @@ public void stopWaitForCardRemoval() {
604627
@Override
605628
public PcscReader setSharingMode(SharingMode sharingMode) {
606629
Assert.getInstance().notNull(sharingMode, "sharingMode");
607-
logger.info("[{}] set sharing mode [newValue={}]", getName(), sharingMode.name());
630+
logger.info("[readerExt={}] Set sharing mode [value={}]", getName(), sharingMode.name());
608631
if (sharingMode == SharingMode.SHARED) {
609632
// if a card is present, change the mode immediately
610633
if (card != null) {
611634
try {
612635
card.endExclusive();
613636
} catch (CardException e) {
614-
throw new IllegalStateException("Couldn't disable exclusive mode", e);
637+
throw new IllegalStateException("Failed to disable exclusive mode. Reader: " + name, e);
615638
}
616639
}
617640
isModeExclusive = false;
@@ -628,7 +651,7 @@ public PcscReader setSharingMode(SharingMode sharingMode) {
628651
*/
629652
@Override
630653
public PcscReader setContactless(boolean contactless) {
631-
logger.info("[{}] set contactless type [newValue={}]", getName(), contactless);
654+
logger.info("[readerExt={}] Set contactless type [value={}]", getName(), contactless);
632655
this.isContactless = contactless;
633656
return this;
634657
}
@@ -642,7 +665,7 @@ public PcscReader setContactless(boolean contactless) {
642665
public PcscReader setIsoProtocol(IsoProtocol isoProtocol) {
643666
Assert.getInstance().notNull(isoProtocol, "isoProtocol");
644667
logger.info(
645-
"[{}] set ISO protocol [protocolName={}, newValue={}]",
668+
"[readerExt={}] Set ISO protocol [protocol={}, value={}]",
646669
getName(),
647670
isoProtocol.name(),
648671
isoProtocol.getValue());
@@ -658,7 +681,8 @@ public PcscReader setIsoProtocol(IsoProtocol isoProtocol) {
658681
@Override
659682
public PcscReader setDisconnectionMode(DisconnectionMode disconnectionMode) {
660683
Assert.getInstance().notNull(disconnectionMode, "disconnectionMode");
661-
logger.info("[{}] set disconnection mode [newValue={}]", getName(), disconnectionMode.name());
684+
logger.info(
685+
"[readerExt={}] Set disconnection mode [value={}]", getName(), disconnectionMode.name());
662686
this.disconnectionMode = disconnectionMode;
663687
return this;
664688
}
@@ -682,7 +706,7 @@ public byte[] transmitControlCommand(int commandId, byte[] command) {
682706
virtualCard.disconnect(false);
683707
}
684708
} catch (CardException e) {
685-
throw new IllegalStateException("Reader failure.", e);
709+
throw new IllegalStateException("Failed to transmit control command. Reader: " + name, e);
686710
}
687711
return response;
688712
}

0 commit comments

Comments
 (0)