我成功编译了三个文件,当我尝试启动一个包含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);
}
每个类都是一个单独的文件。那么为什么会出现这个错误?
答案 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} }命令)。