0

对于 Java / OSGi 项目,我需要与插入计算机的智能卡进行通信。我使用包 javax.smartcardio 来做到这一点。

当我第一次导入这个包并想使用它时,Eclipse 宣布了一个错误“访问限制:'CommandAPDU' 类型不是 API”。正如https://www.javacardos.com/javacardforum/viewtopic.php?t=918所建议的那样,我在构建路径中添加了一个可访问性规则模式。之后,一切正常,我可以在本地环境中使用该包。

但现在我想将项目传递给我们的持续集成系统,即 Jenkins 和 Maven。我还提交了 .classpath 文件。在那里我得到了同样的错误:

[错误] 导入 javax.smartcardio.CommandAPDU;

[错误] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[错误] 访问限制:“CommandAPDU”类型不是 API(对类路径条目的限制“/disc2/lunifera/server/jenkins/workspace/tools/hudson.model.JDK/JDK-8/jre/lib/rt.jar ')

出于某种原因,访问规则似乎不适用于 Jenkins。有谁知道如何解决这个问题?非常感谢。

4

1 回答 1

0

不完全是我希望的那种答案,但最终,我通过使用反射克服了这个问题。我为需要的 javax.smartcardio 中的类编写了包装类。这些包装类包含原始类的实例,并纯粹通过反射对它们进行操作。例如, CardTerminal 类包装器可能如下所示:

public class CardTerminal {

   private Object originalCardTerminal;

   public CardTerminal(Object originalCardTerminal)
   {
       this.originalCardTerminal = originalCardTerminal;
   }

   public Card connect(String protocol)
   {
       try
       {
           Class originalCardTerminalClass   = Class.forName("javax.smartcardio.CardTerminal");
           Method connectMethod              = originalCardTerminalClass.getMethod("connect", String.class);
           Object originalCard               = connectMethod.invoke(originalCardTerminal, protocol);
        
           if (originalCard == null)
           {
               return null;
           }
           else
           {
               return new Card(originalCard);  // "Card" is another wrapper type, of course
           }
       }
       catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
       {
           return null;
       }  
   }}

当然,这不是一个好的解决方案,因为所有对象都只是“对象”类型,并且您失去了类型安全性。但这是迄今为止我找到的最好的解决方案,而且它正在工作,因为您不需要从 javax.smartcardio 导入任何内容。

于 2020-09-10T12:19:32.060 回答