Java Applets

Ο κώδικας που ακολουθεί είναι ένα πολύ απλό Java applet που εμφανίζει το μήνυμα "Hello World.".

import java.applet.Applet;    // importing the Applet object
import java.awt.*; // importing the ‘abstract window toolkit’

public class HelloWorldApplet extends Applet
{
public void paint(Graphics g)
{
g.drawString("Hello World.",10,10);
}
}
Η εκτέλεση του applet απαιτεί τη ύπαρξη μιας ιστοσελίδας μέσω της οποίας καλείται η κλάση του applet. Ο κώδικας μια ελάχιστης τέτοιας ιστοσελίδας, έστω με όνομα Hello.html, φαίνεται παρακάτω:
<HTML>
<BODY>
<APPLET CODE="HelloWorldApplet.class" WIDTH=150 HEIGHT=50>
</APPLET>
</BODY>
</HTML>

Τo applet εκτελείται με το άνοιγμα της ιστοσελίδας μέσω ενός περιηγητή (browser). H διαχείριση του applet γίνεται από το Java Plug-in του περιηγητή, το οποίο θα πρέπει να είναι συμβατό με το bytecode του applet. Εναλλακτικά η ιστοσελίδα μπορεί να φορτωθεί μέσω της εφαρμογής appletviewer.

appletviewer Hello.html

Java Plug-in

To Java Plug-in του περιηγητή δημιουργεί ένα νήμα για κάθε applet που περιέχει μια ιστοσελίδα. Τα νήματα αυτά εκτελούνται σε ένα στιγμιότυπο του Java Runtime Environment (JRE) που είναι ενσωματωμένο στο περιηγητή.

Τα applets εκτελούνται στο ίδιο στιγμιότυπο JRE αν:

Διαφορετικά τα applets εκελούνται σε ξεχωριστά στιγμιότυπα του JRE. Νήματα που ανήκουν στο ίδιο Applet εκτελούνται στο ίδιο JRE.

Στο διάγραμμα που ακολουθεί τα applets Α, Β εκτελούνται στο ίδιο JRE ενώ το applet C σε διαφορετικό JRE.

This is a picture of the Java Plug-in running applets on different JRE versions.

Java Applets με Swing

To applet που παρουσιάστηκε επεκτείνει τη κλάση java.applet.Applet. Παρακάτω παρουσιάζεται μια εναλλακτική έκδοση ενός applet που χρησιμοποιεί τη κλάση java.applet.JApplet που επιτρέπει τη χρήση συστατικών GUI Swing. Τα applets κληρονομούν σημαντική λειτουργικότητα απο τις κλάσεις Applet ή JApplet, όπως δυνατότητες επικοινωνίας με το περιηγητή και το χειρισμό της γραφικής διεπαφής.

'Ενα άλλο ενδιαφέρον χαρακτηριστικό είναι η χρήση νημάτων που θα συζητηθεί παρακάτω.

Ακολουθεί εναλλακτικός κώδικας:


import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;

public class HelloWorldJApplet extends JApplet {
//Called when this applet is loaded into the browser.
public void init() {
//Execute a job on the event-dispatching thread; creating this applet's GUI.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JLabel lbl = new JLabel("Hello World");
add(lbl);
}
});
} catch (Exception e) {
System.err.println("createGUI didn't complete successfully");
}
}
}
 
Σημείωση: αν το applet δε λειτουργήσει σωστά, ελέγξτε το διερμηνέα JavaScript του περιηγητή σας.

Κύκλος Ζωής ενός Applet

Οι κλάσεις Applet, JApplet,  παρέχουν ένα πλαίσιο εκτέλεσης ενός applet με βάση ορισμένα ορόσημα. Τα ορόσημα είναι σημαντικά γεγονότα στο κύκλο ζωής ενός applet.

O κύκλος ζωής ενός applet έχει τα εξής ορόσημα:

init Method

Η μέθοδος init χρησιμοποιείται για την αρχικοποίηση του applet. Είναι η πρώτη μέθοδος που καλείται, γι' αυτό ο κώδικας πρέπει να είναι σύντομος ώστε το applet να φορτώνεται σύντομα.

start Method

Η μέθοδος start ξεκινά την εκτέλεση του applet. 

stop Method

Η μέθοδος stop αναστέλει την εκτέλεση του applet.

destroy Method

Η μέθοδος destroy απελευθερώνει πόρους που πιθανώς δεσμεύει το applet.

Ακολουθεί ο κώδικας του applet Simple. To applet αυτό εμφανίζει ένα μήνυμα όταν συναντά ένα ορόσημο του κύκλου ζωής του.  Η εκτέλεση του applet εξηγείται παρακάτω.

import java.applet.Applet;
import java.awt.Graphics;

//No need to extend JApplet, since we don't add any components;
//we just paint.
public class Simple extends Applet {

StringBuffer buffer;

public void init() {
buffer = new StringBuffer();
addItem("initializing... ");
}

public void start() {
addItem("starting... ");
}

public void stop() {
addItem("stopping... ");
}

public void destroy() {
addItem("preparing for unloading...");
}

private void addItem(String newWord) {
System.out.println(newWord);
buffer.append(newWord);
repaint();
}

public void paint(Graphics g) {
//Draw a Rectangle around the applet's display area.
g.drawRect(0, 0,
getWidth() - 1,
getHeight() - 1);

//Draw the current string inside the rectangle.
g.drawString(buffer.toString(), 5, 15);
}
}

Φόρτωση

Κατά τη φόρτωση του applet γίνεται η αρχικοποίηση και εμφανίζεται το μήνυμα "initializing... starting...". Κατά το φόρτωση:

Αποχώρηση και Επιστροφή

Όταν ο χρήστης αποχωρεί από την ιστοσελίδα του applet, πχ για να δεί μια άλλη σελίδα, ο περιηγητής σταματά και καταστρέφει το applet. Η κατάσταση του applet δεν διατηρείται. Όταν ο χρήστης επιστρέφει στην ιστοσελίδα, το applet φορτώνεται από την αρχή.

Επαναφόρτωση

Αν γίνει επαναφόρτωση (ή refresh) το τρέχον στιγμιότυπο του applet καταστρέφεται και δημιουργείται νέο στιγμιότυπο.

Κλείσιμο

Όταν ο χρήστης εγκαταλείπει το περιηγητή το applet σταματά και απελευθερώνει τους πόρους.

Αpplets και Νήματα

Η κλάση ThreadExample.java επεκτείνει (extends) τη κλάση Applet αλλά επιπλέον υλοποιεί (implements) της διεπιφάνεια Runnable. Για να την εκτελέσετε μπορείτε να χρησιμιποιείσετε το αρχείο ThreadTest.html. Κατά την εκτέλεση της μεθόδου init του applet δημιουργείται ένα νήμα που κληρονομεί το κώδικα του applet.

public class ThreadExample extends Applet implements Runnable {
   // Define your thread.
   Thread clockThread;
boolean running = true;
   ...

   public void init() {
   ...
      // Create the thread.
      clockThread= new Thread(this);
      // and let it start running
      clockThread.start();
   }
...

Έτσι, με τη κλήση της μεθόδου start  to νήμα του applet εκτελεί το κώδικα της μεθόδου run που ακολουθεί.

   public void run() {
      // loop until told to stop
      while (running)  {
         ...
         // Now the reason for threads
         try {
             // Wait 500 milliseconds before continuing
             clockThread.sleep(500);
         }
         catch (InterruptedException e) {
             System.out.println(e);
         }
         // he has wait and will now restart his actions.
  }

To νήμα αναστέλει την εκτέλεσή του για 500 msec. Η καθυστέρηση αυτή είναι σημαντική όταν υπάρχουν γραφικά που απαιτούν επανασχεδίαση, ή άλλα νήματα του applet που περιμένουν να εκτελεστούν.

Η μεταβλητή running επιτρέπει το τερματισμό του νήματος κατά το κλείσιμο του applet με κλήση της μεθόδου destroy.

public void destroy() {
   // will cause thread to stop looping
   running = false;
   // destroy it.
   clockThread = null;
}

Απλός Πελάτης Διακομιστής με Applet

Έστω οτι η κλάση AppletClient.java βρίσκεται μεταγλωττισμένη (δηλαδή ως AppletClient.class) σε ένα   κατάλογο ενός διακομιστή ιστού, έστω http://Some.Server.com, μαζί με τη κατάλληλη HTML σελίδα NetHello.html.

Μέσω αυτής της σελίδας μεταφρορτώνεται και εκτελείται η κλάση AppletClient.class από το σύστημα του διακομιστή στον υπολογιστή του πελάτη, όπου και εκτελείται μέσα στο περιβάλλον Java Plug-in του περιηγητή. Αφού ξεκινήσει η εφαρμογή μέσω του applet, συμπεριφέρεται πλέον ως κανονικός πελάτης σεπρογραμματισμό υποδοχών.

Το αρχείο κλάσης του πελάτη πρέπει να βρίσκεται στη διαδρομή που ορίζει η σελίδα html. Τα αρχεία που σχετίζονται με το διακομιστή μπορούν να τοποθετηθούν ανεξάρτητα και να εκτελεστούν όπως σε οποιαδήποτε εφαρμογή πελάτη διακομιστή. Η εφαρμογή του διακομιστή πρέπει να εκτελεστεί πριν την εφαρμογή του πελάτη applet.

Από ένα περιηγητή ανοίγουμε την ιστοσελίδα έστω

	http://Some.Server.com/NetHello.html

O κώδικας του πελάτη φαίνεται ο παρακάτω:

import java.io.*;
import java.net.*;
import java.awt.*;
import java.applet.*;

public class AppletClient extends Applet {

  public void init() {
    Label label=new Label(" ");
    int port=5000;
    add(label);
 
    try {
      Socket socket=new Socket(this.getCodeBase().getHost(), port); // connect to server
   
      BufferedReader bufferedreader=new BufferedReader(new // set up in and out streams
          InputStreamReader(socket.getInputStream()));
      PrintWriter printwriter=new PrintWriter(socket.getOutputStream(),true);

      printwriter.println("java"); // send "java" message to server
      String string=bufferedreader.readLine(); // receive message from server

      label.setText(string); // should be "javaworld"
    }
    catch(Exception error){
      label.setText(error.getMessage()); //cannot access host:port
    }
  }
}

Στό κώδικα του πελάτη παρατηρούμε οτι χρησιμοποιείται μόνο η μέθοδος init,  για λόγους απλότητας. Έτσι, για παράδειγμα τα streams και το socket δεν κλείνουν κανονικά στο τέλος της επικοινωνίας. Επίσης η 'κύρια' λειτουργία δεν έχει διαχωριστεί από την αρχικοπόιηση.

Tο πιο ενδιαφέρον σημείο του κώδικα είναι η χρήση της μεθόδου getCodeBase().getHost() στο δημιουργούμενο αντικείμενο socket. Με αυτό το τρόπο δεν απαιτείται πρότερη γνώση της ακριβούς ΙP διεύθυνσης του διακομιστή, αφού αυτή αναγνωρίζεται δυναμικά κατά τη μεταφορά του applet από το διακομιστή ιστού στο JRE του περιηγητή.

Η εφαρμογή του διακομιστή δινεται στο αρχείο Server.java και φαίνεται παρακάτω

import java.net.*;
import java.io.*;

public class Server{

  public static void main(String args[]) {
  int port=5000;

  try {
    ServerSocket serversocket=new ServerSocket(port);
    Socket socket=serversocket.accept(); // wait for client connection

    BufferedReader bufferedreader=new BufferedReader(new
      InputStreamReader(socket.getInputStream()));
    PrintWriter printwriter=new PrintWriter(socket.getOutputStream(),true); //set up in and out streams

    String string1=bufferedreader.readLine(); // receive message from client
    String string2=string1+"world";
    printwriter.println(string2); // send message back to client
    }
  catch(IOException error) {}
  }
}

Όπως και στο πελάτη ο κώδικας είναι πολύ απλός, για παράδειγμα δεν περιλαμβάνει κλείσιμο των streams και sockets.

Μια μεγαλύτερη εφαρμογή Πελάτη Διακομιστή με Applet

Η κλάση QuoteClientApplet.java επιτρέπει την λήψη και την εμφάνιση quotations απο ένα διακομιστή. 

Οι κλάσεις QuoteServer.java και QuoteServerThread.java συνθέτουν την εφαρμογή του διακομιστή.

Το αρχείο one-liners.txt που περιέχει quotations.

Η ιστοσελίδα quoteApplet.html είναι αυτή που θα φορτωθεί στο περιηγητή για την εκτέλεση του applet.

Από ένα περιηγητή ανοίγουμε την ιστοσελίδα έστω
http://JohnDoeMachine:8080/quoteApplet/quoteApplet.html
Εμφανίζεται το QuoteClientApplet.

Εισάγουμε τον αριθμό θύρας της εφαρμογής διακομιστή και πιέζουμε OK. Εμφανίζεται ένα quotation.


QuoteServer Sample Output

QuoteServer Sample Output

Διαχείριση Ασφάλειας και Applets

Tόσο JRE, όσο και το Java Plug-in των περιηγητών, χρησιμοποιούν το Διαχειριστή Ασφαλείας (Security Manager) της Java ώστε να αποτρέπουν κακόβουλο κώδικα να προσβάλει το σύστημα μέσω της εκτέλεσης ενός applet. Ένα applet μπορεί να έχει πρόσβαση σε πόρο του συστήματος, μόνο αν  ο Διαχειριστής Ασφαλείας διαπιστώσει οτι το συγκεκριμένο applet έχει άδεια πρόσβασης στο συγκεκριμένο πόρο. Αυτή η άδεια καθορίζεται μέσω ενός αρχείου πολιτικής ασφάλειας (policy file).

Η πολιτική ασφάλειας γίνεται αντιληπτή μόνο όταν το applet (ή γενικότερα κάποιος φιλοξενούμενος κώδικας) που εκετελείται στο τοπικό JRE ή Java Plug-in προσπαθήσει να προσπελάσει πόρους εκτός του περιβάλλοντος αυτού. Τέτοιοι πόροι είναι, για παράδειγμα, το σύστημα αρχείων, η διεπιφάνεια δικτύου, εντολές συστήματος κλπ. Αν όμως ο κώδικας δρά καθαρά εντός του περιβάλλοντος εκτέλεσης (όπως πχ στο αρχικό παράδειγμα applet) τότε η πολιτική ασφάλειας δεν είναι απαραίτητη.

Το πρόβλημα αυτό θα έγινε ήδη αντιληπτό αν προσπαθήσατε να εκτελέσετε εφαρμογή πελάτη διακομιστή με appletviewer. Στη περίπτωση χρήσης περιηγητή το Java Plug-in χρησιμοποιεί το Διαχειριστή Ασφαλείας του περιηγητή, o όποίος φέρεται διαφορετικά. Συνήθως παράγει ένα πλαίσιο διαλόγου (Security Warning) με επιλογές Yes / No. Όμως, στη περίπτωση του appletviewer, αν ο Διαχειριστής Ασφάλειας δεν είναι σωστά ρυθμισμένος, η εφαρμογή μας καταρρέει.

Το applet WriteFile.java που ακολουθεί προσπαθεί να δημιουργήσει και να γράφει σε ένα αρχείο με όνομα writetest στο τρέχοντα κατάλογο. Για να λειτουργήσει πρέπει να υπάρχει άδεια εγγραφής στο σύστημα αρχείων (στον τρέχοντα κατάλογο συγκεκριμένα) η οποία θα χορηγηθεί μέσω του αντίστοιχου αρχείου πολιτικής ασφάλειας.

import java.awt.*;
import java.io.*;
import java.lang.*;
import java.applet.*;

public class WriteFile extends Applet {
String myFile = "writetest";
File f = new File(myFile);
DataOutputStream dos;

public void init() {

String osname = System.getProperty("os.name");
}

public void paint(Graphics g) {
try {
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(myFile),128));
dos.writeChars("Cats can hypnotize you when you least expect it\n");
dos.flush();
g.drawString("Successfully wrote to the file named " + myFile + " -- go take a look at it!", 10, 10);
}
catch (SecurityException e) {
g.drawString("writeFile: caught security exception: " + e, 10, 10);
}
catch (IOException ioe) {
g.drawString("writeFile: caught i/o exception", 10, 10);
}
}
}

Παρακάτω δίνεται ένα html αρχείο που καλεί το applet:

<html>
<boby>
<hr>
Here's an applet that tries to write to the file named "writetest".

<p>
<applet code=WriteFile.class width=500 height=150 alt="WritingFile applet">
</applet>
<p>
Here's the <a href=WriteFile.java>source</a>.
<p>
This applet won't work unless you've configured your policy to allow it to write such a file; if not, you will see an AccessControlException.
If you've configured your system to allow applets from this applets' location to write the specified file, check your current directory!
You'll find a file there named "writetest".
</body>
</html>
Μπορείτε να εκτελέσετε το applet ως εξής:
appletviewer WriteFile.html
Πρέπει να δείτε ένα μήνυμα σχετικά με μια εξαίρεση ασφαλείας, όπως φαίνεται παρακάτω. Το applet δεν έχει δικαίωμα να γράψει (write permissions) στο τρέχοντα κατάλογο.
WriteFile doesn't have permission to write to writetest

Εκτέλεση Applet με Policy File

Κατά την εκτέλεση ενός applet  o Διαχειριστής Ασφάλειας του JRE προσπαθεί να διαβάσει πολιτικές ασφάλειας από κάποιο αρχείο πολιτικών ασφάλειας (policy file). Τα policy files συνήθως διακρίνονται σε τρείς κατηγορίες:

(α) policy file του JRE
(b) policy file της συγκεκριμένης εκτέλεσης
(γ) policy file του χρήστη

Από τα παραπάνω αρχεία μόνο το policy file του JRE είναι προεγκατεστημένο (εγκαθίσταται με την Java).

Το policy file του JRE βρίσκεται στη θέση
policy.url=file:${java.home}/lib/security/java.policy
όπου η τιμή ${java.home} αντικαθίσταται από το σύστημα εκτέλεσης με το pathname οπου είναι εγκατεστημένο το  JRE. Αν δεν γνωρίζετε το pathname μπορείτε να το βρείτε με τη παρακάτω μέθοδο
$ which java
/usr/bin/java
$ ls -l /usr/bin/java
... /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
... /etc/alternatives/java -> /usr/lib/jvm/java-7-oracle/jre/bin/java
$ cat /usr/lib/jvm/java-7-oracle/jre/lib/security/java.policy
Το policy file του JRE είναι το προεπιλεγμένο αρχείο που διαβάζει ο Διαχειριστής Ασφάλειας, αν ο χρήστης δεν ορίσει κάτι διαφορετικό.

Το policy file της εκτέλεσης  καλείται μόνο για τη συγκεκριμένη εκτέλεση όπως παρακάτω:
appletviewer -J-Djava.security.policy=policy.url WriteFile.html
όπου το policy.url αντιστοχεί σε οποιοδήποτε έγκυρο pathname (URLname). Aν για παράδειγμα το policy file της εκτέλεσης βρίσκεται στον ίδιο κατάλογο με το ΗΤΜL αρχείο WriteFile.html και ονομάζεται mypolicy τότε η σύνταξη της εντολής εκτέλεσης θα είναι η εξής
appletviewer -J-Djava.security.policy=mypolicy WriteFile.html
Tο pathname θα μπορούσε να έχει τη μορφή file:/home/myhome/mypolicy ή http://Some.Server.com/Policies/mypolicy

Το policy file του χρήστη -αν υπάρχει τέτοιο- βρίσκεται στη θέση
policy.url=file:${user.home}/.java.policy
όπου η τιμή ${user.home} αντικαθίσταται από το σύστημα εκτέλεσης με το pathname του οικείου καταλόγου του χρήστη. Αν δε γνωρίζετε το pathname μπορείτε να το βρείτε με την εντολή
$echo $HOME
To policy file χρήστη μας επιτρέπει να συλλέξουμε σε ένα σημείο όλες τις επιυθμητές πολιτικές ασφάλειας που μας αφορούν ώστε η κλήση του Διαχειριστή Ασφάλειας να είναι ευκολότερη.

Αν επομένως θεωρήσουμε οτι το policy file mypolicy βρίσκεται στον ίδιο κατάλογο με το WriteFile.html και το WriteFile applet, η εκτέλεση της εντολής
appletviewer -J-Djava.security.policy=mypolicy WriteFile.html
θα επιτρέψει τη δημιουργία και εγγραφή στο αρχείο writetest, σύμφωνα με το παρακάτω σχήμα.
WriteFile can now access writetest

Δομή απλού Policy File

Ένα απλό policy file είναι ένα απλό text αρχείο που έχει συγκεκριμένη δομή. H δομή ενός policy file είναι η εξής:

grant [signedBy <SignerNames>], 
[codebase <Codebase>],
[principal prinicipal_class_name <PrincipalName>] { permission <Permission>; permission <Permission>; permission <Permission>; };
<CodeBase>: A URL. For example, "file:${java.home}/lib/tools.jar", "http://Some.Server.com/applets/" When [codebase <Codebase>] is not specified, listed permissions are applied to everything. If URL ends with a JAR file name, only the classes in the JAR file belong to the codebase. If URL ends with "/", only the class files in the specified directory belong to the codebase. If URL ends with "*", all JAR and class files in the specified directory belong to the codebase. If URL ends with "-", all JAR and class files in the specified directory and its subdirectories belong to the codebase.

<Permissions>: Consists of Permission Type : class name of the permission Target Name : name specifying the target Actions : actions allowed on target For example, the following syntax grants read and write permissions on file /tmp/xxx java.io.FilePermission "/tmp/xxx", "read, write"

Tα πεδία signedBy και principal δεν εξετάζονται εδώ. Για ανάλυση και παραδείγματα δείτε στο σύνδεσμο  http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html .

Για το παράδειγμα του applet WriteFile, ένα απλό  policy file θα έχει τη μορφή
grant {
permission java.io.FilePermission "writetest", "write";
};
που σημαίνει οτι ένα applet με οποιοδήποτε όνομα και προέλευση έχει δικαιώματα εγγραφής στο αρχείο writetest στον τρέχοντα κατάλογο.

Για το παράδειγμα της απλής εφαρμογής πελάτη διακομιστή με applet, στον υπολογιστή που θα εκτελέσει το πελάτη πρέπει να δημιουργηθεί ένα απλό policy file της μορφής
grant {
    permission java.net.SocketPermission "Some.Server.com:5000", "connect, accept, resolve";
};
που σημαίνει αποδοχή σύδεσης και επικοινωνίας μέσω υποδοχών με τη θύρα 5000 του συγκεκριμένου διακομιστή.

Ένα "ακραίο" policy file της μορφής
grant {
    permission java.security.AllPermission;
};
μας επιτρέπει να εκτελέσουμε οποιοδήποτε applet ή κλάση Java.

Ο σύνδεσμος http://download.java.net/jdk8/docs/technotes/guides/security/permissions.html περιγράφει τη σύνταξη και τις ιδιότητες όλων των security permissions στη Java.

Εκτός από τα απλά στατικά policy files που περιγράφονται, υπάρχει η δυνατότητα συγγραφής δυναμικών policy files, όπου τα διάφορα πεδία του policy file μπορεί να υπολογίζονται κατά την εκτέλεση. Για περισσότερες πληροφορίες δείτε το σύνδεσμο http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html .

Policy Tool

Το εργαλείο Policy Tool επιτρέπει τη διαλογική κατασκευή policy files. Για να δημιουργήσουμε ένα policy file ξεκινούμε το Policy Tool:
policytool

To Policy Tool κατ' αρχήν προσπαθεί να αντλήσει πληροφορίες από το προεπιλεγμένο user policy file. Το user policy file, εάν αυτό υπάρχει, πρέπει να ονομάζεται .java.policy και να βρίσκεται στον user home directory.

Τη πρώτη φορά που θα χρησιμοποιήσετε το Policy Tool θα δείτε ένα άδειο παράθυρο όπως αυτό.

the PolicyTool window

Δημιουργία Policy File

Επιλέγουμε το κουμπί Add Policy Entry. Εμφανίζεται το παρακάτω παραθυρο:

the Policy Entry dialog


Το CodeBase καθορίζει το URL από όπου προέρχεται ο κώδικας που εκτελείται. Αν η γραμμή CodeBase μείνει άδεια αυτό σημαίνει "κώδικας απο οπουδήποτε".

Το SignedBy καθορίζει την υπογραφή (πιστοποιητικό) που βρίσκεται σε κάποιο keystore. Αν η γραμμή SignedBy μείνει άδεια αυτό σημαίνει "οποιοδήποτε πιστοποιητικό".

Αν ορίσετε τιμές στο CodeBase και στο SignedBy, τότε παρέχετε άδειες μόνο σε κώδικα από συγκεκριμένη πηγή και με συγκεκριμένη υπογραφή.

Η απλούστερη επιλογή είναι να αφήσουμε τις δύο γραμμές άδειες.

Επιλέγουμε το κουμπί Add Pemission και εμφανίζεται το παρακάτω πλαίσιο διαλόγου.

the Permissions dialog
  1. Επιλέγουμε File Permission από το Permissions drop-down list. Δεξιά εμφανίζεται το πλήρες όνομα java.io.FilePermission.
  2. Δεξιά από το πλαίσιο Target Name γράφουμε :
    writetest
  3. Επιλέγουμε write από το Actions drop-down list.
the Permissions dialog, with fields filled in

Επιλέγουμε OK. Η νέα πολιτική ασφάλειας έχει καταγραφεί. Για να τη σώσουμε σε ένα αρχείο policy file πηγαίνουμε στο Save As από το File menu. Μετακινούμαστε πχ στο κατάλογο όπου βρίσκεται η html σελίδα που θα φορτώσει το applet και σώζουμε το policy file ως mypolicy.

Σε επόμενη χρήση του Policy Tool μπορούμε να φορτώσουμε, επιθεωρήσουμε ή διιορθώσουμε το policy file μας. Εάν θελήσουμε να εμφανίσουμε το policy file με την εντολή cat θα δούμε το εξής αρχείο:

grant {
permission java.io.FilePermission "writetest", "write";
};