我编写了我的第一个Java applet,并在我的Web服务器上部署时遇到错误。我的applet使用了几个额外的jar文件,如javaMail mail.jar
,smtp.jar
,mailapi.jar
等。当我尝试在Web浏览器中显示我的applet时,我在错误对话框中获得了这样的信息:
java.lang.RuntimeException: java.lang.NoClassDefFoundError: javax/mail/Authenticator
..
Caused by: java.lang.NoClassDefFoundError: javax/mail/Authenticator
... 20 more
我对网络应用程序不是很了解,也不确定导致此错误的原因。从信息我假设我的applet无法加载库。那我怎么解决这个问题呢?我在/ lib目录下的服务器上有这些库。所有其他文件都在主目录中。我的HTML文件如下:
<HTML>
<HEAD>
<TITLE>TPSA Speed Test</TITLE>
</HEAD>
<BODY>
<P>
<APPLET code="speedtester_pkg/AppletMain.class" archive="SpeedTester.jar" width=440 height=600></APPLET>
</P>
</BODY>
</HTML>
我还尝试使用JNLP将我的applet加载到Web浏览器,效果相同。我试图找到一些方法将这些库指向HTML文件,但我没有管理(尝试在JNLP文件中添加另一个jar
存档行或nativelib
)。我也尝试用applet类将这些库添加到jar文件中,但这也无济于事。
这是我的代码,我在代码末尾使用javaMail(sendTestResults()方法):
/*
* AppletMain.java
*/
package speedtester_pkg;
import java.awt.*;
import java.beans.*;
import java.io.*;
import java.util.*;
import java.util.logging.*;
import javax.swing.*;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class AppletMain extends javax.swing.JApplet implements PropertyChangeListener{
private ArrayList<String> customerFields;
private DataReader dataReader;
private Test test;
private FileHandler fh;
private ProgressBarTask progressBarTask;
private JTextField[] customerData;
private String speed, cpuLoad, NICspeed, testTime;
private int timeDef = 60;
/**
* The input file directory
*/
// public String directory = "C:\\Documents and Settings\\Administrator\\Pulpit\\";
public String filename = "speedtestData.txt";
/**
* Input file should be a simple "*.txt" file named "speedtestData.txt"
*/
public File file;
// mail sending data
/**
* TO DO encrypt mailing data
*/
private String smtpHost = "smtp.gmail.com",
username = "myUserName",
password = "myPassword";
private int port = 465; // TLS 587/ SSL 465
/** Initializes the applet Applet */
@Override
public void init() {
try {
java.awt.EventQueue.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
/** This method is called from within the init() method to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
infoPanel = new javax.swing.JPanel();
labelLogo = new javax.swing.JLabel();
labelTitle = new javax.swing.JLabel();
labelLinkSpeed = new javax.swing.JLabel();
labelProcessorLoad = new javax.swing.JLabel();
labelNIC = new javax.swing.JLabel();
buttonStart = new javax.swing.JButton();
jLabel4 = new javax.swing.JLabel();
jLabel5 = new javax.swing.JLabel();
jLabel6 = new javax.swing.JLabel();
jProgressBar = new javax.swing.JProgressBar();
formPanel = new javax.swing.JPanel();
jLabel8 = new javax.swing.JLabel();
buttonSend = new javax.swing.JButton();
labelForm = new javax.swing.JLabel();
infoLabel = new javax.swing.JLabel();
jScrollPane = new javax.swing.JScrollPane();
commentText = new javax.swing.JTextArea();
labelTitle.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
labelTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
labelTitle.setText("Link Speed Test");
labelLinkSpeed.setFont(new java.awt.Font("Tahoma", 1, 24)); // NOI18N
labelLinkSpeed.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
labelProcessorLoad.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
labelProcessorLoad.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
labelNIC.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
labelNIC.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
buttonStart.setText("Start");
buttonStart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonStartActionPerformed(evt);
}
});
jLabel4.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
jLabel4.setText("Szybkość łącza:");
jLabel5.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
jLabel5.setText("Obciążenie procesora:");
jLabel6.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
jLabel6.setText("Szybkość karty sieciowej:");
javax.swing.GroupLayout infoPanelLayout = new javax.swing.GroupLayout(infoPanel);
infoPanel.setLayout(infoPanelLayout);
infoPanelLayout.setHorizontalGroup(
infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, infoPanelLayout.createSequentialGroup()
.addComponent(labelLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(infoPanelLayout.createSequentialGroup()
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addComponent(jLabel6)
.addComponent(jLabel4))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(labelLinkSpeed, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
.addComponent(labelProcessorLoad, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
.addComponent(labelNIC, javax.swing.GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)))
.addComponent(labelTitle, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 289, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(22, 22, 22))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, infoPanelLayout.createSequentialGroup()
.addContainerGap(352, Short.MAX_VALUE)
.addComponent(buttonStart, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE))
);
infoPanelLayout.setVerticalGroup(
infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(infoPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, infoPanelLayout.createSequentialGroup()
.addComponent(labelTitle)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelLinkSpeed, javax.swing.GroupLayout.DEFAULT_SIZE, 31, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel5)
.addComponent(labelProcessorLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel6)
.addComponent(labelNIC, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(6, 6, 6))
.addGroup(infoPanelLayout.createSequentialGroup()
.addGap(16, 16, 16)
.addComponent(labelLogo, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE)
.addComponent(buttonStart)
.addContainerGap())
);
javax.swing.GroupLayout formPanelLayout = new javax.swing.GroupLayout(formPanel);
formPanel.setLayout(formPanelLayout);
formPanelLayout.setHorizontalGroup(
formPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 417, Short.MAX_VALUE)
);
formPanelLayout.setVerticalGroup(
formPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 127, Short.MAX_VALUE)
);
jLabel8.setText("Uwagi:");
buttonSend.setText("Wyślij");
buttonSend.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
buttonSendActionPerformed(evt);
}
});
labelForm.setFont(new java.awt.Font("Tahoma", 0, 14));
labelForm.setText("Formularz:");
infoLabel.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
infoLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
infoLabel.setText("Kliknij przycisk \"Start\" aby rozpocząć test");
commentText.setColumns(20);
commentText.setRows(5);
jScrollPane.setViewportView(commentText);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 437, Short.MAX_VALUE)
.addGap(0, 437, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)
.addComponent(formPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(infoLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)
.addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 417, Short.MAX_VALUE)
.addComponent(infoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(labelForm)
.addComponent(buttonSend, javax.swing.GroupLayout.Alignment.TRAILING))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 572, Short.MAX_VALUE)
.addGap(0, 572, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(infoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(labelForm)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(formPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(buttonSend)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>
public void createGUI()
{
try {
dataReader = new DataReader(this);
dataReader.read();
customerFields = dataReader.getCustomerFields();
testTime = String.valueOf(dataReader.getTestTime());
initComponents();
generateCustomerForm();
test = new Test(this, dataReader.getDownloadURLs(), dataReader.getTestTime());
} catch (ClassNotFoundException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void buttonStartActionPerformed(java.awt.event.ActionEvent evt) {
buttonStart.setEnabled(false);
infoLabel.setText("Poczekaj do końca testu...");
progressBarTask = new ProgressBarTask(this);
infoLabel.setText("progress bar");
progressBarTask.addPropertyChangeListener(this);
progressBarTask.execute();
Thread testThread = new Thread(this.test);
testThread.start();
System.out.println("Test thread \"" + testThread.getName() + "\" started.");
}
private void buttonSendActionPerformed(java.awt.event.ActionEvent evt) {
try {
sendTestResults();
} catch (MessagingException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(AppletMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void generateCustomerForm() throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
{
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
//correcting auto-generated layout
jLabel8.setFont(new java.awt.Font("Tahoma", 0, 11));
labelProcessorLoad.setAlignmentX(RIGHT_ALIGNMENT);
labelLogo.setIcon(new ImageIcon(getImage(getDocumentBase(), "orange.jpeg")));
//gereate JLabels and JTextFields read from file
GridBagLayout gridBagLayout = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
formPanel.setLayout(gridBagLayout);
customerData = new JTextField[customerFields.size()];
for(int i=0; i<customerFields.size(); i++)
{
JLabel l = new JLabel(customerFields.get(i));
l.setFont(new java.awt.Font("Tahoma", 0, 11));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx=0;
gbc.gridy=i;
gbc.weightx = 0.5;
gbc.weighty = 0.5;
formPanel.add(l, gbc);
JTextField t = new JTextField();
t.setFont(new java.awt.Font("Tahoma", 0, 11));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx=1;
gbc.gridy=i;
gbc.weightx = 0.5;
gbc.weighty = 0.5;
formPanel.add(t, gbc);
customerData[i] = t;
}
}
/**
* Invoked when task's progress property changes.
*/
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progress")) {
int progress = (Integer) evt.getNewValue();
jProgressBar.setValue(progress);
}
}
public void setLabelProcessorLoad(String text)
{
labelProcessorLoad.setText(text);
}
public void setLabelLinkSpeed(String text)
{
labelLinkSpeed.setText(text);
}
public void setLabelNIC(String text)
{
labelNIC.setText(text);
}
public JProgressBar getProgressBar()
{
return jProgressBar;
}
public JButton getButtonStart()
{
return buttonStart;
}
public Test getTest()
{
return this.test;
}
public void setNICspeed(String NICspeed) {
this.NICspeed = NICspeed;
}
public void setCpuLoad(String cpuLoad) {
this.cpuLoad = cpuLoad;
}
public void setSpeed(String speed) {
this.speed = speed;
}
public JLabel getInfoLabel() {
return infoLabel;
}
/**
* Prepares e-mail message for sending via google SMTP protocol with SSL
*/
private void sendTestResults() throws MessagingException, UnsupportedEncodingException{
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username,password);
}
});
MimeMessage message = new MimeMessage(session);
//Setting message fields
Address toAddress = new InternetAddress(dataReader.getMail(), "SpeedTest crew");
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject("SpeedTest");
message.setText(prepareMailText(), "UTF8");
Transport.send(message);
infoLabel.setText("Wiadomość z wynikami testu została wysłana pomyślnie");
System.out.println("Mail sent.");
}
/**
* Gets all test results and customer data and prepares mail content
* @return the content of e-mail body
*/
private String prepareMailText()
{
String messageContentHeader = "Prędkość pobierania\t" + "Obciążenie procesora\t" +
"Szybkość łącza karty sieciowej\t" + "Czas trwania testu\t";
String messageContent = speed + "\t"+ cpuLoad + "\t" + NICspeed + "\t" + testTime + "\t";
for(int j=0;j<customerData.length;j++)
{
messageContentHeader += customerFields.get(j) + "\t";
messageContent += customerData[j].getText() + "\t";
}
messageContentHeader += "Uwagi";
messageContent += commentText.getText();
String messageText = messageContentHeader + "\n" + messageContent;
return messageText;
}
// Variables declaration - do not modify
private javax.swing.JButton buttonSend;
private javax.swing.JButton buttonStart;
private javax.swing.JTextArea commentText;
private javax.swing.JPanel formPanel;
private javax.swing.JLabel infoLabel;
private javax.swing.JPanel infoPanel;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel8;
private javax.swing.JProgressBar jProgressBar;
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JLabel labelForm;
private javax.swing.JLabel labelLinkSpeed;
private javax.swing.JLabel labelLogo;
private javax.swing.JLabel labelNIC;
private javax.swing.JLabel labelProcessorLoad;
private javax.swing.JLabel labelTitle;
// End of variables declaration
}
我也遇到过像Sigar.jar这样的其他库的问题,但我想它会解决类似问题。
有人有好的建议吗?
答案 0 :(得分:4)
有必要将包含javax.mail
包的Jar添加到applet的运行时类路径中。要实现这一点(一种方法)将Jar放在同一个地方SpeedTester.jar
并从以下位置更改存档属性:
archive="SpeedTester.jar"
..为:
archive="SpeedTester.jar,mail.jar"
更改整个applet元素:
<APPLET
code="speedtester_pkg/AppletMain.class"
archive="SpeedTester.jar"
width=440
height=600>
</APPLET>
<APPLET
code="speedtester_pkg.AppletMain"
archive="SpeedTester.jar,mail.jar"
width=440
height=600>
</APPLET>
假设applet类的包是speedtester_pkg
,applet名为AppletMain
。 code属性应该是applet类的完全限定名,而不是路径/文件名。
上述建议重新开始。 mail.jar
未考虑从Test
,DataReader
或ProgressBarTask
(或其加载的类)中引用的类。使用存档属性“冲洗并重复”有关向运行时类路径添加额外API的建议。
其他答案似乎指的是网络应用。这完全是服务器端的。对于这样的网络应用程序,将Jars放入lib
是有道理的。 OTOH applet只能通过将Jar的URL复制/粘贴到浏览器地址栏并点击 enter 来访问可用的Jar。
事实上,正是这样做,使用代码库和&amp;组合。 jar的href,是对applet是否能够访问存档的一个很好的“酸测试”。
答案 1 :(得分:0)
您似乎错过了使用javax.mail.Authenticator
您可以使用FindJar网站来确定JAR的名称以及下载位置。谷歌为它;值得了解。
你可能也会错过其他人。继续将JAR添加到应用程序的WEB-INF / lib中,直到CNF异常消失为止。
答案 2 :(得分:0)
缺少JAR(在您的情况下为mail.jar)是任何ClassNotFound异常的主要原因。将其放在应用服务器的 lib 目录中以解决此问题。