{"id":71649,"date":"2017-12-27T10:00:33","date_gmt":"2017-12-27T08:00:33","guid":{"rendered":"https:\/\/www.javacodegeeks.com\/?p=71649"},"modified":"2017-12-21T14:24:26","modified_gmt":"2017-12-21T12:24:26","slug":"fatjars-thinwars-openliberty-cool","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html","title":{"rendered":"Fatjars, Thinwars and why OpenLiberty is cool"},"content":{"rendered":"<h2>Fatjars<\/h2>\n<p>Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do:<\/p>\n<pre class=\"brush:bash\">java -jar myapp.jar<\/pre>\n<p>and off you go. No Application server. No classpath.<\/p>\n<p>This approach has been popularised by the microservices architectural style and frameworks like <a href=\"https:\/\/projects.spring.io\/spring-boot\/\">Springboot<\/a>.<\/p>\n<p><em>\u201cIn short, the <a href=\"https:\/\/martinfowler.com\/articles\/microservices.html\">microservice architectural style<\/a> is an approach to developing a <strong>single application<\/strong> as a suite of <strong>small services<\/strong>, each running in its <strong>own process<\/strong> and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and <strong>independently deployable<\/strong> by fully automated deployment machinery\u201d<\/em>.<\/p>\n<p>Having a bunch of executable jar files tick all the boxes above.<\/p>\n<h2>Java EE<\/h2>\n<p>The fatjar concept has also been available in Java EE for a while now. All the lightweight application servers have a \u201cMicro\u201d option:<\/p>\n<ul>\n<li><a href=\"http:\/\/wildfly-swarm.io\/\">WildFly Swarm<\/a><\/li>\n<li><a href=\"https:\/\/www.payara.fish\/payara_micro\">Payara Micro<\/a><\/li>\n<li><a href=\"http:\/\/openejb.apache.org\/\">TomEE<\/a><\/li>\n<li><a href=\"https:\/\/ee.kumuluz.com\/\">KumuluzEE<\/a><\/li>\n<li><a href=\"http:\/\/openwebbeans.apache.org\/meecrowave\/index.html\">Meecrowave<\/a><\/li>\n<\/ul>\n<p>There are many pros to having a fatjar deployment. However, there are some cons as well.<\/p>\n<ul>\n<li>You make this choice at development time (and it\u2019s actually a deployment time choice). I like to separate my development model from my deployment model.<\/li>\n<li>This gives you a sub-optimal development cycle. You need to build a fatjar, then stop the previous version, most likely with a kill, then do a start again. The turnaround from \u201ccode change\u201d to \u201ccode running\u201d gets annoyingly long after a while. One of the benefits of deploying a thin war to a running application server is the quick turnaround.<\/li>\n<li>Not having a classpath is actually a pro and a con. Even though one of the advertised advantages of fatjars is not having an application server, you actually still have an application server, it\u2019s just embedded. Having only one jar file, means your application and the embedded application server have the same dependencies. You might run into issues where your application uses another version of a dependency than the embedded server. This can cause some nice hidden bugs. Having the ability to isolate the application server classpath from you application is actually a good thing. Java 9 might solve this, however most application servers are still running on Java 8.<\/li>\n<\/ul>\n<h2>Docker<\/h2>\n<p>Docker has taken the microservices approach a level deeper and allow you to isolate on OS level. This means, building separate jar files become less relevant as you will be building separate Docker images.<\/p>\n<p>Building a fat jar to be deployed as a Docker image is actually slower and heavier than a thin war. You typically layer you Docker images:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/docker_layering.png\"><img decoding=\"async\" class=\"aligncenter wp-image-71657\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/docker_layering.png\" alt=\"\" width=\"860\" height=\"531\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/docker_layering.png 392w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/docker_layering-300x185.png 300w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<p>(above: your final layer in the fatjar option is much heavier than the thinwar option, as it includes the embedded application server)<\/p>\n<h2>OpenLiberty is cool !<\/h2>\n<p>Traditional Websphere is big, slow, expensive and difficult to install. Not something you would use to build Microservices with. IBM is a fairly late entry to the lightweight application server solutions with <a href=\"https:\/\/developer.ibm.com\/wasdev\/websphere-liberty\/\">Websphere Liberty<\/a>, of which the core has been open-sourced recently under <a href=\"https:\/\/openliberty.io\/\">OpenLiberty<\/a>.<\/p>\n<p>But this late entry might be the reason why they have done certain things right and very clean. The way that you can only load the parts that you need with features, and how you can extend the server with your own features, is awesome. Even though other application servers are also doing some modularity with OSGi (or JBoss Modules), it\u2019s just easier with Liberty. For Liberty, including <a href=\"https:\/\/microprofile.io\/\">Microprofile<\/a> is just another feature. Other application servers have added MicroProfile to their fatjar (\u201cMicro\u201d) distributions, and even though I believe it\u2019s possible to also add it to the full application server release, it\u2019s not easy to do.<\/p>\n<p>The other cool thing is how you can very easily decide the deployment model only at deploy time. So you can have the best of all worlds. You can develop against a full application server with the thinwar model to get a quick turnaround. When building, you can assemble a fatjar, thinwar, docker image or all of them. What you develop against stays the same.<\/p>\n<h2>OpenLiberty with MicroProfile example<\/h2>\n<p>I have created a simple application to demonstrate these deployment options. (Code is available in <a href=\"https:\/\/github.com\/phillip-kruger\/quote-service\">GitHub<\/a>)<\/p>\n<p>I did not want to build a basic \u201cHello world\u201d, as I wanted to include some of the MicroProfile features, so this is a \u201cQuote of the Day\u201d app. It uses a factory to load a quote provider (there is only one for now). The current provider gets and caches a quote from <a href=\"http:\/\/forismatic.com\/en\/api\/\">forismatic.com<\/a>. I use the <a href=\"https:\/\/www.ibm.com\/support\/knowledgecenter\/en\/was_beta_liberty\/com.ibm.websphere.wlp.nd.multiplatform.doc\/ae\/cwlp_microprofile_overview.html\">MicroProfile Configuration API<\/a> to configure things like the HTTP Proxy, the URL and the provider to load. I use the <a href=\"https:\/\/www.ibm.com\/support\/knowledgecenter\/en\/was_beta_liberty\/com.ibm.websphere.liberty.autogen.beta.doc\/ae\/rwlp_feature_mpFaultTolerance-1.0.html\">MicroProfile Fault Tolerance API<\/a> to make sure we survive when the provider source is not available.<\/p>\n<h3>Configuring OpenLiberty<\/h3>\n<p>Configuration on OpenLiberty is also very clean. This makes it easy to include the configuration in your project. Using maven resource filtering, you can also extract certain variables to your build. Below the important parts of my <code>server.xml<\/code> (you can see the full one in <a href=\"https:\/\/github.com\/phillip-kruger\/quote-service\/blob\/master\/src\/main\/liberty\/config\/server.xml\">github<\/a>)<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><strong>src\/main\/liberty\/config\/server.xml<\/strong><\/p>\n<pre class=\"brush:xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;server description=\"${project.build.finalName}\"&gt;\r\n\r\n    &lt;featureManager&gt;\r\n        &lt;feature&gt;javaee-7.0&lt;\/feature&gt;\r\n        &lt;feature&gt;microProfile-1.2&lt;\/feature&gt;\r\n    &lt;\/featureManager&gt;\r\n\r\n    &lt;httpEndpoint id=\"defaultHttpEndpoint\"\r\n        httpPort=\"${httpPort}\"\r\n        httpsPort=\"${httpsPort}\"\/&gt;\r\n\r\n    &lt;application location=\"${project.build.directory}\/${project.build.finalName}.war\"\/&gt;\r\n\r\n    &lt;logging traceSpecification=\"${log.name}.*=${log.level}\"\/&gt;\r\n\r\n&lt;\/server&gt;<\/pre>\n<p>For now we just include the umbrella features for Java EE and Microprofile. A bit later we can fine tune that to reduce the memory footprint.<\/p>\n<p>The <code>${httpPort}<\/code> and <code>${httpsPort}<\/code> will actually come from <a href=\"https:\/\/www.ibm.com\/support\/knowledgecenter\/en\/SSAW57_liberty\/com.ibm.websphere.wlp.nd.multiplatform.doc\/ae\/twlp_inst_bootstrap.html\">bootstrap.properties<\/a> that we create with the <a href=\"https:\/\/github.com\/WASdev\/ci.maven\">liberty maven plugin<\/a>.<\/p>\n<p>All variables in the <code>server.xml<\/code>, including <code>${project.build.directory}<\/code> and <code>${project.build.finalName}<\/code> will be replaced when we build with this resource filtering in the pom.xml:<\/p>\n<pre class=\"brush:xml\">&lt;build&gt;\r\n    &lt;finalName&gt;${project.artifactId}&lt;\/finalName&gt;\r\n    &lt;resources&gt;\r\n        &lt;resource&gt;\r\n            &lt;directory&gt;${basedir}\/src\/main\/liberty\/config&lt;\/directory&gt;\r\n            &lt;targetPath&gt;${project.build.directory}&lt;\/targetPath&gt;\r\n            &lt;filtering&gt;true&lt;\/filtering&gt;\r\n            &lt;includes&gt;\r\n                &lt;include&gt;server.xml&lt;\/include&gt;\r\n            &lt;\/includes&gt;\r\n        &lt;\/resource&gt;\r\n    &lt;\/resources&gt;\r\n&lt;\/build&gt;<\/pre>\n<p>(You can see the full <code>pom.xml<\/code> in <a href=\"https:\/\/github.com\/phillip-kruger\/quote-service\/blob\/master\/pom.xml\">github<\/a>)<\/p>\n<p>So when we do a <code>mvn clean install<\/code> the <code>server.xml<\/code> will be copied to the target directory with the variables replaced.<\/p>\n<h3>Deployment options<\/h3>\n<p>I am using <a href=\"http:\/\/maven.apache.org\/guides\/introduction\/introduction-to-profiles.html\">maven profiles<\/a> to allow me to select, at build time, which deployment option I want:<\/p>\n<p>In the <code>&lt;build&gt;<\/code> of <a href=\"\/\/github.com\/phillip-kruger\/quote-service\/blob\/master\/pom.xml)\">pom.xml<\/a><\/p>\n<pre class=\"brush:xml\">&lt;plugins&gt;\r\n    &lt;plugin&gt;\r\n        &lt;groupId&gt;net.wasdev.wlp.maven.plugins&lt;\/groupId&gt;\r\n        &lt;artifactId&gt;liberty-maven-plugin&lt;\/artifactId&gt;\r\n        &lt;version&gt;${openliberty.maven.version}&lt;\/version&gt;\r\n\r\n        &lt;configuration&gt;\r\n            &lt;assemblyArtifact&gt;\r\n                &lt;groupId&gt;io.openliberty&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;openliberty-runtime&lt;\/artifactId&gt;\r\n                &lt;version&gt;${openliberty.version}&lt;\/version&gt;\r\n                &lt;type&gt;zip&lt;\/type&gt;\r\n            &lt;\/assemblyArtifact&gt;\r\n        &lt;\/configuration&gt;\r\n    &lt;\/plugin&gt;\r\n&lt;\/plugins&gt;<\/pre>\n<h2>On the fly option<\/h2>\n<p>This option follows the same development cycle than a fatjar cycle (although it does not create a jar file). If you do a <code>mvn clean install -Pfatjar<\/code>, it will install, configure (from <code>server.xml<\/code>) and start a server in the foreground. In other words, the mvn process does not finish, as the server start is part of the mvn process. To stop the server you need to <code>ctrl-c<\/code> the process.<\/p>\n<pre class=\"brush:xml; wrap-lines:false\">&lt;profile&gt;\r\n        &lt;id&gt;fatjar&lt;\/id&gt;\r\n        &lt;activation&gt;\r\n            &lt;property&gt;\r\n                &lt;name&gt;fatjar&lt;\/name&gt;\r\n            &lt;\/property&gt;\r\n        &lt;\/activation&gt;\r\n        &lt;build&gt;\r\n            &lt;plugins&gt;\r\n                &lt;plugin&gt;\r\n                    &lt;groupId&gt;net.wasdev.wlp.maven.plugins&lt;\/groupId&gt;\r\n                    &lt;artifactId&gt;liberty-maven-plugin&lt;\/artifactId&gt;\r\n\r\n                    &lt;executions&gt;\r\n                        &lt;execution&gt;\r\n                            &lt;phase&gt;install&lt;\/phase&gt;\r\n                            &lt;goals&gt;\r\n                                &lt;goal&gt;install-server&lt;\/goal&gt;\r\n                                &lt;goal&gt;create-server&lt;\/goal&gt;\r\n                                &lt;goal&gt;run-server&lt;\/goal&gt;    \r\n                            &lt;\/goals&gt;\r\n\r\n                            &lt;configuration&gt;\r\n                                &lt;configFile&gt;${project.build.directory}\/server.xml&lt;\/configFile&gt;\r\n                                &lt;bootstrapProperties&gt;\r\n                                    &lt;httpPort&gt;${openliberty.http.port}&lt;\/httpPort&gt;\r\n                                    &lt;httpsPort&gt;${openliberty.https.port}&lt;\/httpsPort&gt;\r\n                                &lt;\/bootstrapProperties&gt;\r\n                                &lt;jvmOptions&gt;\r\n                                    &lt;param&gt;-Xmx${openliberty.Xmx}&lt;\/param&gt;\r\n                                &lt;\/jvmOptions&gt;\r\n                            &lt;\/configuration&gt;\r\n                        &lt;\/execution&gt;\r\n                    &lt;\/executions&gt;\r\n                &lt;\/plugin&gt;\r\n\r\n            &lt;\/plugins&gt;\r\n        &lt;\/build&gt;\r\n    &lt;\/profile&gt;<\/pre>\n<p>Of course using an IDE like Netbeans (or any other IDE) this is actually just a button you click:<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans.png\"><img decoding=\"async\" class=\"aligncenter wp-image-71658\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans.png\" alt=\"\" width=\"860\" height=\"466\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans.png 1920w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans-300x163.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans-768x416.png 768w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2017\/12\/netbeans-1024x555.png 1024w\" sizes=\"(max-width: 860px) 100vw, 860px\" \/><\/a><\/p>\n<h2>Full application server option:<\/h2>\n<p>With this option we want to install, configure and start the server, and then deploy a thin war continuously as we write code. We still install and configure the server from scratch every time we start the server, just not on every deploy.<\/p>\n<p><code>mvn clean install -Pstart-liberty<\/code> will install, configure (from <code>server.xml<\/code>) and start a liberty server in <code>\/tmp<\/code> folder:<\/p>\n<pre class=\"brush:xml;wrap-lines:false\">&lt;profile&gt;\r\n        &lt;id&gt;start-liberty&lt;\/id&gt;\r\n        &lt;activation&gt;\r\n            &lt;property&gt;\r\n                &lt;name&gt;start-liberty&lt;\/name&gt;\r\n            &lt;\/property&gt;\r\n        &lt;\/activation&gt;\r\n        &lt;build&gt;\r\n\r\n            &lt;plugins&gt;\r\n                &lt;plugin&gt;\r\n                    &lt;groupId&gt;net.wasdev.wlp.maven.plugins&lt;\/groupId&gt;\r\n                    &lt;artifactId&gt;liberty-maven-plugin&lt;\/artifactId&gt;\r\n\r\n                    &lt;executions&gt;\r\n\r\n                        &lt;execution&gt;\r\n                            &lt;id&gt;1&lt;\/id&gt;\r\n                            &lt;phase&gt;pre-integration-test&lt;\/phase&gt;\r\n                            &lt;goals&gt;\r\n                                &lt;goal&gt;install-server&lt;\/goal&gt;\r\n                            &lt;\/goals&gt;\r\n                            &lt;configuration&gt;\r\n                                &lt;assemblyInstallDirectory&gt;${openliberty.installDir}&lt;\/assemblyInstallDirectory&gt;\r\n                            &lt;\/configuration&gt;\r\n                        &lt;\/execution&gt;\r\n\r\n                        &lt;execution&gt;\r\n                            &lt;id&gt;2&lt;\/id&gt;\r\n                            &lt;phase&gt;pre-integration-test&lt;\/phase&gt;\r\n                            &lt;goals&gt;\r\n                                &lt;goal&gt;create-server&lt;\/goal&gt;\r\n                                &lt;goal&gt;start-server&lt;\/goal&gt;\r\n                            &lt;\/goals&gt;\r\n                            &lt;configuration&gt;\r\n                                &lt;installDirectory&gt;${openliberty.installDir}\/wlp&lt;\/installDirectory&gt;\r\n                                &lt;serverName&gt;${project.artifactId}&lt;\/serverName&gt;\r\n                                &lt;configFile&gt;${project.build.directory}\/server.xml&lt;\/configFile&gt;\r\n                                &lt;bootstrapProperties&gt;\r\n                                    &lt;httpPort&gt;${openliberty.http.port}&lt;\/httpPort&gt;\r\n                                    &lt;httpsPort&gt;${openliberty.https.port}&lt;\/httpsPort&gt;\r\n                                &lt;\/bootstrapProperties&gt; \r\n                                &lt;jvmOptions&gt;\r\n                                    &lt;param&gt;-Xmx${openliberty.Xmx}&lt;\/param&gt;\r\n                                &lt;\/jvmOptions&gt;\r\n                            &lt;\/configuration&gt;\r\n                        &lt;\/execution&gt;\r\n\r\n                    &lt;\/executions&gt;\r\n                &lt;\/plugin&gt;\r\n\r\n            &lt;\/plugins&gt;\r\n        &lt;\/build&gt;\r\n    &lt;\/profile&gt;<\/pre>\n<p>You can now deploy the thinwar continuously:<\/p>\n<p><code>mvn clean install -Pdeploy<\/code><\/p>\n<pre class=\"brush:xml;wrap-lines:false\">&lt;profile&gt;\r\n    &lt;id&gt;deploy&lt;\/id&gt;\r\n    &lt;activation&gt;\r\n        &lt;property&gt;\r\n            &lt;name&gt;deploy&lt;\/name&gt;\r\n        &lt;\/property&gt;\r\n    &lt;\/activation&gt;\r\n    &lt;build&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;net.wasdev.wlp.maven.plugins&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;liberty-maven-plugin&lt;\/artifactId&gt;\r\n                &lt;executions&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;phase&gt;pre-integration-test&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;deploy&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                        &lt;configuration&gt;\r\n                            &lt;appArchive&gt;${project.build.directory}\/${project.artifactId}.war&lt;\/appArchive&gt;\r\n                            &lt;serverName&gt;${project.artifactId}&lt;\/serverName&gt;\r\n                            &lt;installDirectory&gt;${openliberty.installDir}\/wlp&lt;\/installDirectory&gt;\r\n                        &lt;\/configuration&gt;\r\n                    &lt;\/execution&gt;\r\n                &lt;\/executions&gt;\r\n            &lt;\/plugin&gt;\r\n        &lt;\/plugins&gt;\r\n    &lt;\/build&gt;\r\n&lt;\/profile&gt;<\/pre>\n<p>Stopping the server is also very easy:<\/p>\n<p><code>mvn clean install -Pstop-liberty<\/code><\/p>\n<h2>Fatjar distribution<\/h2>\n<p>It\u2019s very easy to create a fatjar distribution with <code>mvn clean install -Ppackage-liberty<\/code>:<\/p>\n<pre class=\"brush:xml;wrap-lines:false\">&lt;profile&gt;\r\n    &lt;id&gt;package-liberty&lt;\/id&gt;\r\n    &lt;activation&gt;\r\n        &lt;property&gt;\r\n            &lt;name&gt;package-liberty&lt;\/name&gt;\r\n        &lt;\/property&gt;\r\n    &lt;\/activation&gt;\r\n    &lt;build&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;net.wasdev.wlp.maven.plugins&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;liberty-maven-plugin&lt;\/artifactId&gt;\r\n                &lt;executions&gt;\r\n                    &lt;execution&gt;\r\n                        &lt;phase&gt;package&lt;\/phase&gt;\r\n                        &lt;goals&gt;\r\n                            &lt;goal&gt;package-server&lt;\/goal&gt;\r\n                        &lt;\/goals&gt;\r\n                        &lt;configuration&gt;\r\n                            &lt;packageFile&gt;${project.build.directory}\/${project.artifactId}.jar&lt;\/packageFile&gt;\r\n                            &lt;include&gt;runnable&lt;\/include&gt;\r\n                            &lt;serverName&gt;${project.artifactId}&lt;\/serverName&gt;\r\n                            &lt;installDirectory&gt;${openliberty.installDir}\/wlp&lt;\/installDirectory&gt;\r\n                        &lt;\/configuration&gt;\r\n                    &lt;\/execution&gt;\r\n                &lt;\/executions&gt;\r\n            &lt;\/plugin&gt;\r\n        &lt;\/plugins&gt;\r\n    &lt;\/build&gt;\r\n\r\n&lt;\/profile&gt;<\/pre>\n<p>In my target directory I now have an executable (fat)jar file that I can start with: <code>java -jar quote-service.jar<\/code><\/p>\n<p>In all the above mentioned <code>profiles<\/code> you can test the example app with:<\/p>\n<p><code>mvn -Dtest=com.github.phillipkruger.quoteservice.QuoteApiIT surefire:test<\/code><\/p>\n<p>And that should give you a quote of the day:<\/p>\n<pre class=\"brush:bash\">{\r\n    \"author\":\"Naguib Mahfouz\",\r\n    \"text\":\"You can tell whether a man is clever by his answers. You can tell whether a man is wise by his questions.\"\r\n}<\/pre>\n<h3>Fine-tuning the memory footprint.<\/h3>\n<p>To start off I used the umbrella <code>javaee-7.0<\/code> and <code>microProfile-1.2<\/code> features, even though my application only uses a subset of these specifications.<\/p>\n<p>Using <code>jconsole<\/code> I measured the memory footprint (after a GC) of the running server:<\/p>\n<p><strong>50,691 kbytes<\/strong><\/p>\n<p>You can change the <code>server.xml<\/code> to only include the features your app is using, in my example:<\/p>\n<pre class=\"brush:xml\">&lt;feature&gt;jaxrs-2.0&lt;\/feature&gt;\r\n&lt;feature&gt;ejb-3.2&lt;\/feature&gt;\r\n&lt;feature&gt;cdi-1.2&lt;\/feature&gt;\r\n&lt;feature&gt;jsonp-1.0&lt;\/feature&gt;\r\n&lt;feature&gt;jaxrsClient-2.0&lt;\/feature&gt;\r\n&lt;feature&gt;mpConfig-1.1&lt;\/feature&gt;\r\n&lt;feature&gt;mpFaultTolerance-1.0&lt;\/feature&gt;<\/pre>\n<p>Again using <code>jconsole<\/code> I measured the memory footprint (after a GC) of the running server:<\/p>\n<p><strong>30,198 kbytes<\/strong><\/p>\n<p>Ideally you would also fine-tune the <code>pom.xml<\/code> to only include the specification you use.<\/p>\n<h2>Conclusion<\/h2>\n<p>We can argue whether it\u2019s better to do fatjars vs thinwars and the pros and cons of having an application server, or not. However, not having to make this decision when we start developing (ie. download the micro distribution or the full distribution) but only when we build, allows for more options. Maybe it\u2019s possible to do that with the other application servers, but OpenLiberty made it easy.<\/p>\n<h2>More info<\/h2>\n<p>Also read this great blogs from <a href=\"https:\/\/twitter.com\/PavelPscheidl\">Pavel Pscheidl<\/a><\/p>\n<ul>\n<li><a href=\"http:\/\/www.pavel.cool\/javaee\/java-ee-fatjars-docker\/\">Building, packaging and distributing Java EE applications in 2017<\/a><\/li>\n<li><a href=\"http:\/\/www.pavel.cool\/javaee\/ee4j\/openliberty-jaxrs\/\">OpenLiberty.io: Simple guide<\/a><\/li>\n<\/ul>\n<p>and watch this video from <a href=\"https:\/\/twitter.com\/AdamBien\">Adam Bien<\/a><\/p>\n<ul>\n<li><a href=\"https:\/\/www.youtube.com\/watch?v=5N4EUDhrkec\">Thin WARs, Java EE 7, Docker and Productivity<\/a><\/li>\n<\/ul>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td>Published on Java Code Geeks with permission by Phillip Kr\u00fcger, partner at our <a href=\"http:\/\/www.javacodegeeks.com\/join-us\/jcg\/\" target=\"_blank\" rel=\"noopener\">JCG program<\/a>. See the original article here: <a href=\"https:\/\/www.phillip-kruger.com\/post\/fatjars_thinwars_and_why_openliberty_is_cool\/\" target=\"_blank\" rel=\"noopener\">Fatjars, Thinwars and why OpenLiberty is cool.<\/a><\/p>\n<p>Opinions expressed by Java Code Geeks contributors are their own.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar myapp.jar and off you go. No Application server. No classpath. This approach has been popularised by the microservices architectural style and frameworks like Springboot. \u201cIn short, the microservice architectural style &hellip;<\/p>\n","protected":false},"author":10628,"featured_media":112,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-71649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-12-27T08:00:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Phillip Kruger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Phillip Kruger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html\"},\"author\":{\"name\":\"Phillip Kruger\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/f24087666e9c716ac25d6c5aceff9a6a\"},\"headline\":\"Fatjars, Thinwars and why OpenLiberty is cool\",\"datePublished\":\"2017-12-27T08:00:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html\"},\"wordCount\":1377,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html\",\"name\":\"Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"datePublished\":\"2017-12-27T08:00:33+00:00\",\"description\":\"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/enterprise-java-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"java-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2017\\\/12\\\/fatjars-thinwars-openliberty-cool.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Fatjars, Thinwars and why OpenLiberty is cool\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/f24087666e9c716ac25d6c5aceff9a6a\",\"name\":\"Phillip Kruger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g\",\"caption\":\"Phillip Kruger\"},\"description\":\"Phillip is a software developer and a systems architect who knacks for solving problems. He has a passion for clean code and evolutionary architecture. He blogs about all technical things.\",\"sameAs\":[\"https:\\\/\\\/www.phillip-kruger.com\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/phillipkruger\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/phillip-kruger\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks","description":"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html","og_locale":"en_US","og_type":"article","og_title":"Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks","og_description":"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar","og_url":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2017-12-27T08:00:33+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","type":"image\/jpeg"}],"author":"Phillip Kruger","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Phillip Kruger","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html"},"author":{"name":"Phillip Kruger","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/f24087666e9c716ac25d6c5aceff9a6a"},"headline":"Fatjars, Thinwars and why OpenLiberty is cool","datePublished":"2017-12-27T08:00:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html"},"wordCount":1377,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html","url":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html","name":"Fatjars, Thinwars and why OpenLiberty is cool - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","datePublished":"2017-12-27T08:00:33+00:00","description":"Fatjars Building a Fatjar (or Uberjar) that contains everything you need to run your application nicely packaged together means you can just do: java -jar","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/enterprise-java-logo.jpg","width":150,"height":150,"caption":"java-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2017\/12\/fatjars-thinwars-openliberty-cool.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Fatjars, Thinwars and why OpenLiberty is cool"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/f24087666e9c716ac25d6c5aceff9a6a","name":"Phillip Kruger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/38e989af8597679e556461deb73f4044c27d0228a28f9971d2ac37794b1b8603?s=96&d=mm&r=g","caption":"Phillip Kruger"},"description":"Phillip is a software developer and a systems architect who knacks for solving problems. He has a passion for clean code and evolutionary architecture. He blogs about all technical things.","sameAs":["https:\/\/www.phillip-kruger.com\/","https:\/\/www.linkedin.com\/in\/phillipkruger\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/phillip-kruger"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/71649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/10628"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=71649"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/71649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=71649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=71649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=71649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}