3

I have written a java applet which tests user link speed. I gather some system information prom user's computer: CPU load, amount of data downloaded on eth0 interface and NIC card max speed with SIGAR API. I deployed it on a web server but when i try to run it I get following error info in java console:

java.lang.reflect.InvocationTargetException
    at java.awt.EventQueue.invokeAndWait(Unknown Source)
    at speedtester_pkg.AppletMain.init(AppletMain.java:80)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ExceptionInInitializerError
    at speedtester_pkg.Test.<init>(Test.java:54)
    at speedtester_pkg.AppletMain.createGUI(AppletMain.java:282)
    at speedtester_pkg.AppletMain$1.run(AppletMain.java:82)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied (java.util.PropertyPermission sigar.nativeLogging read)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
    at java.lang.System.getProperty(Unknown Source)
    at org.hyperic.sigar.Sigar.<clinit>(Sigar.java:78)
    ... 17 more

I am not sure if this is not blocked due to applet security restrictions, but from the SIGAR user forum (http://forums.hyperic.com/jiveforums/forum.jspa?forumID=2) I have got impression, that it is possible to use it with web applications.

This is my class which uses Sigar API:

    /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package speedtester_pkg;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hyperic.sigar.CpuPerc;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;

/**
 *  The logic of the speed test. Starts downloading threads and performs measurements.
 *
 * @author Karol Abramczyk
 */
public class Test implements Runnable{

    private ArrayList <String> urlsValues;
    private URL[] urls;
    private File[] files;
    private int stabilizationTimeSeconds, threadNo, allThreadsNo;
    private boolean continueDownload;
    public AppletMain applet;
    private Sigar sigar;
    private NetInterfaceStat nis;
    private long downloadedDataOld, downloadedDataNew, uploadedDataOld, uploadedDataNew, dataDownloaded,
            downloadingTime;
    private long startTime, stopTime;
    private double speed;
//    private String dir = "D:\\StraTJ_THD\\Abramczyk\\TestySpeedtestera\\";


    /**
     * Creates new instance of the Test object
     * @param gui the calling AppletGUI object
     * @param urlsVal the list of urls to files to download
     * @param time the time of the delay for line stabilization
     */
    public Test(AppletMain applet, ArrayList<String> urlsVal, int time){
        try {
            this.applet = applet;
            this.urlsValues = urlsVal;
            stabilizationTimeSeconds = time;
            allThreadsNo = urlsVal.size();
            AccessController.doPrivileged(new PrivilegedAction()
            { public Object run()
              {
                try {
                    sigar = new Sigar();
                    nis = sigar.getNetInterfaceStat("eth0");
                } catch (SigarException ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
                return null;
              }
            });


            urls = new URL[allThreadsNo];
            for (int j = 0; j < allThreadsNo; j++) {
                    urls[j] = new URL(urlsValues.get(j));
            }
        } catch (MalformedURLException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * returns number of bytes downloaded so far
     * @return number of bytes downloaded
     */
    private long getDownloadedDataSize()
    {
        return nis.getRxBytes()*8;
    }

    /**
     * returns number of bytes uploaded so far
     * @return number of bytes uploaded
     */
    private long getUploadedDataSize()
    {
        return nis.getTxBytes()*8;
    }

    /**
     * saves data on the test start: time, downloaded and uploaded number of bytes
     */
    private void getStartData()
    {
        downloadedDataOld = getDownloadedDataSize();
        uploadedDataOld = getUploadedDataSize();
        startTime = System.currentTimeMillis();
        System.out.println(nis.getRxBytes());
        System.out.println(downloadedDataOld);
    }

    /**
     * saves dataon the test stop: time, downloaded and uploaded number of bytes
     */
    private void getStopData()
    {
        stopTime = System.currentTimeMillis();
        downloadedDataNew = getDownloadedDataSize();
        uploadedDataNew = getUploadedDataSize();
    }

    /**
     * starts downloading all the files specified in input file
     * @throws java.io.IOException
     * @throws java.lang.InterruptedException
     */
    public void startDownload() throws IOException, InterruptedException{
        continueDownload = true;

        files = new File[allThreadsNo];
        for (int g = 0; g < allThreadsNo; g++) {
            String name = "speedTest" + g + "_";
            files[g] = File.createTempFile(name, null);
        }

        Thread[] threads = new Thread[allThreadsNo];
        for(int i=0; i<allThreadsNo;i++)
        {
            threadNo = i;
            threads[threadNo] = new Thread(new Download(this, threadNo));
            threads[threadNo].start();
        }

    }

    /**
     * preforms mesurements of speed ralated values as speed, cpu load, nic card speed
     * @throws org.hyperic.sigar.SigarException
     * @throws java.lang.InterruptedException
     */
    private void measure() throws SigarException, InterruptedException {

        measureCPUload();

        measureLinkSpeed();

        System.out.println(dataDownloaded);
        System.out.println(downloadingTime);
        System.out.println(speed);

        measureNICspeed();

    }

    /**
     * measures system CPU load and displays it in applet GUI
     * @throws org.hyperic.sigar.SigarException
     */
    private void measureCPUload() throws SigarException
    {
        CpuPerc cpuPerc = sigar.getCpuPerc();
        applet.setLabelProcessorLoad(CpuPerc.format(cpuPerc.getCombined()));
        applet.setCpuLoad(CpuPerc.format(cpuPerc.getCombined()));
    }

    /**
     * measures link speed as:
     * (number_of_bytes_downloaded_at_the_end - number_of_bytes_downloaded_at_the_beginning)/test_time
     * @throws org.hyperic.sigar.SigarException
     */
    private void measureLinkSpeed() throws SigarException
    {
        nis = sigar.getNetInterfaceStat("eth0");
        getStopData();
        dataDownloaded = downloadedDataNew-downloadedDataOld;
        downloadingTime = (stopTime - startTime)/1000;
        speed = dataDownloaded/downloadingTime;
        applet.setLabelLinkSpeed(formatSpeed(speed));
        applet.setSpeed(formatSpeed(speed));
    }

    /**
     * measures Network Card Interface speed
     * @throws org.hyperic.sigar.SigarException
     */
    private void measureNICspeed() throws SigarException
    {
        nis = sigar.getNetInterfaceStat("eth0");
        long nicSpeed = nis.getSpeed();
        applet.setLabelNIC(formatSpeed(nicSpeed));
        applet.setNICspeed(formatSpeed(nicSpeed));
    }

    /**
     * stops file download
     */
    private void stopDownload()
    {
        continueDownload = false;
    }

    /**
     * formats link speed to more readable format with units. For example "3.54324E7"
     * would be formatted to "35.0 Mb/s"
     * @param speed the link speed
     * @return the more readable link speed with units
     */
    public String formatSpeed(double speed)
    {
        double speedD;
        int speedI;

        if(speed>=1000000)
        {
            speedI = (int)speed/10000;
            speedD = speedI/100;
            return new String(speedD + " Mb/s");
        }
        else if(speed<1000000 && speed>=1000)
        {
            speedI = (int)speed/10;
            speedD = speedI/100;
            return new String(speedD + " Kb/s");
        }
        else
        {
            speedI = (int)speed*100;
            speedD = speedI/100;
            return new String(speedD + " b/s");
        }

    }

    /**
     * starts the test thread
     */
    public void run() {
        try {
            startDownload();
            getStartData();
            System.out.println("Sleep for " + stabilizationTimeSeconds + " seconds");
            Thread.sleep(stabilizationTimeSeconds * 1000);
            System.out.println("Sleep finished");
            measure();
            stopDownload();
            Thread.sleep(1000 * files.length / 2);
            //            removeDownloadedFiles();
        } catch (SigarException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public URL[] getUrls() {
        return urls;
    }

    public boolean isContinueDownload() {
        return continueDownload;
    }

    public File[] getFiles() {
        return files;
    }

    public int getStabilizationTimeSeconds() {
        return stabilizationTimeSeconds;
    }

}

This is my first applet and I am not very familiar with the web solutions so if anyone could help me, I would appreciate. I have searcher through many similar topics, but didn't find solution. I tried to use AccessCOntroller.do Priviliged() method, but that didn't work as well. I signed my jar file with applet classes. I am not sure if I should sign those jar libraries, should I? My html file is as follows:

<HTML>
<HEAD>
    <TITLE>Speed Test</TITLE>
</HEAD>
<BODY>


<P>
<APPLET 
    code="speedtester_pkg.AppletMain" 
    archive="SpeedTester.jar,activation.jar,mail.jar,mailapi.jar,sigar.jar,smtp.jar" 
    width=440     
    height=600>
</APPLET>
</P>

</BODY>
</HTML>
k4b
  • 215
  • 1
  • 3
  • 12

1 Answers1

3

The applet needs to be trusted to do certain things. To be trusted, an applet (and the other dependent Jars) must be:

  1. Digitally signed (using a valid code signing certificate) by the developer.
  2. OK'd by the end user when prompted. It generally pays to forewarn the user as to what is required of them ('click OK when prompted'), and why ('so the applet can function'), before throwing up a prompt in their face.
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • @1 It's Java Web Start application. Is it recommended solution for such problems? Is there a solution that lets me keep my applet deployed on a web page? Is it going to help if I just sign the dependent jars and place them on the server? – k4b Sep 16 '11 at 08:22