为什么在这种情况下会引发ClassLoader异常?

时间:2011-11-18 07:09:33

标签: java noclassdeffounderror

我成功编译了三个文件,当我尝试启动一个包含public static void main的类时,我遇到了错误。这是错误:

C:\Documents and Settings\Ambre-28\Mes documents\JavaMESDKProjects\exempleRXTX\src\net\net>java Example
Exception in thread "main" java.lang.NoClassDefFoundError: Example (wrong name:
net/Example)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(Unknown Source)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$000(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: Example.  Program will exit.

以下是代码:

package net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;

/**
 * This is a very simple example showing the most basic use of
 * {@link net.Network} and {@link net.Network_iface}. Feel free to use,
 * overwrite, or just ignore code as you like.
 * 
 * As a default, a connection speed of 115200 baud is assumed. You can use a
 * different speed by giving it as an <b>int</b> as the first command line
 * argument or changing the default speed in the source code.
 * 
 * @author Raphael Blatter (raphael@blatter.sg)
 */
public class Example implements net.Network_iface {

    // set the speed of the serial port
    public static int speed = 115200;
    private static net.Network network;

    private static boolean resend_active = false;

    public static void main(String[] args) {
        network = new net.Network(0, new net.Example(), 255);

        // reading the speed if
        if (args.length > 0) {
            try {
                speed = Integer.parseInt(args[0]);
            } catch (NumberFormatException e) {
                System.out.println("the speed must be an integer\n");
                System.exit(1);
            }
        }

        // initializing reader from command line
        int i, inp_num = 0;
        String input;
        BufferedReader in_stream = new BufferedReader(new InputStreamReader(
                System.in));

        // getting a list of the available serial ports
        Vector<String> ports = network.getPortList();

        // choosing the port to connect to
        System.out.println();
        if (ports.size() > 0) {
            System.out.println("the following serial ports have been detected:");
        } 
        else {
            System.out.println("sorry, no serial ports were found on your computer\n");
            System.exit(0);
        }
        for (i = 0; i < ports.size(); ++i) {
            System.out.println("    " + Integer.toString(i + 1) + ":  " + ports.elementAt(i));
        }
        boolean valid_answer = false;
        while (!valid_answer) {
            System.out.println("enter the id (1,2,...) of the connection to connect to: ");
            try {
                input = in_stream.readLine();
                inp_num = Integer.parseInt(input);
                if ((inp_num < 1) || (inp_num >= ports.size() + 1))
                    System.out.println("your input is not valid");
                else
                    valid_answer = true;
            } catch (NumberFormatException ex) {
                System.out.println("please enter a correct number");
            } catch (IOException e) {
                System.out.println("there was an input error\n");
                System.exit(1);
            }
        }

        // connecting to the selected port
        if (network.connect(ports.elementAt(inp_num - 1), speed)) {
            System.out.println();
        } else {
            System.out.println("sorry, there was an error connecting\n");
            System.exit(1);
        }

        // asking whether user wants to mirror traffic
        System.out.println("do you want this tool to send back all the received messages?");
        valid_answer = false;
        while (!valid_answer) {
            System.out.println("'y' for yes or 'n' for no: ");
            try {
                input = in_stream.readLine();
                if (input.equals("y")) {
                    resend_active = true;
                    valid_answer = true;
                } else if (input.equals("n")) {
                    valid_answer = true;
                } else if (input.equals("q")) {
                    System.out.println("example terminated\n");
                    System.exit(0);
                }
            } catch (IOException e) {
                System.out.println("there was an input error\n");
                System.exit(1);
            }
        }

        // reading in numbers (bytes) to be sent over the serial port
        System.out.println("type 'q' to end the example");
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
            }
            System.out.println("\nenter a number between 0 and 254 to be sent ('q' to exit): ");
            try {
                input = in_stream.readLine();
                if (input.equals("q")) {
                    System.out.println("example terminated\n");
                    network.disconnect();
                    System.exit(0);
                }
                inp_num = Integer.parseInt(input);
                if ((inp_num > 255) || (inp_num < 0)) {
                    System.out.println("the number you entered is not valid");
                } else {
                    int temp[] = { inp_num };
                    network.writeSerial(1, temp);   // ecriture dans le port série
                    System.out.println("sent " + inp_num + " over the serial port");
                }
            } catch (NumberFormatException ex) {
                System.out.println("please enter a correct number");
            } catch (IOException e) {
                System.out.println("there was an input error");
            }
        }
    }

    /**
     * Implementing {@link net.Network_iface#networkDisconnected(int)}, which is
     * called when the connection has been closed. In this example, the program
     * is ended.
     * 
     * @see net.Network_iface
     */
    public void networkDisconnected(int id) {
        System.exit(0);
    }

    /**
     * Implementing {@link net.Network_iface#parseInput(int, int, int[])} to
     * handle messages received over the serial port. In this example, the
     * received bytes are written to command line (0 to 254) and the message is
     * sent back over the same serial port.
     * 
     * @see net.Network_iface
     */
    public void parseInput(int id, int numBytes, int[] message) {
        if (resend_active) {
            network.writeSerial(numBytes, message);
            System.out.print("received and sent back the following message: ");
        } else {
            System.out.print("received the following message: ");
        }
        System.out.print(message[0]);
        for (int i = 1; i < numBytes; ++i) {
            System.out.print(", ");
            System.out.print(message[i]);
        }
        System.out.println();
    }

    /**
     * Implementing {@link net.Network_iface#writeLog(int, String)}, which is
     * used to write information concerning the connection. In this example, all
     * the information is simply written out to command line.
     * 
     * @see net.Network_iface
     */
    public void writeLog(int id, String text) {
        System.out.println("   log:  |" + text + "|");
    }

}

package net;

import gnu.io.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Vector;

/**
 * Used to simplify communication over a Serial port. Using the RXTX-library
 * (rxtx.qbang.org), one connection per instance of this class can be handled.
 * In addition to handling a connection, information about the available Serial
 * ports can be received using this class.
 * 
 * A separate {@link Thread} is started to handle messages that are being
 * received over the Serial interface.
 * 
 * This class also makes packages out of a stream of bytes received, using a
 * {@link #divider}, and sending these packages as an array of <b>int</b>s (each
 * between 0 and 255) to a function implemented by a class implementing the
 * {@link net.Network_iface}-interface.
 * 
 * @author Raphael Blatter (raphael@blatter.sg)
 * @author heavily using code examples from the RXTX-website (rxtx.qbang.org)
 */
public class Network {
    private InputStream inputStream;
    private OutputStream outputStream;
    /**
     * The status of the connection.
     */
    private boolean connected = false;
    /**
     * The Thread used to receive the data from the Serial interface.
     */
    private Thread reader;
    private SerialPort serialPort;
    /**
     * Communicating between threads, showing the {@link #reader} when the
     * connection has been closed, so it can {@link Thread#join()}.
     */
    private boolean end = false;

    /**
     * Link to the instance of the class implementing {@link net.Network_iface}.
     */
    private Network_iface contact;
    /**
     * A small <b>int</b> representing the number to be used to distinguish
     * between two consecutive packages. It can only take a value between 0 and
     * 255. Note that data is only sent to
     * {@link net.Network_iface#parseInput(int, int, int[])} once the following
     * 'divider' could be identified.
     * 
     * As a default, <b>255</b> is used as a divider (unless specified otherwise
     * in the constructor).
     * 
     * @see net.Network#Network(int, Network_iface, int)
     */
    private int divider;
    /**
     * <b>int</b> identifying the specific instance of the Network-class. While
     * having only a single instance, 'id' is irrelevant. However, having more
     * than one open connection (using more than one instance of {@link Network}
     * ), 'id' helps identifying which Serial connection a message or a log
     * entry came from.
     */
    private int id;

    private int[] tempBytes;
    int numTempBytes = 0, numTotBytes = 0;

    /**
     * @param id
     *            <b>int</b> identifying the specific instance of the
     *            Network-class. While having only a single instance,
     *            {@link #id} is irrelevant. However, having more than one open
     *            connection (using more than one instance of Network),
     *            {@link #id} helps identifying which Serial connection a
     *            message or a log entry came from.
     * 
     * @param contact
     *            Link to the instance of the class implementing
     *            {@link net.Network_iface}.
     * 
     * @param divider
     *            A small <b>int</b> representing the number to be used to
     *            distinguish between two consecutive packages. It can take a
     *            value between 0 and 255. Note that data is only sent to
     *            {@link net.Network_iface#parseInput(int, int, int[])} once the
     *            following {@link #divider} could be identified.
     */
    public Network(int id, Network_iface contact, int divider) {
        this.contact = contact;
        this.divider = divider;
        if (this.divider > 255)
            this.divider = 255;
        if (this.divider < 0)
            this.divider = 0;
        this.id = id;
        tempBytes = new int[1024];
    }

    /**
     * Just as {@link #Network(int, Network_iface, int)}, but with a default
     * {@link #divider} of <b>255</b>.
     * 
     * @see #Network(int, Network_iface, int)
     */
    public Network(int id, Network_iface contact) {
        this(id, contact, 255);
    }

    /**
     * Just as {@link #Network(int, Network_iface, int)}, but with a default
     * {@link #divider} of <b>255</b> and a default {@link #id} of 0. This
     * constructor may mainly be used if only one Serial connection is needed at
     * any time.
     * 
     * @see #Network(int, Network_iface, int)
     */
    public Network(Network_iface contact) {
        this(0, contact);
    }

    /**
     * This method is used to get a list of all the available Serial ports
     * (note: only Serial ports are considered). Any one of the elements
     * contained in the returned {@link Vector} can be used as a parameter in
     * {@link #connect(String)} or {@link #connect(String, int)} to open a
     * Serial connection.
     * 
     * @return A {@link Vector} containing {@link String}s showing all available
     *         Serial ports.
     */
    @SuppressWarnings("unchecked")
    public Vector<String> getPortList() {
        Enumeration<CommPortIdentifier> portList;
        Vector<String> portVect = new Vector<String>();
        portList = CommPortIdentifier.getPortIdentifiers();

        CommPortIdentifier portId;
        while (portList.hasMoreElements()) {
            portId = (CommPortIdentifier) portList.nextElement();
            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                portVect.add(portId.getName());
            }
        }
        contact.writeLog(id, "found the following ports:");
        for (int i = 0; i < portVect.size(); i++) {
            contact.writeLog(id, ("   " + (String) portVect.elementAt(i)));
        }

        return portVect;
    }

    /**
     * Just as {@link #connect(String, int)}, but using 115200 bps as a default
     * speed of the connection.
     * 
     * @param portName
     *            The name of the port the connection should be opened to (see
     *            {@link #getPortList()}).
     * @return <b>true</b> if the connection has been opened successfully,
     *         <b>false</b> otherwise.
     * @see #connect(String, int)
     */
    public boolean connect(String portName) {
        return connect(portName, 115200);
    }

    /**
     * Opening a connection to the specified Serial port, using the specified
     * speed. After opening the port, messages can be sent using
     * {@link #writeSerial(String)} and received data will be packed into
     * packets (see {@link #divider}) and forwarded using
     * {@link net.Network_iface#parseInput(int, int, int[])}.
     * 
     * @param portName
     *            The name of the port the connection should be opened to (see
     *            {@link #getPortList()}).
     * @param speed
     *            The desired speed of the connection in bps.
     * @return <b>true</b> if the connection has been opened successfully,
     *         <b>false</b> otherwise.
     */
    public boolean connect(String portName, int speed) {
        CommPortIdentifier portIdentifier;
        boolean conn = false;
        try {
            portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
            if (portIdentifier.isCurrentlyOwned()) {
                contact.writeLog(id, "Error: Port is currently in use");
            } else {
                serialPort = (SerialPort) portIdentifier.open("RTBug_network",
                        2000);
                serialPort.setSerialPortParams(speed, SerialPort.DATABITS_8,
                        SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

                inputStream = serialPort.getInputStream();
                outputStream = serialPort.getOutputStream();

                reader = (new Thread(new SerialReader(inputStream)));
                end = false;
                reader.start();
                connected = true;
                contact.writeLog(id, "connection on " + portName
                        + " established");
                conn = true;
            }
        } catch (NoSuchPortException e) {
            contact.writeLog(id, "the connection could not be made");
            e.printStackTrace();
        } catch (PortInUseException e) {
            contact.writeLog(id, "the connection could not be made");
            e.printStackTrace();
        } catch (UnsupportedCommOperationException e) {
            contact.writeLog(id, "the connection could not be made");
            e.printStackTrace();
        } catch (IOException e) {
            contact.writeLog(id, "the connection could not be made");
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * A separate class to use as the {@link net.Network#reader}. It is run as a
     * separate {@link Thread} and manages the incoming data, packaging them
     * using {@link net.Network#divider} into arrays of <b>int</b>s and
     * forwarding them using
     * {@link net.Network_iface#parseInput(int, int, int[])}.
     * 
     */
    private class SerialReader implements Runnable {
        InputStream in;

        public SerialReader(InputStream in) {
            this.in = in;
        }

        public void run() {
            byte[] buffer = new byte[1024];
            int len = -1, i, temp;
            try {
                while (!end) {
                    if ((in.available()) > 0) {
                        if ((len = this.in.read(buffer)) > -1) {
                            for (i = 0; i < len; i++) {
                                temp = buffer[i];
                                 // adjust from C-Byte to Java-Byte
                                if (temp < 0)
                                    temp += 256;
                                if (temp == divider) {
                                    if  (numTempBytes > 0) {
                                        contact.parseInput(id, numTempBytes,
                                                tempBytes);
                                    }
                                    numTempBytes = 0;
                                } else {
                                    tempBytes[numTempBytes] = temp;
                                    ++numTempBytes;
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                end = true;
                try {
                    outputStream.close();
                    inputStream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                serialPort.close();
                connected = false;
                contact.networkDisconnected(id);
                contact.writeLog(id, "connection has been interrupted");
            }
        }
    }

    /**
     * Simple function closing the connection held by this instance of
     * {@link net.Network}. It also ends the Thread {@link net.Network#reader}.
     * 
     * @return <b>true</b> if the connection could be closed, <b>false</b>
     *         otherwise.
     */
    public boolean disconnect() {
        boolean disconn = true;
        end = true;
        try {
            reader.join();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
            disconn = false;
        }
        try {
            outputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            disconn = false;
        }
        serialPort.close();
        connected = false;
        contact.networkDisconnected(id);
        contact.writeLog(id, "connection disconnected");
        return disconn;
    }

    /**
     * @return Whether this instance of {@link net.Network} has currently an
     *         open connection of not.
     */
    public boolean isConnected() {
        return connected;
    }

    /**
     * This method is included as a legacy. Depending on the other side of the
     * Serial port, it might be easier to send using a String. Note: this method
     * does not add the {@link #divider} to the end.
     * 
     * If a connection is open, a {@link String} can be sent over the Serial
     * port using this function. If no connection is available, <b>false</b> is
     * returned and a message is sent using
     * {@link net.Network_iface#writeLog(int, String)}.
     * 
     * @param message
     *            The {@link String} to be sent over the Serial connection.
     * @return <b>true</b> if the message could be sent, <b>false</b> otherwise.
     */
    public boolean writeSerial(String message) {
        boolean success = false;
        if (isConnected()) {
            try {
                outputStream.write(message.getBytes());
                success = true;
            } catch (IOException e) {
                disconnect();
            }
        } else {
            contact.writeLog(id, "No port is connected.");
        }
        return success;
    }

    /**
     * If a connection is open, an <b>int</b> between 0 and 255 (except the
     * {@link net.Network#divider}) can be sent over the Serial port using this
     * function. The message will be finished by sending the
     * {@link net.Network#divider}. If no connection is available, <b>false</b>
     * is returned and a message is sent using
     * {@link net.Network_iface#writeLog(int, String)}.
     * 
     * @param numBytes
     *            The number of bytes to send over the Serial port.
     * @param message
     *            [] The array of<b>int</b>s to be sent over the Serial
     *            connection (between 0 and 256).
     * @return <b>true</b> if the message could be sent, <b>false</b> otherwise
     *         or if one of the numbers is equal to the #{@link Network#divider}
     *         .
     */
    public boolean writeSerial(int numBytes, int message[]) {
        boolean success = true;
        int i;
        for (i = 0; i < numBytes; ++i) {
            if (message[i] == divider) {
                success = false;
                break;
            }
        }
        if (success && isConnected()) {
            try {
                for (i = 0; i < numBytes; ++i) {
                        outputStream.write(changeToByte(message[i]));
                }
                outputStream.write(changeToByte(divider));
            } catch (IOException e) {
                success = false;
                disconnect();
            }
        } else if (!success) {
            // message contains the divider
            contact.writeLog(id, "The message contains the divider.");
        } else {
            contact.writeLog(id, "No port is connected.");
        }
        return success;
    }

    private byte changeToByte(int num) {
        byte number;
        int temp;
        temp = num;
        if (temp > 255)
            temp = 255;
        if (temp < 0)
            temp = 0;
        number = (byte) temp;
        return number;
    }
}

package net;

/**
 * An instance of a class implementing this interface has to be passed to the
 * constructor of {@link net.Network}. It will be used by {@link net.Network} to
 * forward received messages, write to a log and take action when the connection
 * is closed.
 * 
 * @see net.Network#Network(int, Network_iface, int)
 * 
 * @author Raphael Blatter (raphael@blatter.sg)
 */
public interface Network_iface {
    /**
     * Is called to write connection information to the log. The information can
     * either be ignored, directed to stdout or written out to a specialized
     * field or file in the program.
     * 
     * @param id
     *            The <b>int</b> passed to
     *            {@link net.Network#Network(int, Network_iface, int)} in the
     *            constructor. It can be used to identify which instance (which
     *            connection) a message comes from, when several instances of
     *            {@link net.Network} are connected to the same instance of a
     *            class implementing this interface.
     * @param text
     *            The text to be written into the log in human readable form.
     *            Corresponds to information about the connection or ports.
     */
    public void writeLog(int id, String text);

    /**
     * Is called when sequence of bytes are received over the Serial interface.
     * It sends the bytes (as <b>int</b>s between 0 and 255) between the two
     * {@link net.Network#divider}s passed via the constructor of
     * {@link net.Network} (
     * {@link net.Network#Network(int, Network_iface, int)}), without the
     * {@link net.Network#divider}s. Messages are only forwarded using this
     * function, once a {@link net.Network#divider} has been recognized in the
     * incoming stream.
     * 
     * @param id
     *            The <b>int</b> passed to
     *            {@link net.Network#Network(int, Network_iface, int)} in the
     *            constructor. It can be used to identify which instance a
     *            message comes from, when several instances of
     *            {@link net.Network} are connected to the same instance of a
     *            class implementing this interface.
     * @param numBytes
     *            Number of valid bytes contained in the message
     * @param message
     *            Message received over the Serial interface. The complete array
     *            of bytes (as <b>int</b>s between 0 and 255) between
     *            {@link net.Network#divider} is sent (without
     *            {@link net.Network#divider}s).
     */
    public void parseInput(int id, int numBytes, int[] message);

    /**
     * Is called when the network has been disconnected. This call can e.g. be
     * used to show the connection status in a GUI or inform the user using
     * other means.
     * 
     * @param id
     *            {@link net.Network#id} of the corresponding
     *            {@link net.Network} instance (see {@link net.Network#id}).
     */
    public void networkDisconnected(int id);
}

每个类都是一个单独的文件。那么为什么会出现这个错误?

2 个答案:

答案 0 :(得分:4)

您应该从父目录中将其作为

启动
java net.Example

运行java命令时,它会获取完整类名,包括包名。所以在你的情况下,JVM试图找到一个名为Example的类 - 它发现Example.class作为文件,但后来失败,因为该类文件包含类net.Example,而不是{{ 1}}。

您需要位于父目录(Example)中,这样当JVM查找...\exempleRXTX\src\net时,它将在net.Example目录中查找名为...\exempleRXTX\src\net\net的文件

答案 1 :(得分:2)

检查.class文件的生成位置,并确保类路径设置正确。但是,似乎你从@Jon提到的正确目录运行`java命令'。

注意:指定'。'(单点)作为类路径值将配置java以搜索同一目录中的.class文件(从中尝试{{1} }命令)。