title: How to programmatically load a Java card applet ( .cap file ) using java or java Applet
body: <p>How to programmatically load a Java card applet ( .cap file ) using java or java Applet.</p>
  
  <pre><code>I'm trying to install an applet (.cap file) into a smart card. I read that can be done using APDU. I created my applet using Netbeans.
  </code></pre>
  
  <p>I have already created a .CAP file using Netbeans for my applet which I would now like to install/load into the physical smart card. I would appreciate assistance on how or what tool I could use to install the .CAP file to the card. Also, what else do I need to install into the card.
   And I have two devices  HID OMNIKEY CARDMAN  5x21  1 and HID OMNIKEY CARDMAN 3x21 0   java  smart  card reader and also I have two kinds of cards like java card (J2A.. or J3A..) and basics cards(ZC..)
  Note: I don’t want to use any third party software or tools
  And my applet code is:
  package smartCard;
  import javacard.framework.*;</p>
  
  <p>/**
   *
   * @author patidar
   */
  public class SmartCard extends Applet {</p>
  
  <pre><code>/**
   * Installs this applet.
   * 
   * @param bArray
   *            the array containing installation parameters
   * @param bOffset
   *            the starting offset in bArray
   * @param bLength
   *            the length in bytes of the parameter data in bArray
   */
  /**
   * Only this class's install method should create the applet object.
   */
  protected SmartCard() {
      register();
  }
  /**
   * Processes an incoming APDU.
   * 
   * @see APDU
   * @param apdu
   *            the incoming APDU
   */
  /* constants declaration */
  // code of CLA byte in the command APDU header
  final static byte Wallet_CLA =(byte)0x80;
  // codes of INS byte in the command APDU header
  final static byte VERIFY = (byte) 0x20;
  final static byte CREDIT = (byte) 0x30;
  final static byte DEBIT = (byte) 0x40;
  final static byte GET_BALANCE = (byte) 0x50;
  // maximum balance
  final static short MAX_BALANCE = 0x7FFF;
  // maximum transaction amount
  final static byte MAX_TRANSACTION_AMOUNT = 127;
  
  // maximum number of incorrect tries before the
  // PIN is blocked
  final static byte PIN_TRY_LIMIT =(byte)0x03;
  // maximum size PIN
  final static byte MAX_PIN_SIZE =(byte)0x08;
  
  // signal that the PIN verification failed
  final static short SW_VERIFICATION_FAILED =
  0x6300;
  // signal the the PIN validation is required
  // for a credit or a debit transaction
  final static short SW_PIN_VERIFICATION_REQUIRED =
                                          0x6301;
  // signal invalid transaction amount
  // amount &gt; MAX_TRANSACTION_AMOUNT or amount &lt; 0
  final static short SW_INVALID_TRANSACTION_AMOUNT = 0x6A83;
  
  // signal that the balance exceed the maximum
  final static short SW_EXCEED_MAXIMUM_BALANCE = 0x6A84;
  // signal the the balance becomes negative
  final static short SW_NEGATIVE_BALANCE = 0x6A85;
  
  /* instance variables declaration */
  OwnerPIN pin;
  short balance;
  private SmartCard (byte[] bArray,short bOffset,byte bLength) 
      // It is good programming practice to allocate
      // all the memory that an applet needs during
      // its lifetime inside the constructor
      pin = new OwnerPIN(PIN_TRY_LIMIT,   MAX_PIN_SIZE);
  
      byte iLen = bArray[bOffset]; // aid length
      bOffset = (short) (bOffset+iLen+1);
      byte cLen = bArray[bOffset]; // info length
      bOffset = (short) (bOffset+cLen+1);
      byte aLen = bArray[bOffset]; // applet data length
  
      // The installation parameters contain the PIN
      // initialization value
      pin.update(bArray, (short)(bOffset+1), aLen);
      register();
  
  } // end of the constructor
  
  public static void install(byte[] bArray, short bOffset, byte bLength) {
      // create a Wallet applet instance
      new SmartCard(bArray, bOffset, bLength);
  } // end of install method
  
  public boolean select() {
  
      // The applet declines to be selected
      // if the pin is blocked.
      if ( pin.getTriesRemaining() == 0 )
         return false;
  
      return true;
  
  }// end of select method
  
  public void deselect() {
  
      // reset the pin value
      pin.reset();
  
  }
  
  public void process(APDU apdu) {
  
      // APDU object carries a byte array (buffer) to
      // transfer incoming and outgoing APDU header
      // and data bytes between card and CAD
  
      // At this point, only the first header bytes
      // [CLA, INS, P1, P2, P3] are available in
      // the APDU buffer.
      // The interface javacard.framework.ISO7816
      // declares constants to denote the offset of
      // these bytes in the APDU buffer
  
      byte[] buffer = apdu.getBuffer();
      // check SELECT APDU command
  
      if (apdu.isISOInterindustryCLA()) {
          if (buffer[ISO7816.OFFSET_INS] == (byte)(0xA4)) {
              return;
          } else {
              ISOException.throwIt (ISO7816.SW_CLA_NOT_SUPPORTED);
          }
      }
  
      // verify the reset of commands have the
      // correct CLA byte, which specifies the
      // command structure
      if (buffer[ISO7816.OFFSET_CLA] != Wallet_CLA)
          ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
  
      switch (buffer[ISO7816.OFFSET_INS]) {
      case GET_BALANCE:
          getBalance(apdu);
          return;
      case DEBIT:
          debit(apdu);
          return;
      case CREDIT:
          credit(apdu);
          return;
      case VERIFY:
          verify(apdu);
          return;
      default:
          ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
      }
  
  }   // end of process method
  
  private void credit(APDU apdu) {
  
      // access authentication
      if ( ! pin.isValidated() )
          ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  
      byte[] buffer = apdu.getBuffer();
  
      // Lc byte denotes the number of bytes in the
      // data field of the command APDU
      byte numBytes = buffer[ISO7816.OFFSET_LC];
  
      // indicate that this APDU has incoming data
      // and receive data starting from the offset
      // ISO7816.OFFSET_CDATA following the 5 header
      // bytes.
      byte byteRead =
          (byte)(apdu.setIncomingAndReceive());
  
      // it is an error if the number of data bytes
      // read does not match the number in Lc byte
      if ( ( numBytes != 1 ) || (byteRead != 1) )
          ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  
      // get the credit amount
      byte creditAmount = buffer[ISO7816.OFFSET_CDATA];
  
      // check the credit amount
      if ( ( creditAmount &gt; MAX_TRANSACTION_AMOUNT)
           || ( creditAmount &lt; 0 ) )
          ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  
      // check the new balance
      if ( (short)( balance + creditAmount)  &gt; MAX_BALANCE )
         ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
  
      // credit the amount
      balance = (short)(balance + creditAmount);
  
  } // end of deposit method
  
  private void debit(APDU apdu) {
  
      // access authentication
      if ( ! pin.isValidated() )
          ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
  
      byte[] buffer = apdu.getBuffer();
  
      byte numBytes =
          (byte)(buffer[ISO7816.OFFSET_LC]);
  
      byte byteRead =
          (byte)(apdu.setIncomingAndReceive());
  
      if ( ( numBytes != 1 ) || (byteRead != 1) )
         ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  
      // get debit amount
      byte debitAmount = buffer[ISO7816.OFFSET_CDATA];
  
      // check debit amount
      if ( ( debitAmount &gt; MAX_TRANSACTION_AMOUNT)
           ||  ( debitAmount &lt; 0 ) )
         ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
  
      // check the new balance
      if ( (short)( balance - debitAmount ) &lt; (short)0 )
           ISOException.throwIt(SW_NEGATIVE_BALANCE);
  
      balance = (short) (balance - debitAmount);
  
  } // end of debit method
  
  private void getBalance(APDU apdu) {
  
      byte[] buffer = apdu.getBuffer();
  
      // inform system that the applet has finished
      // processing the command and the system should
      // now prepare to construct a response APDU
      // which contains data field
      short le = apdu.setOutgoing();
  
      if ( le &lt; 2 )
         ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  
      //informs the CAD the actual number of bytes
      //returned
      apdu.setOutgoingLength((byte)2);
  
      // move the balance data into the APDU buffer
      // starting at the offset 0
      buffer[0] = (byte)(balance &gt;&gt; 8);
      buffer[1] = (byte)(balance &amp; 0xFF);
  
      // send the 2-byte balance at the offset
      // 0 in the apdu buffer
      apdu.sendBytes((short)0, (short)2);
  
  } // end of getBalance method
  
  private void verify(APDU apdu) {
  
      byte[] buffer = apdu.getBuffer();
      // retrieve the PIN data for validation.
      byte byteRead = (byte)(apdu.setIncomingAndReceive());
  
      // check pin
      // the PIN data is read into the APDU buffer
      // at the offset ISO7816.OFFSET_CDATA
      // the PIN data length = byteRead
      if ( pin.check(buffer, ISO7816.OFFSET_CDATA,
          byteRead) == false )
          ISOException.throwIt(SW_VERIFICATION_FAILED);
  
  } // end of validate method
  </code></pre>
  
  <p>} // end of class SmartCard</p>
  
  <p>With this information can anyone help me to build the correct APDU to install my cap file into a real smart card?
  Thank you.</p>