Applet Access Denied bei Function-Aufruf

chrissy

Bekanntes Mitglied
Hallo,

ich habe ein Applet, welches bei Button-Klick einen JFileChooser öffnet.

Java:
import java.applet.Applet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.security.AccessControlException;

import javax.swing.JFileChooser;


public class browser extends Applet
{
  JFileChooser file;
  
  public browser()
  {
  }

  public static void main(String[] args)
  {
    browser browser = new browser();
    browser.init();
    browser.start();
  }
  
  public void start()
  {   
    
    file = new JFileChooser();
  
  }
  
  public String showDialog()
  {    
    String dir = new String();
    
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = file.showDialog(null, "OK");
    if (returnVal == JFileChooser.APPROVE_OPTION)
    {
      dir = file.getSelectedFile().getAbsolutePath();
      if (dir.contains(":\\") )
      {
        String driveOld = dir.substring(0, dir.indexOf(":") + 1);
        String driveNew = convertToUNCPath(driveOld);
        if (driveNew != null) dir = dir.replace(driveOld, driveNew);
      }
    } 
    
    return dir;
  }
  
  private String convertToUNCPath(String path)
  {
    String s = null;
    String unc = null;
    String result ="";
    
    StringBuffer command = new StringBuffer("C:\\Windows\\System32\\net.exe use ");
    command.append(path);
    
    try
    {
      Process p = Runtime.getRuntime().exec( command.toString() );
      BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream()) );        
      while((s = in.readLine()) != null) 
      {
        if (s.startsWith("Remotename")) unc =s.substring(12).trim();
      }
    }
    catch (IOException e) 
    {
      result = e.getMessage();
      showStatus( result );
      System.out.println(result);
    }
    catch ( AccessControlException e)
    {
      result = command + " " + e.getMessage();
      showStatus( result );
      System.out.println(result);
    }

    return unc;
  }
}

HTML:
HTML:
<html><head><title>Test</title>
<script type="text/javascript">
function openDialog()
{
 alert('hello');
 var applet = document.getElementById("Hallo")	
 document.getElementById('textHelp').value = applet.showDialog();
}
</script>
</head><body>
<!--[if !IE]> Firefox and others will use outer object -->
      
      <object classid="java:browser.class" 
              type="application/x-java-applet"
              archive="FileBrowse.jar" 
              name="FileBrowaw" id="Hallo"
              height="0" width="0">
        <param name="archive" value="FileBrowse.jar" />
</object>
      <!--<![endif]-->
<form name="Eingabe" action="">
<input type="text" name="Text" id="textHelp">
<input type="button" value="Test" onclick="openDialog();">
</form>
</body></html>

Das Applet ist erfolgreich signiert (per SignTool.bat von L-ectron-X) sollte also auf das Dateisystem des Clients zugreifen können. Die Abfrage, ob man dem Zertifikat vertrauen möchte, kommt auch und ich klicke natürlich brav "Ja" an.

Beim Button-Klick bekomme ich nun die Fehlermeldung:
uncaught exception: java.security.AccessControlException: access denied (java.util.PropertyPermission user.dir read)

... was heißt, mein Applet ist nicht signiert ...

Gleiches Szenario, allerdings wird der JFileChooser sofort in der start()-Procedure aufgerufen:
Java:
import java.applet.Applet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.security.AccessControlException;

import javax.swing.JFileChooser;


public class browser extends Applet
{
  JFileChooser file;
  
  public browser()
  {
  }

  public static void main(String[] args)
  {
    browser browser = new browser();
    browser.init();
    browser.start();
  }
  
  public void start()
  {   
    String dir = new String();
    file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = file.showDialog(null, "OK");
    if (returnVal == JFileChooser.APPROVE_OPTION)
    {
      dir = file.getSelectedFile().getAbsolutePath();
      if (dir.contains(":\\") )
      {
        String driveOld = dir.substring(0, dir.indexOf(":") + 1);
        String driveNew = convertToUNCPath(driveOld);
        if (driveNew != null) dir = dir.replace(driveOld, driveNew);
      }
    } 
  
  }
   
  private String convertToUNCPath(String path)
  {
    String s = null;
    String unc = null;
    String result ="";
    
    StringBuffer command = new StringBuffer("C:\\Windows\\System32\\net.exe use ");
    command.append(path);
    
    try
    {
      Process p = Runtime.getRuntime().exec( command.toString() );
      BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream()) );        
      while((s = in.readLine()) != null) 
      {
        if (s.startsWith("Remotename")) unc =s.substring(12).trim();
      }
    }
    catch (IOException e) 
    {
      result = e.getMessage();
      showStatus( result );
      System.out.println(result);
    }
    catch ( AccessControlException e)
    {
      result = command + " " + e.getMessage();
      showStatus( result );
      System.out.println(result);
    }

    return unc;
  }
}

gleiche Art der Signierung, ebenfalls erfolgreich, funktioniert ohne Probleme, bei Aufruf der Seite wird das Zertifikat abgefragt und nach dem Bestätigen wird der JFilechooser angezeigt ... allerdings bekomme ich dann ja nicht meinen Rückgabewert ins Textfeld.

Kann mir bitte jemand erklären woran das liegt. Ich bin völlig ratlos und weiß nicht, wo ich ansetzen kann, um das Problem zu lösen.

Danke für eure Hilfe,
chrissy
 
Zuletzt bearbeitet von einem Moderator:

L-ectron-X

Gesperrter Benutzer
Wo ist deine überschriebende init()-Methode? Das ist die erste Methode aus dem Applet-Lebenszyklus, die vom Browser aufgerufen wird.
In Applets gibt es keine main()-Methode.
 

turtle

Top Contributor
Das Signieren von Applets ändert ja nicht die Policy-Einstellungen, Daher bekommst Du auch weiterhin diese Exception.

Die Sicherheitseinstellungen des JDK werden mit Hilfe von Policy-Dateien definiert. Es gibt im Dateisystem eine Stelle, von denen das JDK sie standardmäßig einliest. Die System-Policies befinden sich in der Datei java.policy im Unterverzeichnis jre\lib\security

Darin musst Du einen Eintrag haben, der es Deinem Applet erlaubt, die Property zu lesen:

Code:
grant SignedBy "<WasDuBeimSignierenAngegebenHast>" {
  permission java.util.PropertyPermission "user.dir", "read";
};
 

chrissy

Bekanntes Mitglied
Hallo L-ectron-X,

dass ein Applet keine main braucht, weiß ich, die ist nun aber mal drin, weil das ganze mal eine Java-Application war. Nun soll es aber ins Web ...
Die init()-Methode habe ich aufgrund dieser Information: Java Applets - Methods for Milestones nicht überschrieben. Andere Applets, die ich geschrieben habe, kommen auch ohne aus.
Mein eigentliches Problem kann, glaube ich, auch nciht darauf zurückgeführt werden, da ja ein sofortiger Aufruf von JFileChooser aus start() funktioniert, nur beim Aufruf von showDialog für die Rückgabe nicht.

Aber ich werde mal die init() einbauen, mal sehen, was da läuft.

chrissy
 

L-ectron-X

Gesperrter Benutzer
turtle hat gesagt.:
Das Signieren von Applets ändert ja nicht die Policy-Einstellungen, Daher bekommst Du auch weiterhin diese Exception.
Du brauchst doch nicht irgendwelche Policy-Dateien ändern, um signierte Applets ausführen zu können. Mit der Anahme des Zertifikats ist die Sache erledigt und die signierte Anwendung bekommt volle Zugriffsrechte.

Ich bräuchte nur den Code vom TO anpassen und signieren, dann würde das laufen, ohne das du noch irgendwo rumfummeln musst.
 

chrissy

Bekanntes Mitglied
Hallo turtle,

ok ich glaub, jetzt hab ich was falsch verstanden, ich dachte, man signiert applets, damit man nicht mit der Policy rummachen muss, vor allem, da ich ja zur Laufzeit keinen Zugriff auf das Client-System habe und somit keinen Einfluss darauf, was beim USer drin steht.
Laut L-ectron-X tutorial zum Signieren ist dies auch nicht notwendig ... oder bin ich jetzt total auf dem falschen Weg?

chrissy
 

turtle

Top Contributor
Ihr habt Recht und ich bin doof, weil ich auf etwas aus Halbwissen beantwortet habe.

Ich habs gerade nachgeschlagen und natürlich bekommen signierte Applets AllPermissions bei der Ausführung.

Sorry für meinen Post:oops:
 

chrissy

Bekanntes Mitglied
Hi,

Ich habe nun die init()-Methode überschrieben und die main() entfernt, mein Java sieht nun folgendermaßen aus:
Java:
import java.applet.Applet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.security.AccessControlException;

import javax.swing.JFileChooser;


public class browser extends Applet
{
  JFileChooser file;
  
  public void init()
  {
    file = new JFileChooser();
  }
  
  public void start()
  {   
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  }
  
  public String showMyDialog()
  {    
    String dir = new String();
  
    int returnVal = file.showDialog(null, "OK");
    if (returnVal == JFileChooser.APPROVE_OPTION)
    {
      dir = file.getSelectedFile().getAbsolutePath();
      if (dir.contains(":\\") )
      {
        String driveOld = dir.substring(0, dir.indexOf(":") + 1);
        String driveNew = convertToUNCPath(driveOld);
        if (driveNew != null) dir = dir.replace(driveOld, driveNew);
      }
    } 
    
    return dir;
  }
  
  private String convertToUNCPath(String path)
  {
    String s = null;
    String unc = null;
    String result ="";
    
    StringBuffer command = new StringBuffer("C:\\Windows\\System32\\net.exe use ");
    command.append(path);
    
    try
    {
      Process p = Runtime.getRuntime().exec( command.toString() );
      BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream()) );        
      while((s = in.readLine()) != null) 
      {
        if (s.startsWith("Remotename")) unc =s.substring(12).trim();
      }
    }
    catch (IOException e) 
    {
      result = e.getMessage();
      showStatus( result );
      System.out.println(result);
    }
    catch ( AccessControlException e)
    {
      result = command + " " + e.getMessage();
      showStatus( result );
      System.out.println(result);
    }

    return unc;
  }
}

Die Fehlermeldung bleibt allerdings die gleiche ... Wie schon gesagt, bei einem direkten Öffnen, des FileChoosers aus der init() oder start() Methode, klappt auch alles ohne Probleme. Allerdings benötige ich den Rückgabewert und rufe starte deshalb das Applet und greife dann auf showMyDialog() zu (mit Fehler).

Noch eine Idee was da schief läuft.

Danke
chrissy
 

Marco13

Top Contributor
Bist du sicher, dass die Exception nicht von "convertToUNCPath" kommt? Was passiert, wenn du die Verwendung dieser Methode mal testweise auskommentierst?
 

chrissy

Bekanntes Mitglied
Hallo Marco13,

ja ich bin mir sicher, ich hatte den Block für UNC auch schon komplett auskommentiert und es kam die gleiche Fehlermeldung. Außerdem kommt er ja überhaupt nicht soweit, da der Fehler ja bereits beim Aufruf von showMyDialog() kommt. U nd es funktioniert ja alles super wenn ich den ganzen Code von showMyDialog() in die start()-Methode packe. Aber wie komme ich dann an meine Rückgabevariable ????

chrissy
 

L-ectron-X

Gesperrter Benutzer
Wenn ich deinen Code etwas umbaue, um Ergebnisse zu sehen,
Java:
import java.io.*;
import java.security.AccessControlException;
import javax.swing.*;

public class browser extends JApplet
{
  private JFileChooser file;

  public void init()
  {
    file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  }

  public void start()
  {
    String result = showMyDialog();
    JOptionPane.showMessageDialog(null, "Die Auswahl lautet: "+result, "Ergebnis", JOptionPane.INFORMATION_MESSAGE);
  }

  public String showMyDialog()
  {
    String dir = null;

    int returnVal = file.showDialog(null, "OK");
    if (returnVal == JFileChooser.APPROVE_OPTION)
    {
      dir = file.getSelectedFile().getAbsolutePath();
      if (dir.contains(":\\") )
      {
        String driveOld = dir.substring(0, dir.indexOf(":") + 1);
        String driveNew = convertToUNCPath(driveOld);
        if (driveNew != null) dir = dir.replace(driveOld, driveNew);
      }
    }

    return dir;
  }

  private String convertToUNCPath(String path)
  {
    String s = null;
    String unc = null;
    String result ="";

    StringBuffer command = new StringBuffer("C:\\Windows\\System32\\net.exe use ");
    command.append(path);

    try
    {
      Process p = Runtime.getRuntime().exec( command.toString() );
      BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream()) );
      while((s = in.readLine()) != null)
      {
        if (s.startsWith("Remotename")) unc =s.substring(12).trim();
      }
    }
    catch (IOException e)
    {
      result = e.getMessage();
      showStatus( result );
      System.out.println(result);
    }
    catch ( AccessControlException e)
    {
      result = command + " " + e.getMessage();
      showStatus( result );
      System.out.println(result);
    }

    return unc;
  }
}
diesen dann signiere und in folgende HTML-Datei einbaue,
HTML:
<html>
<head>
<title>browser-Applet</title>
</head>
<body>
<applet archive="browser.jar" code="browser.class"  width="300" height="300">
</applet>
</body>
</html>

funktioniert das Applet bei mir ohne Fehlermeldung... :bahnhof:
 

chrissy

Bekanntes Mitglied
Hi L-extron-X,

danke für deine Hilfe, werde das mal ausprobieren. Ich habe mich in der Zwischenzeit aber auch noch mal ein bißchen durch das Java-Tutorial gearbeitet und eine Lösung über das JSObject gefunden.
Java:
import java.applet.Applet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessControlException;
import javax.swing.JFileChooser;
import netscape.javascript.JSException;
import netscape.javascript.JSObject;


public class browser extends Applet
{
  JFileChooser file;
  
  public void init()
  {
  }
  
  public void start()
  {   
    String dir = "";
    file = new JFileChooser();
    file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    int returnVal = file.showDialog(null, "OK");
    if (returnVal == JFileChooser.APPROVE_OPTION)
    {
      dir = file.getSelectedFile().getAbsolutePath();
      if (dir.contains(":\\") )
      {
        String driveOld = dir.substring(0, dir.indexOf(":") + 1);
        String driveNew = convertToUNCPath(driveOld);
        if (driveNew != null) dir = dir.replace(driveOld, driveNew);
      }
    } 
    try
    {
      JSObject window = JSObject.getWindow(this);
      window.call("setPath", new Object[] {dir});
    }
    catch (JSException jse)
    {
      jse.printStackTrace();
    }
  }
    
  private String convertToUNCPath(String path)
  {
    String s = null;
    String unc = null;
    String result ="";
    
    StringBuffer command = new StringBuffer("C:\\Windows\\System32\\net.exe use ");
    command.append(path);
    
    try
    {
      Process p = Runtime.getRuntime().exec( command.toString() );
      BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream()) );        
      while((s = in.readLine()) != null) 
      {
        if (s.startsWith("Remotename")) unc =s.substring(12).trim();
      }
    }
    catch (IOException e) 
    {
      result = e.getMessage();
      showStatus( result );
      System.out.println(result);
    }
    catch ( AccessControlException e)
    {
      result = command + " " + e.getMessage();
      showStatus( result );
      System.out.println(result);
    }

    return unc;
  }
}

Das funktioniert ebenfalls ohne Probleme. Man muß nur im HTML folgende Änderung machen:
HTML:
<html><head><title>Test</title>
<script type="text/javascript">
function setPath(path)
{
 document.getElementById('textHelp').value = path;
}
</script>
</head><body>
<!--[if !IE]> Firefox and others will use outer object -->
      
      <object classid="java:browser.class" 
              type="application/x-java-applet"
              archive="FileBrowse.jar" 
              name="Run RAdmin Viewer" id="Hallo"
              height="0" width="0">
        <param name="archive" value="FileBrowse.jar">
	<PARAM NAME="MAYSCRIPT" VALUE="true">
</object>
      <!--<![endif]-->
<form name="Eingabe" action="">
<input type="text" name="Text" id="textHelp">
<input type="button" value="Test" onclick="openDialog();">
</form>
</body></html>

Vielen Dank für eure Hilfe
chrissy
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben