{"id":348,"date":"2024-04-19T20:21:39","date_gmt":"2024-04-19T19:21:39","guid":{"rendered":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=348"},"modified":"2024-06-01T20:24:06","modified_gmt":"2024-06-01T19:24:06","slug":"ssh-verbindungen-in-java-anwendungen-mit-sshj","status":"publish","type":"post","link":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/?p=348","title":{"rendered":"SSH-Verbindungen in Java-Anwendungen mit SSHJ"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\">Einf\u00fchrung<\/h3>\n\n\n\n<p>SSHJ ist eine Java-Bibliothek, die eine einfache und leistungsstarke API zur Verwaltung von SSH-Verbindungen bietet. Sie wird h\u00e4ufig verwendet, um sichere Kommunikation zwischen verschiedenen Servern oder zwischen einem Client und einem Server zu erm\u00f6glichen. In diesem Artikel werden wir einen detaillierten \u00dcberblick \u00fcber die Nutzung von SSHJ in Java geben, einschlie\u00dflich Installation, grundlegender Konfiguration und erweiterter Nutzungsm\u00f6glichkeiten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installation und Einrichtung<\/h3>\n\n\n\n<p>Bevor wir SSHJ verwenden k\u00f6nnen, m\u00fcssen wir es in unser Projekt einbinden. SSHJ kann einfach \u00fcber Maven oder Gradle hinzugef\u00fcgt werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Maven<\/h4>\n\n\n\n<p>Um SSHJ mit Maven zu verwenden, f\u00fcgen Sie die folgende Abh\u00e4ngigkeit zu Ihrer <code>pom.xml<\/code> hinzu:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>com.hierynomus<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>sshj<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version<\/span>&gt;<\/span>0.31.0<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">version<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Gradle<\/h4>\n\n\n\n<p>F\u00fcr Gradle f\u00fcgen Sie die Abh\u00e4ngigkeit zu Ihrem <code>build.gradle<\/code> hinzu:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">dependencies {\n    implementation <span class=\"hljs-string\">'com.hierynomus:sshj:0.31.0'<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Grundlegende Nutzung<\/h3>\n\n\n\n<p>Nachdem SSHJ erfolgreich in unser Projekt eingebunden wurde, k\u00f6nnen wir mit der Implementierung beginnen. Der erste Schritt besteht darin, eine Verbindung zu einem SSH-Server herzustellen.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Verbindung herstellen<\/h4>\n\n\n\n<p>Hier ist ein einfaches Beispiel, wie man eine SSH-Verbindung zu einem Server herstellt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.SSHClient;\n<span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.transport.verification.PromiscuousVerifier;\n\n<span class=\"hljs-keyword\">import<\/span> java.io.IOException;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SSHExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        SSHClient ssh = <span class=\"hljs-keyword\">new<\/span> SSHClient();\n        ssh.addHostKeyVerifier(<span class=\"hljs-keyword\">new<\/span> PromiscuousVerifier());\n\n        <span class=\"hljs-keyword\">try<\/span> {\n            ssh.connect(<span class=\"hljs-string\">\"hostname\"<\/span>, <span class=\"hljs-number\">22<\/span>);\n            ssh.authPassword(<span class=\"hljs-string\">\"username\"<\/span>, <span class=\"hljs-string\">\"password\"<\/span>);\n            System.out.println(<span class=\"hljs-string\">\"Verbindung erfolgreich hergestellt!\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n            e.printStackTrace();\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            <span class=\"hljs-keyword\">try<\/span> {\n                ssh.disconnect();\n            } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird eine Verbindung zu einem SSH-Server hergestellt, der unter <code>hostname<\/code> l\u00e4uft. Der Hostname kann entweder eine IP-Adresse oder ein DNS-Name sein. Der <code>PromiscuousVerifier<\/code> wird verwendet, um alle Host-Schl\u00fcssel zu akzeptieren, was in einer Produktionsumgebung durch einen sichereren Verifizierungsmechanismus ersetzt werden sollte.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Befehle ausf\u00fchren<\/h4>\n\n\n\n<p>Nachdem die Verbindung hergestellt ist, k\u00f6nnen wir Befehle auf dem Remote-Server ausf\u00fchren. Hier ist ein Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.connection.channel.direct.Session;\n<span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.connection.channel.direct.Session.Command;\n\n<span class=\"hljs-keyword\">import<\/span> java.io.BufferedReader;\n<span class=\"hljs-keyword\">import<\/span> java.io.InputStreamReader;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SSHCommandExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        SSHClient ssh = <span class=\"hljs-keyword\">new<\/span> SSHClient();\n        ssh.addHostKeyVerifier(<span class=\"hljs-keyword\">new<\/span> PromiscuousVerifier());\n\n        <span class=\"hljs-keyword\">try<\/span> {\n            ssh.connect(<span class=\"hljs-string\">\"hostname\"<\/span>, <span class=\"hljs-number\">22<\/span>);\n            ssh.authPassword(<span class=\"hljs-string\">\"username\"<\/span>, <span class=\"hljs-string\">\"password\"<\/span>);\n\n            Session session = ssh.startSession();\n            Command cmd = session.exec(<span class=\"hljs-string\">\"ls -l\"<\/span>);\n\n            BufferedReader reader = <span class=\"hljs-keyword\">new<\/span> BufferedReader(<span class=\"hljs-keyword\">new<\/span> InputStreamReader(cmd.getInputStream()));\n            <span class=\"hljs-built_in\">String<\/span> line;\n            <span class=\"hljs-keyword\">while<\/span> ((line = reader.readLine()) != <span class=\"hljs-literal\">null<\/span>) {\n                System.out.println(line);\n            }\n\n            cmd.join();\n            session.close();\n        } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n            e.printStackTrace();\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            <span class=\"hljs-keyword\">try<\/span> {\n                ssh.disconnect();\n            } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel f\u00fchren wir den Befehl <code>ls -l<\/code> auf dem Remote-Server aus und geben die Ausgabe auf der Konsole aus.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dateitransfer<\/h3>\n\n\n\n<p>SSHJ unterst\u00fctzt auch den sicheren Transfer von Dateien mittels SCP (Secure Copy Protocol). Hier ist ein Beispiel, wie man eine Datei vom lokalen System auf einen Remote-Server hochl\u00e4dt:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.sftp.SFTPClient;\n\n<span class=\"hljs-keyword\">import<\/span> java.io.File;\n<span class=\"hljs-keyword\">import<\/span> java.io.IOException;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">SFTPExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        SSHClient ssh = <span class=\"hljs-keyword\">new<\/span> SSHClient();\n        ssh.addHostKeyVerifier(<span class=\"hljs-keyword\">new<\/span> PromiscuousVerifier());\n\n        <span class=\"hljs-keyword\">try<\/span> {\n            ssh.connect(<span class=\"hljs-string\">\"hostname\"<\/span>, <span class=\"hljs-number\">22<\/span>);\n            ssh.authPassword(<span class=\"hljs-string\">\"username\"<\/span>, <span class=\"hljs-string\">\"password\"<\/span>);\n\n            SFTPClient sftp = ssh.newSFTPClient();\n            sftp.put(<span class=\"hljs-keyword\">new<\/span> FileSystemFile(<span class=\"hljs-keyword\">new<\/span> File(<span class=\"hljs-string\">\"localfile.txt\"<\/span>)), <span class=\"hljs-string\">\"remotefile.txt\"<\/span>);\n            sftp.close();\n\n            System.out.println(<span class=\"hljs-string\">\"Datei erfolgreich hochgeladen!\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n            e.printStackTrace();\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            <span class=\"hljs-keyword\">try<\/span> {\n                ssh.disconnect();\n            } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird die Datei <code>localfile.txt<\/code> vom lokalen Dateisystem auf den Remote-Server hochgeladen und als <code>remotefile.txt<\/code> gespeichert.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Erweiterte Nutzung<\/h3>\n\n\n\n<p>Neben den grundlegenden Funktionen bietet SSHJ auch erweiterte Funktionen wie die Authentifizierung mittels Public Key, Portweiterleitung und die Verwendung von Agenten f\u00fcr die Schl\u00fcsselverwaltung.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Authentifizierung mittels Public Key<\/h4>\n\n\n\n<p>Die Authentifizierung mittels Public Key ist sicherer als die Verwendung von Passw\u00f6rtern. Hier ist ein Beispiel, wie man diese Methode implementiert:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> net.schmizz.sshj.userauth.keyprovider.KeyProvider;\n\npublic <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">PublicKeyAuthExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        SSHClient ssh = <span class=\"hljs-keyword\">new<\/span> SSHClient();\n        ssh.addHostKeyVerifier(<span class=\"hljs-keyword\">new<\/span> PromiscuousVerifier());\n\n        <span class=\"hljs-keyword\">try<\/span> {\n            ssh.connect(<span class=\"hljs-string\">\"hostname\"<\/span>, <span class=\"hljs-number\">22<\/span>);\n            KeyProvider keys = ssh.loadKeys(<span class=\"hljs-string\">\"path\/to\/private_key\"<\/span>);\n            ssh.authPublickey(<span class=\"hljs-string\">\"username\"<\/span>, keys);\n\n            System.out.println(<span class=\"hljs-string\">\"Authentifizierung erfolgreich!\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n            e.printStackTrace();\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            <span class=\"hljs-keyword\">try<\/span> {\n                ssh.disconnect();\n            } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird der private Schl\u00fcssel zur Authentifizierung verwendet. Stellen Sie sicher, dass der private Schl\u00fcssel sicher gespeichert und gesch\u00fctzt ist.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Portweiterleitung<\/h4>\n\n\n\n<p>SSHJ unterst\u00fctzt auch die Weiterleitung von Ports. Hier ist ein Beispiel f\u00fcr die lokale Portweiterleitung:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">public <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">PortForwardingExample<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> main(<span class=\"hljs-built_in\">String<\/span>&#91;] args) {\n        SSHClient ssh = <span class=\"hljs-keyword\">new<\/span> SSHClient();\n        ssh.addHostKeyVerifier(<span class=\"hljs-keyword\">new<\/span> PromiscuousVerifier());\n\n        <span class=\"hljs-keyword\">try<\/span> {\n            ssh.connect(<span class=\"hljs-string\">\"hostname\"<\/span>, <span class=\"hljs-number\">22<\/span>);\n            ssh.authPassword(<span class=\"hljs-string\">\"username\"<\/span>, <span class=\"hljs-string\">\"password\"<\/span>);\n\n            ssh.newLocalPortForwarder(<span class=\"hljs-keyword\">new<\/span> LocalPortForwarder.Parameters(<span class=\"hljs-string\">\"localhost\"<\/span>, <span class=\"hljs-number\">9090<\/span>, <span class=\"hljs-string\">\"remotehost\"<\/span>, <span class=\"hljs-number\">80<\/span>)).listen();\n\n            System.out.println(<span class=\"hljs-string\">\"Portweiterleitung eingerichtet!\"<\/span>);\n        } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n            e.printStackTrace();\n        } <span class=\"hljs-keyword\">finally<\/span> {\n            <span class=\"hljs-keyword\">try<\/span> {\n                ssh.disconnect();\n            } <span class=\"hljs-keyword\">catch<\/span> (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In diesem Beispiel wird der lokale Port 9090 mit dem Remote-Host <code>remotehost<\/code> auf Port 80 weitergeleitet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fazit<\/h3>\n\n\n\n<p>SSHJ ist eine m\u00e4chtige und flexible Bibliothek f\u00fcr die Verwaltung von SSH-Verbindungen in Java. Es bietet eine Vielzahl von Funktionen, die von grundlegenden Verbindungen und Befehlsausf\u00fchrungen bis hin zu erweiterten Funktionen wie Public Key-Authentifizierung und Portweiterleitung reichen. Durch die Nutzung von SSHJ k\u00f6nnen Entwickler sichere und robuste Anwendungen erstellen, die mit Remote-Servern interagieren.<\/p>\n\n\n\n<p>Mit der richtigen Konfiguration und Implementierung k\u00f6nnen Sie SSHJ effektiv nutzen, um die Sicherheit und Effizienz Ihrer Java-Anwendungen zu verbessern. Wir hoffen, dass dieser Artikel Ihnen einen guten \u00dcberblick und eine solide Grundlage f\u00fcr die Nutzung von SSHJ bietet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Einf\u00fchrung SSHJ ist eine Java-Bibliothek, die eine einfache und leistungsstarke API zur Verwaltung von SSH-Verbindungen bietet. Sie wird h\u00e4ufig verwendet, um sichere Kommunikation zwischen verschiedenen Servern oder zwischen einem Client und einem Server zu erm\u00f6glichen. In diesem Artikel werden wir einen detaillierten \u00dcberblick \u00fcber die Nutzung von SSHJ in Java geben, einschlie\u00dflich Installation, grundlegender Konfiguration [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-348","post","type-post","status-publish","format-standard","hentry","category-plain_java"],"_links":{"self":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/348","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=348"}],"version-history":[{"count":1,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/348\/revisions"}],"predecessor-version":[{"id":349,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=\/wp\/v2\/posts\/348\/revisions\/349"}],"wp:attachment":[{"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=348"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=348"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xn--javaeinfacherklrt-4qb.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=348"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}