{"id":504,"date":"2011-02-21T08:00:49","date_gmt":"2011-02-21T07:00:49","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=504"},"modified":"2016-01-11T23:44:24","modified_gmt":"2016-01-11T22:44:24","slug":"java-applet-tutorial","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/java-applet-tutorial\/","title":{"rendered":"Java Applet Tutorial: Applet erstellen, einbinden und mit Javascript ansprechen"},"content":{"rendered":"<p>Wenn ich an Java Applets denke, ist damit immer ein verstaubtes Web 1.0 &#8211; Bild assoziiert, gepaart mit animierten gifs und anderen Schandtaten. Heutzutage haben die Applets ihre Nische gefunden und werden vor allem da benutzt, wo Javascript noch zu langsam \/ umst\u00e4ndlich ist, bspw. mathematische Zwecke. Wir widmen uns dem Thema mal ganz von vorne. Selbst wenn keine Javakenntnisse bestehen, soll man also noch gut folgen k\u00f6nnen. Soweit der Plan.<\/p>\n<h2>Was am Ende bei rumkommen wird<\/h2>\n<p>Wir werden ein Java-Applet bauen, das den Inhalt von Ordnern auf dem PC des Users in einer Liste anzeigt. Auch das L\u00f6schen von Dateien ist m\u00f6glich. Das Java-Applet wird von au\u00dfen per Javascript angesteuert, um in andere Verzeichnisse wechseln zu k\u00f6nnen. W\u00e4re zwar nicht n\u00f6tig, aber um zu zeigen dass &#8211; und vor allem wie &#8211; sowas geht, tun wir es. <\/p>\n<p><iframe src=\"https:\/\/www.youtube.com\/embed\/IPbUHrs8mXE\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>So, angeschnallt!<\/p>\n<h2>Applet anlegen<\/h2>\n<p>Wir werden Netbeans verwenden. In Eclipse sollte es aber simultan gehen. Ich setze ein f\u00fcr die Java-Entwicklung konfiguriertes Netbeans voraus (incl. JDK). Wird <a href=\"https:\/\/d-mueller.de\/blog\/java-und-sqlite\/\">hier in den ersten 2 Schritten<\/a> kurz angeschnitten. Okay.<\/p>\n<ol>\n<li>Neues Projekt -> &#8222;Java Application&#8220;\n<div id=\"attachment_505\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/1-new-project.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-505\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/1-new-project-300x212.png\" alt=\"Neues Projekt anlegen\" title=\"Neues Projekt anlegen\" width=\"300\" height=\"212\" class=\"size-medium wp-image-505\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/1-new-project-300x212.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/1-new-project.png 585w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-505\" class=\"wp-caption-text\">Neues Projekt anlegen<\/p><\/div>\n<\/li>\n<li>Das Projekt nennen wir <i>fileapplet<\/i>. Die Main-Klasse heisst <i>com.dav.FileApplet<\/i>. Bedeutet: Es wird im Package <i>com.dav<\/i> eine Klasse mit dem Name <i>FileApplet.java<\/i> angelegt. That&#8217;s what we want.\n<div id=\"attachment_506\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/2-anlegen.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-506\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/2-anlegen-300x223.png\" alt=\"Projekt anlegen\" title=\"Projekt anlegen\" width=\"300\" height=\"223\" class=\"size-medium wp-image-506\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/2-anlegen-300x223.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/2-anlegen.png 596w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-506\" class=\"wp-caption-text\">Projekt anlegen<\/p><\/div>\n<\/li>\n<li>Jetzt putzen wir die automatisch angelegte <i>main<\/i> erstmal weg, die brauchen wir nicht. Die Datei sollte nun so aussehen:\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npackage com.dav;\r\n\r\npublic class FileApplet \r\n{\r\n\r\n}\r\n<\/pre>\n<p>Gut, damit l\u00e4sst sich arbeiten.\n<\/li>\n<\/ul>\n<h2>Erster GUI-Entwurf<\/h2>\n<p>Unsere Klasse erbt von <i>JApplet<\/i> und bekommt einen Konstruktor (der in Java genauso hei\u00dft wie die Klasse). Weiterhin kloppen wir alle import&#8217;s dazu, die wir im kompletten Projekt brauchen werden, dass wir Ruhe haben.<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npackage com.dav;\r\n\r\nimport java.awt.*;\r\nimport java.awt.event.*;\r\nimport javax.swing.*;\r\nimport java.io.File;\r\nimport java.security.*;\r\nimport java.util.Vector;\r\n\r\npublic class FileApplet extends JApplet\r\n{\r\n    public FileApplet()\r\n    {\r\n       \r\n    }\r\n}\r\n<\/pre>\n<p>Wie ihr im Video gesehen habt: Wir haben ein <b>Label<\/b> ganz oben, welches den aktuellen Pfad beinhaltet. Darunter sitzt die <b>Liste<\/b> als Dateinamensanzeige. Und ganz unten ist letztendlich der <b>L\u00f6schen-Button<\/b>. Weiterhin brauchen wir eine Variable, die den aktuellen Dateipfad aufnimmt.<\/p>\n<p>Damit sieht unsere Klasse jetzt so aus:<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npublic class FileApplet extends JApplet\r\n{\r\n    private String path;\r\n\r\n    private JLabel lblPath;\r\n    private JList lstFiles;\r\n    private JButton btnDelete;\r\n\r\n    public FileApplet()\r\n    {\r\n        \/\/assign LayoutManager to panel\r\n        JPanel contentPane = (JPanel)this.getContentPane();\r\n        contentPane.setLayout(new BorderLayout(10, 10));\r\n\r\n        \/\/add Label for Path on Top\r\n        lblPath = new JLabel(&quot;Hier steht der Pfad sp\u00e4ter&quot;);\r\n        contentPane.add(lblPath, BorderLayout.NORTH);\r\n\r\n        \/\/add List with all files of path to center\r\n        lstFiles = new JList();\r\n        contentPane.add(new JScrollPane(lstFiles), BorderLayout.CENTER);\r\n\r\n        \/\/add button to bottom\r\n        btnDelete = new JButton(&quot;L\u00f6schen&quot;);\r\n        contentPane.add(btnDelete, BorderLayout.SOUTH);\r\n    }\r\n}\r\n<\/pre>\n<p>Hier sehe ich jetzt nichts gro\u00df erkl\u00e4renswertes. Ist halt der Java-way of life, um Elemente zu erzeugen und auf das Panel zu packen. Es kommt ein LayoutManager (BorderLayout) zum Einsatz, der <a href=\"http:\/\/download.oracle.com\/javase\/tutorial\/uiswing\/layout\/border.html\">hier genauer erkl\u00e4rt wird<\/a>. Tut aber eigentlich nix zur Sache und ist blo\u00df zur ordentlichen Strukturierung der Elemente da.<\/p>\n<h2>Wir wollen Ergebnisse!<\/h2>\n<p>So, das reicht erstmal. Die UI ist nun vollst\u00e4ndig und wir schauen uns das mal an. Dazu builden wir das Projekt und navigieren zur entstandenen <i>fileapplet.jar<\/i> ins <i>dist\/<\/i> &#8211; Verzeichnis unseres Projektordners &#8211; zumindest packt Netbeans die .jar da hin. Alleine ist sie aber nicht lauff\u00e4hig, deswegen erstellen wir eine <i>index.html<\/i> im selben Ordner, die wie folgt aufgebaut ist:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt; \r\n&lt;head&gt; \r\n\t&lt;meta charset=&quot;utf8&quot; \/&gt;\r\n\t&lt;title&gt;File Javaapplet&lt;\/title&gt;\r\n&lt;\/head&gt; \r\n&lt;body&gt; \r\n\t&lt;object type=&quot;application\/x-java-applet;version=1.4.1&quot; name=&quot;jsap&quot; id=&quot;jsap&quot; width=&quot;400&quot; height=&quot;600&quot;&gt;\r\n\t\t&lt;param name=&quot;archive&quot; value=&quot;fileapplet.jar&quot;&gt; \r\n\t\t&lt;param name=&quot;code&quot; value=&quot;com.dav.FileApplet&quot;&gt;\r\n\t\t&lt;param name=&quot;mayscript&quot; value=&quot;yes&quot;&gt; \r\n\t\t&lt;param name=&quot;scriptable&quot; value=&quot;true&quot;&gt; \r\n\t&lt;\/object&gt; \r\n&lt;\/body&gt; \r\n&lt;\/html&gt;\r\n<\/pre>\n<\/p>\n<p>Oracle selbst empfiehlt zwar einen <a href=\"http:\/\/download.oracle.com\/javase\/1.5.0\/docs\/guide\/plugin\/developer_guide\/using_tags.html\">anderen Weg der Einbindung<\/a>. Allerdings funktioniert die <i>object<\/i>-Variante in allen relevanten Browsern und macht uns dehalb gl\u00fccklich &#8211; ohne diese miese Verschachtelung von verschiedenen Techniken, die uns da Oracle aufschw\u00e4tzen will. Eine andere Art der Einbindung ist die per &lt;applet&gt;-Tag, welcher allerdings deprecated ist.<\/p>\n<p>Sollte also eigentlich alles klar sein, was den Code betrifft. Wenn der Benutzer mit einer Java-Version < 1.41 daherkommt, wird er zum Update gebeten. Wir haben als Parameter <i>archive<\/i> unser .jar drinne, geben beim Parameter <i>code<\/i> unser Package samt Filename (ohne Extension) ein. <i>mayscript<\/i> und <i>scriptable<\/i> sind f\u00fcr sp\u00e4ter. Wir wollen das Applet ja irgendwann mal mit Javascript beackern. Wichtig ist die Angabe von Breite und H\u00f6he in genau dieser Notation, also nix mit CSS oder so. Sonst quittiert Firefox den Dienst und zeigt das Applet nicht an.<\/p>\n<p>So, war doch garnicht so schwer. Da erstrahlt das Applet im Browser! Allerdings geht halt noch nix, weil wir bisher noch keine Funktionalit\u00e4t implementiert haben. <\/p>\n<h2>Bring on the Code!<\/h2>\n<p>Okay, bauen wir uns erstmal eine Funktion, die einen <i>Vector<\/i> mit allen Dateinamen im aktuellen Verzeichnis zur\u00fcckgibt:<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\n\/\/return a vector containing the filenames in path\r\npublic Vector&lt;String&gt; getFileList()\r\n{\r\n    Vector&lt;String&gt; fileNames = new Vector&lt;String&gt;();\r\n\r\n    try\r\n    {\r\n        File dir = new File(path);\r\n        File[] fileList = dir.listFiles();\r\n        for (File f : fileList)\r\n        {\r\n            if (!f.isDirectory())\r\n                fileNames.add(f.getName());\r\n        }\r\n    }\r\n    \/\/silence exception in case of invalid path\r\n    catch (Exception ex) {}\r\n  \r\n    return fileNames;\r\n}\r\n<\/pre>\n<p>Weiterhin brauchen wir auch noch was, um eine Datei zu l\u00f6schen:<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npublic boolean deleteFile(String name)\r\n{\r\n    File f = new File(name);\r\n\r\n    if (!f.exists() || !f.canWrite() || f.isDirectory())\r\n        return false;\r\n\r\n    return f.delete();\r\n}\r\n<\/pre>\n<p>Geht ja gut voran. Weiter gehts mit der Methode, die dann sp\u00e4ter von Javascript aus angesteuert wird: <i>setPath<\/i>. <\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npublic void setPath(String newpath)\r\n{\r\n    newpath = newpath.replace(&quot;\\\\&quot;, &quot;\/&quot;);\r\n\r\n    if (!newpath.endsWith(&quot;\/&quot;))\r\n        newpath += &quot;\/&quot;;\r\n\r\n    this.path = newpath;\r\n    lblPath.setText(this.path);\r\n\r\n    AccessController.doPrivileged(new PrivilegedAction()\r\n    {\r\n        public Object run()\r\n        {\r\n            lstFiles.setListData(getFileList());\r\n            return null;\r\n        }\r\n    });\r\n}\r\n<\/pre>\n<p>Hier k\u00fcmmern wir uns drum, dass alle Backslashes zu Forward-Slashes gemacht werden und setzen den Pfad als Text unseres Labels. Au\u00dferdem k\u00fcmmern wir sich noch drum (jaja, kein guter Stil&#8230;), dass die Dateiliste neu gef\u00fcllt wird. Und zwar mit den Dateien im nun aktuellen Verzeichnis. Das abgedrehte Konstrukt um die wirklich relevante Zeile <i>lstFiles.setListData(getFileList());<\/i> ist n\u00f6tig, da das Applet sonst keinen Zugriff auf das Dateisystem des Benutzers h\u00e4tte. Hirn ausschalten und einfach so \u00fcbernehmen.<\/p>\n<p>Letztendlich sind wir damit schon so gut wie fertig. Alles was noch gebraucht wird, ist ein EventHandler f\u00fcr den L\u00f6schen-Knopf. Wenn also auf den L\u00f6schen-Button gedr\u00fcckt wird, sollen alle markierten Dateien in der Liste entfernt werden. Dazu erg\u00e4nzen wir im Konstruktor zum Button:<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\nbtnDelete.addActionListener(new ActionListener()\r\n{\r\n    public void actionPerformed(ActionEvent e)\r\n    {\r\n        Object selectedValues[] = lstFiles.getSelectedValues();\r\n        for (int i = 0; i &lt; selectedValues.length; i++)\r\n        {\r\n            deleteFile(path + selectedValues[i]);\r\n        }\r\n\r\n        lstFiles.setListData(getFileList());\r\n    }\r\n});\r\n<\/pre>\n<p>Paradoxerweise ist das L\u00f6schen von Dateien ohne diesen <i>AccessController<\/i> &#8211; Aufbau m\u00f6glich (Vermutung: Da die L\u00f6sch-Funktion nicht per Javascript getriggert wird, gelten daf\u00fcr andere Gesetze). Damit sind wir mit dem Java-Teil fertig &#8211; hier <b>das Endprodukt, unsere komplette Klasse<\/b>:<\/p>\n<pre data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">\r\npackage com.dav;\r\n\r\nimport java.awt.*;\r\nimport java.awt.event.*;\r\nimport javax.swing.*;\r\nimport java.io.File;\r\nimport java.security.*;\r\nimport java.util.Vector;\r\n\r\npublic class FileApplet extends JApplet\r\n{\r\n    private String path;\r\n\r\n    private JLabel lblPath;\r\n    private JList lstFiles;\r\n    private JButton btnDelete;\r\n\r\n    public FileApplet()\r\n    {\r\n        \/\/assign LayoutManager to panel\r\n        JPanel contentPane = (JPanel)this.getContentPane();\r\n        contentPane.setLayout(new BorderLayout(10, 10));\r\n\r\n        \/\/add Label for Path on Top\r\n        lblPath = new JLabel();\r\n        contentPane.add(lblPath, BorderLayout.NORTH);\r\n\r\n        \/\/add List with all files of path to center\r\n        lstFiles = new JList();\r\n        contentPane.add(new JScrollPane(lstFiles), BorderLayout.CENTER);\r\n\r\n        btnDelete = new JButton(&quot;L\u00f6schen&quot;);\r\n        \/\/add listener to button -&gt; delete files\r\n        btnDelete.addActionListener(new ActionListener()\r\n        {\r\n            public void actionPerformed(ActionEvent e)\r\n            {\r\n                Object selectedValues[] = lstFiles.getSelectedValues();\r\n                for (int i = 0; i &lt; selectedValues.length; i++)\r\n                {\r\n                    deleteFile(path + selectedValues[i]);\r\n                }\r\n\r\n                lstFiles.setListData(getFileList());\r\n            }\r\n        });\r\n        \/\/add button to bottom\r\n        contentPane.add(btnDelete, BorderLayout.SOUTH);\r\n\r\n        setPath(&quot;C:\/&quot;);\r\n    }\r\n\r\n    public void setPath(String newpath)\r\n    {\r\n        newpath = newpath.replace(&quot;\\\\&quot;, &quot;\/&quot;);\r\n\r\n        if (!newpath.endsWith(&quot;\/&quot;))\r\n            newpath += &quot;\/&quot;;\r\n\r\n        this.path = newpath;\r\n        lblPath.setText(this.path);\r\n\r\n        AccessController.doPrivileged(new PrivilegedAction()\r\n        {\r\n            public Object run()\r\n            {\r\n                lstFiles.setListData(getFileList());\r\n                return null;\r\n            }\r\n        });\r\n    }\r\n\r\n    \/\/return a vector containing the filenames in path\r\n    public Vector&lt;String&gt; getFileList()\r\n    {\r\n        Vector&lt;String&gt; fileNames = new Vector&lt;String&gt;();\r\n\r\n        try\r\n        {\r\n            File dir = new File(path);\r\n            File[] fileList = dir.listFiles();\r\n            for (File f : fileList)\r\n            {\r\n                if (!f.isDirectory())\r\n                    fileNames.add(f.getName());\r\n            }\r\n        }\r\n        catch (Exception ex) {}\r\n\r\n        return fileNames;\r\n    }\r\n\r\n    public boolean deleteFile(String name)\r\n    {\r\n        File f = new File(name);\r\n\r\n        if (!f.exists() || !f.canWrite() || f.isDirectory())\r\n            return false;\r\n\r\n        return f.delete();\r\n    }\r\n}\r\n<\/pre>\n<h2>Fertig! &#8230; oder?<\/h2>\n<p>Gut, dann erneut &#8222;build&#8220;. Jetzt erg\u00e4nzen wir die HTML-Datei noch um den notwendigen Javascript-Code, zum wechseln des Pfades im Applet. Dazu kommt in den &lt;body&gt;:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\nPfad: &lt;input type=&quot;text&quot; id=&quot;filepath&quot; value=&quot;C:\/&quot; \/&gt;\r\n&lt;input type=&quot;button&quot; id=&quot;ok&quot; value=&quot;ok&quot; \/&gt;\r\n<\/pre>\n<p>Und im &lt;head&gt; erg\u00e4nzen wir:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;script src=&quot;http:\/\/code.jquery.com\/jquery-1.5.min.js&quot;&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n$(document).ready(function()\r\n{\r\n\t$(&quot;#ok&quot;).click(function()\r\n\t{\r\n\t\tvar filepath = $(&quot;#filepath&quot;).val();\r\n\t\tdocument.jsap.setPath(filepath);\r\n\t});\r\n});\r\n&lt;\/script&gt;\r\n<\/pre>\n<p>Hier nun also der gesamte HTML-Code:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;!DOCTYPE html&gt;\r\n&lt;html&gt; \r\n&lt;head&gt; \r\n\t&lt;meta charset=&quot;utf8&quot; \/&gt;\r\n\t&lt;title&gt;File Javaapplet&lt;\/title&gt;\r\n\t&lt;script src=&quot;http:\/\/code.jquery.com\/jquery-1.5.min.js&quot;&gt;&lt;\/script&gt;\r\n\t&lt;script&gt;\r\n\t$(document).ready(function()\r\n\t{\r\n\t\t$(&quot;#ok&quot;).click(function()\r\n\t\t{\r\n\t\t\tvar filepath = $(&quot;#filepath&quot;).val();\r\n\t\t\tdocument.jsap.setPath(filepath);\r\n\t\t});\r\n\t});\r\n\t&lt;\/script&gt;\r\n&lt;\/head&gt; \r\n&lt;body&gt; \r\n\t&lt;object type=&quot;application\/x-java-applet;version=1.4.1&quot; name=&quot;jsap&quot; id=&quot;jsap&quot; width=&quot;400&quot; height=&quot;600&quot;&gt;\r\n\t\t&lt;param name=&quot;archive&quot; value=&quot;fileapplet.jar&quot;&gt; \r\n\t\t&lt;param name=&quot;code&quot; value=&quot;com.dav.FileApplet&quot;&gt;\r\n\t\t&lt;param name=&quot;mayscript&quot; value=&quot;yes&quot;&gt; \r\n\t\t&lt;param name=&quot;scriptable&quot; value=&quot;true&quot;&gt; \r\n\t&lt;\/object&gt; \r\n\r\n\t&lt;p&gt;\r\n\t\tPfad: &lt;input type=&quot;text&quot; id=&quot;filepath&quot; value=&quot;C:\/&quot; \/&gt;\r\n\t\t&lt;input type=&quot;button&quot; id=&quot;ok&quot; value=&quot;ok&quot; \/&gt;\r\n\t&lt;\/p&gt;\r\n\t\r\n&lt;\/body&gt; \r\n&lt;\/html&gt;\r\n<\/pre>\n<p>Verbl\u00fcffend einfach, wie die Javascript-Br\u00fccke zum Applet hergestellt wird, oder? Einfach <i>document.AppletName.Funktionsaufruf<\/i>. Das wars schon. Ehrlich.<\/p>\n<p><b>Okay, versuchen wirs mal.<\/b>  &#8230; Hm &#8230; Ern\u00fcchterung macht sich breit. Der Pfad im Label wechselt zwar, wie gew\u00fcnscht &#8211; blo\u00df warum klappt die Dateianzeige nicht? Die Antwortet lautet: <b>Signatur<\/b>.<\/p>\n<h2>Das Applet signieren<\/h2>\n<p>&#8222;Unkritische&#8220; Java-Applets werden (nat\u00fcrlich abh\u00e4ngig von der Sicherheitseinstellung im Browser) straight-away ausgef\u00fchrt. Ohne Benachrichtigung. Sobald wir aber kritische Bereiche anfassen (was wir mit dem Auflisten und L\u00f6schen von Dateien definitiv tuen), m\u00fcssen wir unser Applet signieren. Dazu gibt es zum einen fest in den Browsern verdrahtete Zertifizierungsstellen, bei denen man sich gegen Geb\u00fchr ein Zertifikat holen kann. Allerdings kann man auch den kostenlosen Weg w\u00e4hlen und das Applet selbst signieren. Das ist, was wir tun werden.<\/p>\n<ul>\n<li>Dazu eine Dos-Box aufgemacht (Start -> Ausf\u00fchren -> cmd) und zum Pfad eurer JDK-Installation ins <i>\/bin<\/i> &#8211; Verzeichnis gewechselt. Bei mir: <i>D:\\programme\\Java\\jdk1.6.0_22\\bin<\/i>.<\/li>\n<li>Jetzt kopiert ihre eure <i>fileapplet.jar<\/i> ins <i>\/bin<\/i>-Verzeichnis hinein und f\u00fchrt aus:\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">keytool.exe -genkey -keystore davidsKeystore -alias david<\/pre>\n<p>Ihr d\u00fcrft euren Vorname gerne einsetzen ;). Nach dem Absenden des Befehls werden ein paar Angaben von euch gefordert, u.a. ein Passwort.<\/li>\n<li>Der n\u00e4chste Befehl:\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">keytool -selfcert -alias david -keystore davidsKeystore<\/pre>\n<p>Wieder mit dem Passwort best\u00e4tigen.\n<\/li>\n<li>Und der letzte Befehl ist jetzt das eigentliche signieren:\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">jarsigner -keystore davidsKeystore fileapplet.jar david<\/pre>\n<\/li>\n<\/ul>\n<p>Damit ist euer Applet selfsigned. Jetzt muss erstmal die <i>java.exe<\/i> per Taskmanager gekillt werden, da eure alte, unsignierte .jar noch am laufen ist. Jetzt kopiert ihr die <i>fileapplet.jar<\/i> aus dem <i>\/bin<\/i> Ordner nun wieder nach <i>\/dist<\/i> zur\u00fcck, oder wo eben euer Projekt lebt. Nach dem Start der <i>index.html<\/i> erscheint nun hoffentlich:<\/p>\n<div id=\"attachment_508\" style=\"width: 544px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-warnung.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-508\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-warnung.png\" alt=\"Java Warnung\" title=\"Java Warnung\" width=\"534\" height=\"352\" class=\"size-full wp-image-508\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-warnung.png 534w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-warnung-300x197.png 300w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" \/><\/a><p id=\"caption-attachment-508\" class=\"wp-caption-text\">Java Warnung<\/p><\/div>\n<p>Nach dem Klick auf &#8222;Ausf\u00fchren&#8220; sollte nun endlich alles so klappen, wie gew\u00fcnscht. Checkt ihr &#8222;Inhalten dieses Urhebers immer vertrauen&#8220;, werdet ihr beim n\u00e4chsten mal nicht mehr genervt. <b>Fertig.<\/b><\/p>\n<h2>Abrechnung<\/h2>\n<p>Ich habe das Entwickeln von Applets als sehr schmerzvoll empfunden &#8211; unz\u00e4hlige Male musste ich java per Taskamager killen, den Browser neu starten und tempor\u00e4re Dateien leeren, um sicher zu sein, dass ich auch wirklich das aktuelle Ergebnis vor mir habe. Hinweisen sollte man noch auf die java-Konsole, die sich per Rechtsklick auf das java-Symbol im Systray starten l\u00e4sst. Dort werden Exceptions und Fehler untergebracht.<\/p>\n<div id=\"attachment_512\" style=\"width: 456px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-console.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-512\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-console.png\" alt=\"Java Konsole\" title=\"Java Konsole\" width=\"446\" height=\"394\" class=\"size-full wp-image-512\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-console.png 446w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/java-console-300x265.png 300w\" sizes=\"auto, (max-width: 446px) 100vw, 446px\" \/><\/a><p id=\"caption-attachment-512\" class=\"wp-caption-text\">Java Konsole<\/p><\/div>\n<h2>Alles zusammen<\/h2>\n<p><a href='https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/fileapplet.zip'>Alle Dateien zusammen herunterladen<\/a>. <b>Disclaimer:<\/b> Ich bin kein ausgewiesener Java-Experte und hatte mit Applets bisher nicht sonderlich viel am Hut. Nicht an Kritik z\u00f6gern, wenn ihr was besser wisst.<\/p>\n<h2>Bonus: Ein &#8222;vertrauensw\u00fcrdiges&#8220; Zertifikat wieder entfernen<\/h2>\n<p>Jetzt wo bekannt ist, dass nur ein fl\u00fcchtiger Klick auf &#8222;Ausf\u00fchren&#8220; genug sein kann um von einem Applet die komplette Platte geputzt zu bekommen, wollt ihr sicher mal nachschauen, wem ihr in der Vergangenheit so alles euer &#8222;Vertrauen&#8220; ausgeprochen habt ;). In der Systemsteuerung unter &#8222;Programme&#8220; den Eintrag <i>Java<\/i> w\u00e4hlen. Im Tab &#8222;Sicherheit&#8220; bei &#8222;Zertifikate&#8220; lassen sich Zertifikate wieder entfernen.<\/p>\n<div id=\"attachment_511\" style=\"width: 300px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/zertifikate.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-511\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/zertifikate-290x300.png\" alt=\"vertrauensw\u00fcrdige Zertifikate\" title=\"vertrauensw\u00fcrdige Zertifikate\" width=\"290\" height=\"300\" class=\"size-medium wp-image-511\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/zertifikate-290x300.png 290w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/zertifikate.png 592w\" sizes=\"auto, (max-width: 290px) 100vw, 290px\" \/><\/a><p id=\"caption-attachment-511\" class=\"wp-caption-text\">vertrauensw\u00fcrdige Zertifikate<\/p><\/div>\n<p>Das Entfernen des Zertifikats hat aber nur dann Wirkung, wenn die tempor\u00e4ren Dateien von Java geleert werden. Solang da noch eine als vertrauensw\u00fcrdig klassifizierte .jar rumliegt, greift das Entfernen des Zertifikats noch nicht.<\/p>\n<div id=\"attachment_510\" style=\"width: 243px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/temp.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-510\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/temp-233x300.png\" alt=\"tempor\u00e4re Dateien\" title=\"tempor\u00e4re Dateien\" width=\"233\" height=\"300\" class=\"size-medium wp-image-510\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/temp-233x300.png 233w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2011\/02\/temp.png 738w\" sizes=\"auto, (max-width: 233px) 100vw, 233px\" \/><\/a><p id=\"caption-attachment-510\" class=\"wp-caption-text\">tempor\u00e4re Dateien<\/p><\/div>\n<p>Im Reiter &#8222;Allgemein&#8220; unter bei &#8222;Tempor\u00e4re Internet-Dateien&#8220; auf &#8222;Anzeigen&#8220; und da aufr\u00e4umen. Auch der Browser cached eventuell selbst noch. <\/p>\n<p><h2>Further Reading<\/h2>\n<ul>\n<li><a href=\"http:\/\/de.wikipedia.org\/wiki\/Java-Applet\">Wikipedia Artikel zu Java-Applets<\/a> &#8211; Den Abschnitt &#8222;Appletprogrammierung&#8220; mal anschauen<\/a><\/li>\n<li><a href=\"http:\/\/download.oracle.com\/javase\/6\/docs\/technotes\/tools\/windows\/jarsigner.html\">Oracle Docs zum signieren von jars<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Wenn ich an Java Applets denke, ist damit immer ein verstaubtes Web 1.0 &#8211; Bild assoziiert, gepaart mit animierten gifs und anderen Schandtaten. Heutzutage haben die Applets ihre Nische gefunden und werden vor allem da benutzt, wo Javascript noch zu &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/java-applet-tutorial\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,3,13],"tags":[],"class_list":["post-504","post","type-post","status-publish","format-standard","hentry","category-javascript","category-webdev","category-java"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/504","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=504"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/504\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}