Class javacard.framework.service.CardRemoteObject not found
Asked Answered
F

1

6

I'm newer in Java Card Platform so please be patient with me. I'm trying to develop an RMI application for the Java Card 3 Platform. My IDE is Eclipse and my OS is Windows 10. I start by creating a simple interface IContor.java responsible for increasing, decreasing, etc. certain values.

Here is my interface:

package sid;
import java.rmi.Remote;
import java.rmi.RemoteException;

import javacard.framework.UserException;

public interface IContor extends Remote{
   public void Incrementer()throws RemoteException,UserException;
   public void Decrementer()throws RemoteException,UserException;
   public byte GetValue()throws RemoteException,UserException;
   public void Init(byte value)throws RemoteException,UserException;
}

Then I provide an implementation for this interface which I named Contor.java:

package sid;

import java.rmi.RemoteException;
import javacard.framework.UserException;
import javacard.framework.service.CardRemoteObject;

public class Contor extends CardRemoteObject implements IContor {
   private byte contor = 0;
    @Override
    public void Incrementer() throws RemoteException, UserException {
        ++contor;
    }

    @Override
    public void Decrementer() throws RemoteException, UserException {
        --contor;
    }

    @Override
    public byte GetValue() throws RemoteException, UserException {
        return contor;
    }

    @Override
    public void Init(byte value) throws RemoteException, UserException {
        contor = value;
    }
}

My Test applet worked ok. Below I wrote that peace of code:

package sid;

import javacard.framework.*;
import javacard.framework.service.Dispatcher;
import javacard.framework.service.RMIService;

public class Test extends Applet {
    Dispatcher dispatcher;

    public static void install(byte[] bArray, short bOffset, byte bLength) {
       new Test().register();
    }

    protected Test() {
       RMIService rmiService = new RMIService(new Contor());
       dispatcher = new Dispatcher((short)1);
       dispatcher.addService(rmiService,Dispatcher.PROCESS_COMMAND);
    }

    @Override
    public void process(APDU apdu) {
        dispatcher.process(apdu);
    }
}

This is a standard piece of code. However I want to create a client which uses that interface which implements the interface Remote. So I create a Java application in which I copied the IContor.java interface. Then I opened a command prompt and do the following things:

  • Go into the directory where the source files of the first project is located (cd bla_bla/Contor/src)
  • Go a directory up (cd ..)
  • Go into bin directory (cd bin)

Here I have located the name of the package ( sid) and into package sid I have those three files (Contor.class, IContor.class and Test.class). Then I typed the following command on the command prompt:

rmic -v1.2 -classpath .;%JC_CLASSIC_HOME%lib/tools.jar -sid/Contor

but I got the following error:

Class javacard.framework.service.CardRemoteObject not found in class sid.Contor.

I replace the tools.jar with api_classic.jar but I still get the same error . The %JC_CLASSIC_HOME% contains the path to the Java Card 3 development kit. tools.jar contains compiled implementations of packages javacard.framework, javacard.security, javacardx.biometry, javacardx.external and javacardx.framework.tlv . My bout is to generate a client application in bin/sid directory.My %JC_CLASSIC_HOME% value is C:\Program Files (x86)\Oracle\Java Card Development Kit 3.0.5ga\ and I'm using JDK 1.8

Here is my Package Explorer from Eclipse :

enter image description here

Fariss answered 22/9, 2015 at 10:49 Comment(0)
T
1

What does the error "Class javacard.framework.service.CardRemoteObject not found in class sid.Contor." mean?

This means that you reference the class CardRemoteObject from within your class Contor (as Contor extends CardRemoteObject). However, the class path that you use to compile the RMI stub does not contain this class.

The class javacard.framework.service.CardRemoteObject is located in lib/api_classic.jar. Hence, the correct class path for the Java Card Classic API (which is what you need to generate the stub class for RMI) is lib/api_classic.jar. lib/tools.jar is the Java archive that you later need to compile your client applications against. lib/tools.jar only contains the Java Card related exception classes. However, for compiling the remote interface stub you need the whole Java Card API (at least those classes that are referenced from your interface classes).

How does -classpath work?

The parameter -classpath is a list of directories and/or Java archives (.jar files) that contain all the relevant classes to compile a given Java source file (for javac, the Java compiler) or to compile an RMI interface stub from a given Java class file (for rmic, the Java RMI compiler).

For instance, the parameter -classpath .;"%JC_CLASSIC_HOME%/lib/api_classic.jar" specifies two paths (multiple paths are separated by semicolons (";")):

  1. . specifies the current directory (in your case the bin directory).
  2. "%JC_CLASSIC_HOME%/lib/api_classic.jar" specifiees the Java archive api_classic.jar from your Java Card Development Kit.

Within those paths, classes are organized in directories mapping to the components of the Java package names (e.g. a class sid.Contor would be located in a file sid/Contor.class; a class javacard.framework.service.CardRemoteObject would be located in a file javacard/framework/service/CardRemoteObject.class).

How to compile the RMI stub?

  1. Goto your src directory.
  2. Compile the Java classes of the applet. In your case, you could use something like:

    javac -classpath .;"%JC_CLASSIC_HOME%/lib/api_classic.jar" -d ../bin sid/IContor.java sid/Contor.java sid/Test.java
    
  3. Goto your bin directory: cd ../bin

  4. Compile the Java RMI stub. In your case, you could use something like:

    rmic -v1.2 -classpath .;"%JC_CLASSIC_HOME%/lib/api_classic.jar" sid.Contor
    

    The class must be specified without a trailing dash ("-") and using dots (".") instead of slashes ("/"). If the value of the environment variable JC_CLASSIC_HOME contains spaces, you need to surround the whole path of the api_classic.jar file with quotation marks.

Travertine answered 23/9, 2015 at 5:24 Comment(4)
I already tried api_classic.jar but I followed the documentation from Oracle and write tools.jar instead but none seems the work. PS : -sid/Contor is bad because rmic will expect '.' symbol and not '/' symbol because of the packages .Fariss
@Albertooooo See my updated answer (make sure that %JC_CLASSIC_HOME% either contains a trailing slash or that you add one between %JC_CLASSIC_HOME% and "lib"; specify the class name in Java notation). I just tested this and it compiles perfectly fine using JCDK 3.0.2 + JDK 7.Travertine
I do have a trailing slash on %JC_CLASSIC_HOME% but I tried both commands but I got the same error . I think that is something wrong with the -classpath value .However I don't understand the notation with ';' and probably that is the reason for my mistakesFariss
@Albertooooo So now we get closer to your problem. It seems that your JC_CLASSIC_HOME contains spaces. This will result in a wrong classpath and hence, rmic can't find the classes located in api_classic.jar.Travertine

© 2022 - 2024 — McMap. All rights reserved.