I have written my first java applet and get errors when deploying it on my web server. My applet uses couple of additional jar files like javaMail mail.jar, smtp.jar, mailapi.jar and others. When I try to display my applet in web browser I get such info in Error Dialog:
java.lang.RuntimeException: java.lang.NoClassDefFoundError: javax/mail/Authenticator
..
Caused by: java.lang.NoClassDefFoundError: javax/mail/Authenticator
... 20 more
I am not very good with web applications and not sure what causes this error. From the info I assume that my applet cannot load the libraries. So how can I solve this? I have those libraries on my server in /lib directory. All other files are in main directory. My HTML file is as follows:
<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>
I also tried to load my applet to web browser using JNLP with the same effect. I tried to find some way to point those libraries in HTML file, but I didn’t manage (tried to add another jar archive lines or nativelib in JNLP file). I also tried to add those libraries to jar file with my applet classes, but that didn’t help either.
This is my code where I use javaMail (sendTestResults() method near end of the code):
/*
* 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
}
I also had a problem with other libraries like Sigar.jar, but I suppose it will solve similarly.
Somebody has good tips?
It is necessary to add the Jar containing the
javax.mailpackages to the run-time class-path of the applet. To achieve that (one way is to) put that Jar in the same placeSpeedTester.jarand change the archive attribute from:..to:
Update 1
Change the entire applet element:
From
To
Presuming the package of the applet class is
speedtester_pkgand the applet is namedAppletMain. The code attribute should be the fully qualified name of the applet class, not the path/file name.Update 2
The above advice re. the
mail.jardoes not account for classes that are referenced from within theTest,DataReaderorProgressBarTask(or the classes they load). ‘Rinse and repeat’ that advice for adding extra APIs to the run-time class-path using the archive attribute.Note
It seems the other answers are referring to a web-app. that is entirely server-side. For such a web-app., putting Jars into the
libmakes sense. OTOH an applet can only access a Jar that is available by copy/pasting the URL of the Jar into the browser address bar and hitting enter.In fact doing just that, using a combination of the code-base & href of the Jar, is a good ‘acid test’ of whether an applet will be able to access the archive.