{"id":17593,"date":"2021-10-19T18:07:31","date_gmt":"2021-10-19T16:07:31","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=17593"},"modified":"2021-10-20T13:51:20","modified_gmt":"2021-10-20T11:51:20","slug":"web3j-maven-plugin","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=17593","title":{"rendered":"Smart-Contract Wrapper f\u00fcr Java mit web3j-maven-plugin erstellen"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-scaled.jpg\" alt=\"\" width=\"2560\" height=\"1919\" class=\"aligncenter size-full wp-image-17594\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-scaled.jpg 2560w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-300x225.jpg 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-1024x768.jpg 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-768x576.jpg 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-1536x1151.jpg 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/Smart-Contracts-2048x1535.jpg 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><br \/>\nEs muss ja nicht immer <a href=\"https:\/\/rinkeby.etherscan.io\/address\/0xeC7e0b267AA3AB723Ef4E1c7dD5380694fFaE2B0#code\" rel=\"noopener\" target=\"_blank\">remix<\/a> sein, um ein Smart-Contract zu compilieren. Es geht auch wie oben dargestellt mit einem Maven-Plugin (oder Gradle) um mit Ethereum-Netzwerk zu interagieren. Also wie k\u00f6nnen Solidity Smart Contracts kompiliert und daf\u00fcr eine Java-Wrapper-Klassen daf\u00fcr generiert werden?<\/p>\n<p>Wir nehmen als Beispiel mein bekannter Smart-Contract <strong>Gehirn.sol<\/strong> der den IQ auf der Blockchain festhalten kann und mit Solidity programmiert ist und speichern in in dem <strong>src\/main\/resources<\/strong> Verzeichnis. <\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/\/ SPDX-License-Identifier: MIT\r\n\r\npragma solidity ^0.6.0;\r\n\r\n\/**\r\n * @title Gehirn von Thomas Wenzlaff\r\n * @dev Mein Smart Contract mit solidity zum Speichern von IQ auf der Blockchain\r\n *\/\r\ncontract Gehirn {\r\n\r\n    uint256 iq;\r\n\r\n    constructor() public {\r\n        \/\/ Mittelwert des IQ setzen\r\n        iq = 100;\r\n    }\r\n\r\n    function setIQ(uint256 neuerIQ) public payable {\r\n        iq = neuerIQ;\r\n    }\r\n\r\n    function getIQ() public view returns (uint256) {\r\n        return iq;\r\n    }\r\n\r\n    function getBedeutung() public view returns (string memory) {\r\n        if (iq &lt;= 40) return \"Keine Aussagekraft\";\r\n        if (iq &gt;= 41 &amp;&amp; iq &lt;= 70) return \"Weit unterdurchschnittlich \u2013 Geistige Behinderung\";\r\n        if (iq &gt;= 71 &amp;&amp; iq &lt;= 79) return \"unterdurchschnittlich\";\r\n        if (iq &gt;= 80 &amp;&amp; iq &lt;= 89) return \"etwas unterdurchschnittlich\";\r\n        if (iq &gt;= 90 &amp;&amp; iq &lt;=109) return \"Durchschnitt\";\r\n        if (iq &gt;= 110 &amp;&amp; iq &lt;=119) return \"hoch\";\r\n        if (iq &gt;= 120 &amp;&amp; iq &lt;= 129) return \"sehr hoch\";\r\n        if (iq &gt;= 130 &amp;&amp; iq &lt;= 159) return \"hochbegabt\";\r\n        if (iq &gt; 160) return \"Keine Aussagekraft\";\r\n    }\r\n}\r\n<\/pre>\n<p>Das Plugin wird mit <strong>mvn web3j:generate-sources <\/strong>gestartet und wie folgt in der <strong>pom.xml<\/strong> eingebunden: <!--more--><\/p>\n<pre class=\"lang:xhtml decode:true \" >\r\n\r\n&lt;!-- Aufruf: web3j:generate-sources--&gt;\r\n\t\t\t&lt;plugin&gt;\r\n\t\t\t\t&lt;groupId&gt;org.web3j&lt;\/groupId&gt;\r\n\t\t\t\t&lt;artifactId&gt;web3j-maven-plugin&lt;\/artifactId&gt;\r\n\t\t\t\t&lt;version&gt;4.8.7&lt;\/version&gt;\r\n\t\t\t\t&lt;configuration&gt;\r\n\t\t\t\t\t&lt;packageName&gt;de.wenzlaff.blockchain.model&lt;\/packageName&gt;\r\n\t\t\t\t\t&lt;sourceDestination&gt;src\/main\/java\/generated&lt;\/sourceDestination&gt;\r\n\t\t\t\t\t&lt;nativeJavaType&gt;true&lt;\/nativeJavaType&gt;\r\n\t\t\t\t\t&lt;outputFormat&gt;java,bin,abi&lt;\/outputFormat&gt;\r\n\t\t\t\t\t&lt;soliditySourceFiles&gt;\r\n\t\t\t\t\t\t&lt;directory&gt;src\/main\/resources&lt;\/directory&gt;\r\n\t\t\t\t\t\t&lt;includes&gt;\r\n\t\t\t\t\t\t\t&lt;include&gt;**\/*.sol&lt;\/include&gt;\r\n\t\t\t\t\t\t&lt;\/includes&gt;\r\n\t\t\t\t\t&lt;\/soliditySourceFiles&gt;\r\n\t\t\t\t\t&lt;outputDirectory&gt;\r\n\t\t\t            &lt;java&gt;src\/main\/java&lt;\/java&gt;\r\n\t\t\t            &lt;bin&gt;src\/bin\/generated&lt;\/bin&gt;\r\n\t\t\t            &lt;abi&gt;src\/abi\/generated&lt;\/abi&gt;\r\n\t\t\t        &lt;\/outputDirectory&gt;\r\n\t\t\t\t\t&lt;contract&gt;\r\n\t\t\t\t\t\t&lt;includes&gt;\r\n\t\t\t\t\t\t\t&lt;include&gt;&lt;\/include&gt;\r\n\t\t\t\t\t\t&lt;\/includes&gt;\r\n\t\t\t\t\t\t&lt;excludes&gt;\r\n\t\t\t\t\t\t\t&lt;exclude&gt;&lt;\/exclude&gt;\r\n\t\t\t\t\t\t&lt;\/excludes&gt;\r\n\t\t\t\t\t&lt;\/contract&gt;\r\n\t\t\t\t\t&lt;pathPrefixes&gt;\r\n\t\t\t\t\t\t&lt;pathPrefix&gt;dep=..\/dependencies&lt;\/pathPrefix&gt;\r\n\t\t\t\t\t&lt;\/pathPrefixes&gt;\r\n\t\t\t\t&lt;\/configuration&gt;\r\n\t\t\t&lt;\/plugin&gt;\r\n\t\t&lt;\/plugins&gt;<\/pre>\n<p>Nach dem generieren haben wir dann das generierte ABI im Json Format in der Datei <strong>Gehirn.json<\/strong>:<\/p>\n<pre class=\"lang:yaml decode:true \" >[\r\n\t{\r\n\t\t\"inputs\": [],\r\n\t\t\"stateMutability\": \"nonpayable\",\r\n\t\t\"type\": \"constructor\"\r\n\t},\r\n\t{\r\n\t\t\"inputs\": [],\r\n\t\t\"name\": \"getBedeutung\",\r\n\t\t\"outputs\": [\r\n\t\t\t{\r\n\t\t\t\t\"internalType\": \"string\",\r\n\t\t\t\t\"name\": \"\",\r\n\t\t\t\t\"type\": \"string\"\r\n\t\t\t}\r\n\t\t],\r\n\t\t\"stateMutability\": \"view\",\r\n\t\t\"type\": \"function\"\r\n\t},\r\n\t{\r\n\t\t\"inputs\": [],\r\n\t\t\"name\": \"getIQ\",\r\n\t\t\"outputs\": [\r\n\t\t\t{\r\n\t\t\t\t\"internalType\": \"uint256\",\r\n\t\t\t\t\"name\": \"\",\r\n\t\t\t\t\"type\": \"uint256\"\r\n\t\t\t}\r\n\t\t],\r\n\t\t\"stateMutability\": \"view\",\r\n\t\t\"type\": \"function\"\r\n\t},\r\n\t{\r\n\t\t\"inputs\": [\r\n\t\t\t{\r\n\t\t\t\t\"internalType\": \"uint256\",\r\n\t\t\t\t\"name\": \"neuerIQ\",\r\n\t\t\t\t\"type\": \"uint256\"\r\n\t\t\t}\r\n\t\t],\r\n\t\t\"name\": \"setIQ\",\r\n\t\t\"outputs\": [],\r\n\t\t\"stateMutability\": \"payable\",\r\n\t\t\"type\": \"function\"\r\n\t}\r\n]<\/pre>\n<p>Und den bin\u00e4ren Code in der <strong>Gehirn.bin<\/strong> der auch in dem generierten Java-Wrapper als public Konstante <strong>BINARY<\/strong> vorhanden ist:<\/p>\n<pre class=\"minimize:true lang:default decode:true \" >608060405234801561001057600080fd5b5060646000556103d3806100256000396000f3fe6080604052600436106100345760003560e01c806303da5f75146100395780634035548114610060578063cfb996da1461007f575b600080fd5b34801561004557600080fd5b5061004e610109565b60408051918252519081900360200190f35b61007d6004803603602081101561007657600080fd5b5035610110565b005b34801561008b57600080fd5b50610094610115565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ce5781810151838201526020016100b6565b50505050905090810190601f1680156100fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000545b90565b600055565b6060602860005411610150575060408051808201909152601281527112d95a5b9948105d5cdcd859d95adc98599d60721b602082015261010d565b6029600054101580156101665750604660005411155b1561018b5760405180606001604052806033815260200161036b60339139905061010d565b6047600054101580156101a15750604f60005411155b156101d857506040805180820190915260158152740eadce8cae4c8eae4c6d0e6c6d0dcd2e8e8d8d2c6d605b1b602082015261010d565b6050600054101580156101ee5750605960005411155b1561022d575060408051808201909152601b81527f657477617320756e74657264757263687363686e6974746c6963680000000000602082015261010d565b605a600054101580156102435750606d60005411155b15610271575060408051808201909152600c81526b111d5c98da1cd8da1b9a5d1d60a21b602082015261010d565b606e600054101580156102875750607760005411155b156102ad57506040805180820190915260048152630d0dec6d60e31b602082015261010d565b6078600054101580156102c35750608160005411155b156102ee57506040805180820190915260098152680e6cad0e440d0dec6d60bb1b602082015261010d565b6082600054101580156103045750609f60005411155b15610330575060408051808201909152600a8152691a1bd8da189959d8589d60b21b602082015261010d565b60a0600054111561010d575060408051808201909152601281527112d95a5b9948105d5cdcd859d95adc98599d60721b602082015261010d56fe5765697420756e74657264757263687363686e6974746c69636820e2809320476569737469676520426568696e646572756e67a2646970667358221220e47f5ca58cc85c126b32581ede151a0854e01cddae7e74c48381e24fa57c5ed964736f6c634300060c0033<\/pre>\n<p>Hier der <strong>Gehirn.java<\/strong> Wrapper, der f\u00fcr weitere Anwendungsf\u00e4lle verwendet werden kann:<\/p>\n<pre class=\"lang:java decode:true \" >package de.wenzlaff.blockchain.model;\r\n\r\nimport java.math.BigInteger;\r\nimport java.util.Arrays;\r\nimport java.util.Collections;\r\nimport org.web3j.abi.TypeReference;\r\nimport org.web3j.abi.datatypes.Function;\r\nimport org.web3j.abi.datatypes.Type;\r\nimport org.web3j.abi.datatypes.Utf8String;\r\nimport org.web3j.abi.datatypes.generated.Uint256;\r\nimport org.web3j.crypto.Credentials;\r\nimport org.web3j.protocol.Web3j;\r\nimport org.web3j.protocol.core.RemoteCall;\r\nimport org.web3j.protocol.core.RemoteFunctionCall;\r\nimport org.web3j.protocol.core.methods.response.TransactionReceipt;\r\nimport org.web3j.tx.Contract;\r\nimport org.web3j.tx.TransactionManager;\r\nimport org.web3j.tx.gas.ContractGasProvider;\r\n\r\n\/**\r\n * &lt;p&gt;Auto generated code.\r\n * &lt;p&gt;&lt;strong&gt;Do not modify!&lt;\/strong&gt;\r\n * &lt;p&gt;Please use the &lt;a href=\"https:\/\/docs.web3j.io\/command_line.html\"&gt;web3j command line tools&lt;\/a&gt;,\r\n * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the \r\n * &lt;a href=\"https:\/\/github.com\/web3j\/web3j\/tree\/master\/codegen\"&gt;codegen module&lt;\/a&gt; to update.\r\n *\r\n * &lt;p&gt;Generated with web3j version 4.8.7.\r\n *\/\r\n@SuppressWarnings(\"rawtypes\")\r\npublic class Gehirn extends Contract {\r\n    public static final String BINARY = \"608060405234801561001057600080fd5b5060646000556103d3806100256000396000f3fe6080604052600436106100345760003560e01c806303da5f75146100395780634035548114610060578063cfb996da1461007f575b600080fd5b34801561004557600080fd5b5061004e610109565b60408051918252519081900360200190f35b61007d6004803603602081101561007657600080fd5b5035610110565b005b34801561008b57600080fd5b50610094610115565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100ce5781810151838201526020016100b6565b50505050905090810190601f1680156100fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000545b90565b600055565b6060602860005411610150575060408051808201909152601281527112d95a5b9948105d5cdcd859d95adc98599d60721b602082015261010d565b6029600054101580156101665750604660005411155b1561018b5760405180606001604052806033815260200161036b60339139905061010d565b6047600054101580156101a15750604f60005411155b156101d857506040805180820190915260158152740eadce8cae4c8eae4c6d0e6c6d0dcd2e8e8d8d2c6d605b1b602082015261010d565b6050600054101580156101ee5750605960005411155b1561022d575060408051808201909152601b81527f657477617320756e74657264757263687363686e6974746c6963680000000000602082015261010d565b605a600054101580156102435750606d60005411155b15610271575060408051808201909152600c81526b111d5c98da1cd8da1b9a5d1d60a21b602082015261010d565b606e600054101580156102875750607760005411155b156102ad57506040805180820190915260048152630d0dec6d60e31b602082015261010d565b6078600054101580156102c35750608160005411155b156102ee57506040805180820190915260098152680e6cad0e440d0dec6d60bb1b602082015261010d565b6082600054101580156103045750609f60005411155b15610330575060408051808201909152600a8152691a1bd8da189959d8589d60b21b602082015261010d565b60a0600054111561010d575060408051808201909152601281527112d95a5b9948105d5cdcd859d95adc98599d60721b602082015261010d56fe5765697420756e74657264757263687363686e6974746c69636820e2809320476569737469676520426568696e646572756e67a2646970667358221220e47f5ca58cc85c126b32581ede151a0854e01cddae7e74c48381e24fa57c5ed964736f6c634300060c0033\";\r\n\r\n    public static final String FUNC_GETBEDEUTUNG = \"getBedeutung\";\r\n\r\n    public static final String FUNC_GETIQ = \"getIQ\";\r\n\r\n    public static final String FUNC_SETIQ = \"setIQ\";\r\n\r\n    @Deprecated\r\n    protected Gehirn(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {\r\n        super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);\r\n    }\r\n\r\n    protected Gehirn(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {\r\n        super(BINARY, contractAddress, web3j, credentials, contractGasProvider);\r\n    }\r\n\r\n    @Deprecated\r\n    protected Gehirn(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {\r\n        super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);\r\n    }\r\n\r\n    protected Gehirn(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {\r\n        super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);\r\n    }\r\n\r\n    public RemoteFunctionCall&lt;String&gt; getBedeutung() {\r\n        final Function function = new Function(FUNC_GETBEDEUTUNG, \r\n                Arrays.&lt;Type&gt;asList(), \r\n                Arrays.&lt;TypeReference&lt;?&gt;&gt;asList(new TypeReference&lt;Utf8String&gt;() {}));\r\n        return executeRemoteCallSingleValueReturn(function, String.class);\r\n    }\r\n\r\n    public RemoteFunctionCall&lt;BigInteger&gt; getIQ() {\r\n        final Function function = new Function(FUNC_GETIQ, \r\n                Arrays.&lt;Type&gt;asList(), \r\n                Arrays.&lt;TypeReference&lt;?&gt;&gt;asList(new TypeReference&lt;Uint256&gt;() {}));\r\n        return executeRemoteCallSingleValueReturn(function, BigInteger.class);\r\n    }\r\n\r\n    public RemoteFunctionCall&lt;TransactionReceipt&gt; setIQ(BigInteger neuerIQ) {\r\n        final Function function = new Function(\r\n                FUNC_SETIQ, \r\n                Arrays.&lt;Type&gt;asList(new org.web3j.abi.datatypes.generated.Uint256(neuerIQ)), \r\n                Collections.&lt;TypeReference&lt;?&gt;&gt;emptyList());\r\n        return executeRemoteCallTransaction(function);\r\n    }\r\n\r\n    @Deprecated\r\n    public static Gehirn load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {\r\n        return new Gehirn(contractAddress, web3j, credentials, gasPrice, gasLimit);\r\n    }\r\n\r\n    @Deprecated\r\n    public static Gehirn load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {\r\n        return new Gehirn(contractAddress, web3j, transactionManager, gasPrice, gasLimit);\r\n    }\r\n\r\n    public static Gehirn load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {\r\n        return new Gehirn(contractAddress, web3j, credentials, contractGasProvider);\r\n    }\r\n\r\n    public static Gehirn load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {\r\n        return new Gehirn(contractAddress, web3j, transactionManager, contractGasProvider);\r\n    }\r\n\r\n    public static RemoteCall&lt;Gehirn&gt; deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {\r\n        return deployRemoteCall(Gehirn.class, web3j, credentials, contractGasProvider, BINARY, \"\");\r\n    }\r\n\r\n    public static RemoteCall&lt;Gehirn&gt; deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {\r\n        return deployRemoteCall(Gehirn.class, web3j, transactionManager, contractGasProvider, BINARY, \"\");\r\n    }\r\n\r\n    @Deprecated\r\n    public static RemoteCall&lt;Gehirn&gt; deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {\r\n        return deployRemoteCall(Gehirn.class, web3j, credentials, gasPrice, gasLimit, BINARY, \"\");\r\n    }\r\n\r\n    @Deprecated\r\n    public static RemoteCall&lt;Gehirn&gt; deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {\r\n        return deployRemoteCall(Gehirn.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, \"\");\r\n    }\r\n}\r\n<\/pre>\n<p>Als UML:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/wenzlaff.de-2021-10-20-um-13.48.25.png\" alt=\"\" width=\"964\" height=\"716\" class=\"aligncenter size-full wp-image-17602\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/wenzlaff.de-2021-10-20-um-13.48.25.png 964w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/wenzlaff.de-2021-10-20-um-13.48.25-300x223.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2021\/10\/wenzlaff.de-2021-10-20-um-13.48.25-768x570.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p>Weitere Anwendungsf\u00e4lle in weiteren Teilen hier auf dem Blog. <a href=\"https:\/\/rinkeby.etherscan.io\/address\/0xeC7e0b267AA3AB723Ef4E1c7dD5380694fFaE2B0#code\" rel=\"noopener\" target=\"_blank\">Hier<\/a> liegt der Smart-Contract.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es muss ja nicht immer remix sein, um ein Smart-Contract zu compilieren. Es geht auch wie oben dargestellt mit einem Maven-Plugin (oder Gradle) um mit Ethereum-Netzwerk zu interagieren. Also wie k\u00f6nnen Solidity Smart Contracts kompiliert und daf\u00fcr eine Java-Wrapper-Klassen daf\u00fcr generiert werden? Wir nehmen als Beispiel mein bekannter Smart-Contract Gehirn.sol der den IQ auf der &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=17593\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eSmart-Contract Wrapper f\u00fcr Java mit web3j-maven-plugin erstellen\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[220,5027,3161,4606,5037,5,3897,3163,79,5004],"tags":[3496,4597,5049,4992,5045,942,66,293,5046,5006,2180,5048,5047],"class_list":["post-17593","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-blockchain","category-build","category-crypto","category-ethereum","category-java","category-java-programmierung","category-maven","category-programmierung","category-solidity","tag-blockchain","tag-crypto","tag-etc","tag-ethereum","tag-gas","tag-gehirn","tag-maven","tag-plugin","tag-provider","tag-smart-contract","tag-uml","tag-web3j","tag-web3j-maven-plugin"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/17593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17593"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/17593\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17593"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}