Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java: Erroria pukkaa

Sivun loppuun

Juice [24.07.2004 23:04:29]

#


Exception in thread "main" java.lang.NoClassDefFoundError: CreateLogo

Tällaista, ohjelma on Paul Brownin CreateLogo (Mikrobitti 1/04). Tämä tulee, kun siirtyy hakemistoon, missä CreateLogo.class on ja näpyttelee java CreateLogo.
Ohjelman lähdekoodi on alla:

/*
 * @(#)CreateLogo.java	1.1
 *
 * The idea of this code is to take as parameters:
 * 1)Input File = file where a "logo" has been saved in portable bitmap (PBM) format,
 * 2)Operator of the user -- currently supported are: 2G,Finnet,Radiolinja,Sonera,Telia,Alands
 *   and Blank.  (You can use basically any .pbm with blank operator to remove your logo
 *   from your phone, or use the blank.pbm which comes with this package.)
 * 3)Phone# the logo is to be sent to,
 *
 * and will create a set of AT commands to be copied to hyperterminal or some similar session
 * so that the bytes that represent the logo will be sent to that number in the proper fashion.
 *
 * Name of the output file = Inputfilename.txt
 *
 * Layout of the program is:
 * A)Read inputs: bitmap file, operator, phone number
 * B)Convert the bitmap contents to hex
 * C)Determine how many messages are needed to transmit the logo
 * D)Build that many messages with proper headers and write them to the output file
 *
 *
 *
 * Written by: Paul Brown, 2003-11-29 --> 2003-12-12,
 * in Lammi, Tampere, and Lempäälä, Finland
 *
 * Please feel free to edit this as you see fit, but give me some credit if you become
 * rich and famous because of this code, will ya?  (That'll happen.)
 *
 *
 */

import java.io.*;
import java.lang.*;

public class CreateLogo {

  final public String[][] OPERATOR_GRID={
	                              {"Alands","244","14"},
                                  {"Finnet","244","09"},
                                  {"Radiolinja","244","05"},
                                  {"Sonera","244","91"},
                                  {"2G","244","12"},
                                  {"Telia","244","03"},
                                  {"Blank","000","00"},
	                             };
  final public int OP=0,MCC=1,MNC=2; //MCC=MobileCountryCode, MNC=MobileNetworkCode

  final public int SINGLE_MSG_PAYLOAD = 133; //140bytes - 7bytes user data header
  final public int MULTI_MSG_PAYLOAD = 128; //140bytes - 12bytes user data header

  //SMS is TPDU head + UserData
  //       TPDU head is startTPDU + phonenumber + endTPDU + datalength
  //                   UserData is either:
  //                            SHORT_UDH + PORT_ADDRESS + data
  //                             OR
  //                            LONG_UDH + PORT_ADDRESS + CONCAT_START + concatEnd + data
  final public String START_TPDU_HEAD="005100";
  final public String END_TPDU_HEAD="00F5A7";
  final public String SHORT_UDH="06";
  final public String LONG_UDH="0B";
  final public String PORT_ADDRESS = "05"+"04"+"1582"+"0000"; //05=port, 04=length, 1582=dest.port, 0000=src. port
  final public String CONCAT_START = "00"+"03" +"99"; //00=concat, 03=length, 99 is arbitrary number


  //Globals
  public String realWidth="";
  public String realHeight="";
  public String realInputString="";
  public String wholeLogoInHex="";
  public int msgNum=0;
  public boolean optsPossible=false;


  public CreateLogo(String inputfile, String operatorFromUser, String phone) {
    PrintWriter out = null;
    FileWriter f = null;

    File infile = new File(inputfile);
    if(!infile.exists()) {
      System.out.println("The input file you gave does not exist: "+inputfile);
      System.exit(0);
    }
    String tmp_filename = infile.getName();
    String path = infile.getPath();
    String outputfile=path.substring(0,path.indexOf(tmp_filename))+ //path, if there is one...
                      tmp_filename.substring(0,tmp_filename.indexOf("."))+ //root of the filename...
	                  ".txt";
    File outfile = new File(outputfile);
    if(outfile.exists()) {
	  System.out.println("Output file \""+outputfile+"\" already exists, and will be OVERWRITTEN!!!!");
	  System.out.print("Are you sure? (y/n):");


      BufferedReader inp=new BufferedReader(new InputStreamReader(System.in));
      String input="";
      try{
        while(true) {
          input=inp.readLine();
          if (input.trim().equalsIgnoreCase("y")) {
            System.out.println("File will be overwritten");
            break;
          }
          else if(input.trim().equalsIgnoreCase("n")) {
            System.out.println("Execution stopped");
            System.exit(0);
          }
          System.out.print("Please Enter Y/N or y/n   :");
        }//end of while true
      }catch(IOException e) {}

	}

    try {
      f = new FileWriter(outputfile);
      out = new PrintWriter(f);
    } catch(Exception e) {}


//##########  A  ############
    //Read bitmap file into realInputString variable
    try {
      BufferedReader in = new BufferedReader(new FileReader(inputfile));
      int c;
      String str;
      str=in.readLine();//This first line should contain "garbage" for our purposes, so we can move on...
      str=in.readLine();//get the next line...
      while(str.charAt(0)=='#') //This is a comment line, get the next...
        str=in.readLine();

      //When we exit the while loop, str now has the line with the width and length!!!

      int k=str.indexOf(" ");
      realWidth=str.substring(0,k);
      realHeight=str.substring(k+1);

      while ((c = in.read()) != -1) {
        realInputString+=(char)c;
      }
      in.close();
    } catch (IOException e) {
    }

    //Read Width
    String width=getHex2(Integer.parseInt(realWidth));

    //Read Height
    String height=getHex2(Integer.parseInt(realHeight));
    int w=Integer.parseInt(realWidth),h=Integer.parseInt(realHeight);
    if((w*h)%8 != 0) {
      System.out.println("The bitmap must contain a number of bits divisible by 8, so that proper bytes may be formed.");
      return;
	}

//Testing
//System.out.println("Read in:"+realInputString);
//System.out.println("Width is: "+width);
//System.out.println("Height is: "+height);


    //Get phone number
    String tmp=switchBytes(phone.substring(1));
    phone=getHex2(phone.length()-1)+"91"+tmp; //length of number in digits is 1 less, 'cuz we take off the '+', 91 = intl mode

//Testing
//System.out.println("Phone # is: " + phone);


    //Get operator mcc and mnc
    boolean matchedOperator=false;
    int opIndx = 0;
    String mcc="";
    String mnc="";

    while(!matchedOperator && opIndx<OPERATOR_GRID.length) {
	  if(OPERATOR_GRID[opIndx][OP].compareToIgnoreCase(operatorFromUser)==0) {
	    matchedOperator=true;
	    mcc=OPERATOR_GRID[opIndx][MCC];
	    mnc=OPERATOR_GRID[opIndx][MNC];
	  }
	  opIndx++;
	}
	if(!matchedOperator) {
	  System.out.println("WARNING! Operator NOT FOUND!  mcc and mnc will be set to 123 and 45");
	  mcc="123";
	  mnc="45";
    }
    mcc=switchBytes(mcc);
    mnc=switchBytes(mnc);

//Testing
//System.out.println("mcc is: " + mcc);
//System.out.println("mnc is: " + mnc);
//##########  end of A  ############


//##########  B  ############
    int j=0;
    while(j<realInputString.length()-3) {//There are still 4 items in the array left
      int numbits=0;
      String outbits="";
        do {
          if(realInputString.charAt(j)=='0' || realInputString.charAt(j)=='1') {
	        outbits = outbits+realInputString.charAt(j);
	        numbits++;
          }
		  j++;
		}while(numbits<4);
        wholeLogoInHex+=bin2hex(outbits);
    }
//Testing
//System.out.println("wholeLogoInHex= "+wholeLogoInHex);
//##########  end of B  ############


//##########  C  ############

    howManyMessages(wholeLogoInHex.length()/2);

    //Add the OTA bmp header (infofield, width, height, depth)
    wholeLogoInHex="00"+width+height+"01"+wholeLogoInHex;

    //Add the mcc+mnc, with optional leading "0" and trailing linefeed IF POSSIBLE
    if(optsPossible)
      wholeLogoInHex="30"+mcc+mnc+"0A"+wholeLogoInHex;
    else
      wholeLogoInHex=mcc+mnc+wholeLogoInHex;

//Testing
/*
for(int i=0;i<1000;i++) {
  howManyMessages(i);
  if(!optsPossible)
    System.out.println("With Bitmap length "+i+", total BMPlen sans opts is "+(i+7)+", and after filling "+
                        msgNum+" messages, there is no room for the optional 2 bytes.");
}
*/
//##########  end of C  ############


//##########  D  ############
//Build proper amount of messages -- do it properly!
//This section was the trickiest -- there were several times I got mixed up with whether I should have been
//counting bytes or characters....

//TPDU Header (with leading 00 to indicate no SMSC specified)
    String msgOut="";


    String TPDUHeader=START_TPDU_HEAD+phone+END_TPDU_HEAD; //Still need to add data length!!!

    String UDHeader="";
    int dataLen=0; //EXPRESSED IN BYTES!
    int UDHlen=0;

    if(msgNum==1) {
	  UDHeader=SHORT_UDH+PORT_ADDRESS;
      dataLen=(UDHeader.length()+wholeLogoInHex.length())/2;
	  TPDUHeader+=getHex2(dataLen); //add data length
	  msgOut=TPDUHeader+UDHeader+wholeLogoInHex;
      printMsg(msgOut,out);
	}
	else {
	  UDHeader=LONG_UDH+PORT_ADDRESS+CONCAT_START+getHex2(msgNum)+"01"; //01 because this is #1 of series
	  UDHlen = UDHeader.length();

      dataLen=(UDHlen+(MULTI_MSG_PAYLOAD*2))/2;
	  msgOut=TPDUHeader+getHex2(dataLen)+UDHeader+wholeLogoInHex.substring(0,(MULTI_MSG_PAYLOAD*2));
      printMsg(msgOut,out);

      //remove the first part of the message...
	  wholeLogoInHex=wholeLogoInHex.substring(MULTI_MSG_PAYLOAD*2);

	  for(int i=1;i<msgNum;i++) {
	    UDHeader=LONG_UDH+PORT_ADDRESS+CONCAT_START+getHex2(msgNum)+getHex2(i+1);

	    //if this is the last part of the multimessage, there won't *necessarily* be enough to fill a
	    //whole MULTI_MSG_PAYLOAD, but if it's not, then there should be...
        //msgOut=TPDUHeader+UDHeader;

	    if(wholeLogoInHex.length()<=(MULTI_MSG_PAYLOAD*2)) { //fits in
          dataLen=(UDHlen+wholeLogoInHex.length())/2;
          msgOut=TPDUHeader+getHex2(dataLen)+UDHeader+wholeLogoInHex;
		}
	    else {
          dataLen=(UDHlen+(MULTI_MSG_PAYLOAD*2))/2;
		  msgOut=TPDUHeader+getHex2(dataLen)+UDHeader+wholeLogoInHex.substring(0,(MULTI_MSG_PAYLOAD*2));
	      wholeLogoInHex=wholeLogoInHex.substring(MULTI_MSG_PAYLOAD*2);
		}

        printMsg(msgOut,out);

	  }
    }
    //Testing
//##########  end of D  ############


      System.out.println("\n\nThe AT commands for sending your logo have been printed to:\n"+outputfile);

      //Close the file
      try {
        f.close();
	  } catch(Exception e) {}

  }

  private void createRegion(char id, int left, int top, int width, int height, PrintWriter out) {
    out.println("      <region id=\""+id+"\" left=\""+left+"\" top=\""+top+"\" width=\""+width+"\" height=\""+height+"\" />");
  }

  private String switchBytes(String s) {
    String out="";
    char tmp=' ';
    int i=0;
    while(i<s.length()) {
	  tmp=s.charAt(i);
	  if(i+1<s.length())
	    out=out+s.charAt(i+1)+tmp;
	  else
	    out=out+"F"+tmp;
	  i+=2;
	}
    return out;
  }


  private void howManyMessages(int bitmapLength /*IN BYTES!!!*/) { //,int msgNum, boolean optsPossible) {
	optsPossible=false;
	int bitmapHeaderMandLength = 7; //Mandatory bytes for bitmapheader -- there are two bytes which *may*
	                                //be left out at least for most Nokia phones - not sure if this
	                                //ALSO applies to multi-message bitmaps - should work at least for
	                                //single-message ones.
    int bitmapHeaderOptsLength = 2;

	int newBitmapSize = bitmapLength + bitmapHeaderMandLength;
	if(newBitmapSize <= SINGLE_MSG_PAYLOAD) {
	  msgNum=1;
	  if(newBitmapSize <= SINGLE_MSG_PAYLOAD-bitmapHeaderOptsLength)
	    optsPossible=true;
	}
	else {
	  msgNum=(int)Math.ceil((double)newBitmapSize/(double)MULTI_MSG_PAYLOAD);
	  int r = newBitmapSize%MULTI_MSG_PAYLOAD;
	  if(r!=0 && MULTI_MSG_PAYLOAD-r >= bitmapHeaderOptsLength)
	  //if(MULTI_MSG_PAYLOAD-(newBitmapSize%MULTI_MSG_PAYLOAD) >= bitmapHeaderOptsLength)
	    optsPossible=true;
    }
  }

  private String getHex(int i) {
    return Integer.toHexString(i).toUpperCase();
  }

  private String getHex2(int i) {
    String s = Integer.toHexString(i).toUpperCase();
    if(s.length()<2)
      return "0"+s;
    else
      return s;
  }

  private String bin2hex(String s) {
    //Takes String of 4 binary digits and returns a character for its hex representation
    int sum = 0;
    for(int i=0;i<4;i++) {
	  if(s.charAt(i)=='1')
	    //bits are in reverse order, so 1st bit should be 2^3, 2nd 2^2, etc... (that's why have 3-i)
	    sum = sum + (int)Math.pow(2,(3-i));
	}
    return getHex(sum);
  }

  private void printMsg(String s, PrintWriter out) {
	int i = ((s.length())/2)-1;

    out.println("at+cmgs="+i);
  	out.println(s+"\n");

//    System.out.println("at+cmgs="+i);
//    System.out.println(s+"\n");

  }

  public static void main (String[] args) {
	if(args.length<3){
	  System.out.println("Usage:java CreateLogo <pbm file> <operator> <phone number in intl format>");
	  System.out.println("\n<pbm file> = just filename if in current directory, otherwise include path");
	  System.out.println("<operator> values: Alands,Finnet,Radiolinja,Sonera,2G,Telia,Blank");
	  System.out.println("<phone number in intl format> is e.g. +358401234567");
	  System.out.println("\n\nExample: Send \"mikrobitti.pbm\" to Sonera number 0401234567:");
	  System.out.println("    java CreateLogo mikrobitti.pbm sonera +358401234567");
	  System.out.println("\n\nExample2: Clear logo for Radiolinja number 0501234567:");
	  System.out.println("    java CreateLogo blank.pbm blank +358501234567\n");
    }
    else {
      CreateLogo oa = new CreateLogo(args[0], args[1], args[2]);
    }
  }

}

En sitten tiedä, että onko tuo koodi tismalleen sama kuin .class-tiedostossa (tuo on paketin mukana tullut .java-filu, en ole itte kääntänyt). Mistähän tällainen errori johtuu? En itse harrasta Javaa, ja koneellani on Javat Runtime Environment 2 Standard Mode v.1.3.1_12-b03.

tsuriga [25.07.2004 01:32:17]

#

Hyvin kääntyy SDK:lla ja ajautuu myös, virhe on ehkä pathissa tai classpathissa. Otteita omasta autoexec.batista:

path C:\WINDOWS;C:\WINDOWS\COMMAND;D:\j2sdk1.4.2_04\BIN
set CLASSPATH=D:\Java

renni [25.07.2004 02:15:45]

#

Eieiei! Javan hakemistoa EI laiteta classpathiin. Siihen laitetaan se hakemisto missä class-tiedostojen juuri sijaitsee. Yksinkertaisia juttuja tehdessä paras vaihtoehto on yleensä pelkkä piste joka tarkoittaa sitä hakemistoa missä kulloinkin ollaan. Siis:

set CLASSPATH=.

Tässä vielä hyvä linkki missä voi opetella virheilmoitusten tulkintaa:
http://www.mindprod.com/jgloss/errormessages.html

tsuriga [25.07.2004 02:50:39]

#

Read error? Java ei sijaitse minulla D:\Java kansiossa kuten pathista näkyy. Kiitos kuitenkin selvennyksestä ja vinkistä.

renni [25.07.2004 13:55:43]

#

Niin, et selvästikään lukenut mitä kirjoitin. :) Ei ole mitään väliä sillä missä Javasi sijaitsee, sitä hakemistoa kun EI laiteta classpathiin. Eikä tuo virheilmoituskaan liity Javasi sijaintiin mitenkään.

tsuriga [25.07.2004 14:37:30]

#

Mikäs tuo "Eieiei!" on? Eihän path ole sama kuin classpath, joten en neuvonutkaan laittamaan Javan hakemistoa classpathiin? Asentaessa en saanut ensimmäisillä asetuksilla toimimaan ja kun noilla toimi niin minulle riitti se :).

Juice [25.07.2004 18:25:13]

#

Kiitos!

renni [26.07.2004 16:53:36]

#

tsuriga kirjoitti:

Mikäs tuo "Eieiei!" on? Eihän path ole sama kuin classpath, joten en neuvonutkaan laittamaan Javan hakemistoa classpathiin?

tsuriga kirjoitti:

set CLASSPATH=D:\Java

Jaa, mitähän tuo rivi sitten tarkoittaa?-) PATH:in asettaminen ei liittynyt ongelmaan millään lailla joten sekin aika turhaa.

tsuriga [26.07.2004 17:41:47]

#

Oletan, että Javan hakemistolla tarkoitat hakemistoa, jonne Java on asennettu. D:\Java minulla on kaikki Javaan liittyvät koodit ja paketit ja sälä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta