<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Service on ShrimpWorks</title><link>/tags/service/</link><description>Recent content in Service on ShrimpWorks</description><generator>Hugo</generator><language>en-gb</language><lastBuildDate>Tue, 01 Sep 2020 00:00:00 +0000</lastBuildDate><atom:link href="/tags/service/feed.xml" rel="self" type="application/rss+xml"/><item><title>Run Your Java Services with SystemD</title><link>/2020/09/01/run-your-java-services-with-systemd/</link><pubDate>Tue, 01 Sep 2020 00:00:00 +0000</pubDate><guid>/2020/09/01/run-your-java-services-with-systemd/</guid><description>&lt;p&gt;There&amp;rsquo;s a strong tendency to want to run everything in Docker these days,
especially if you&amp;rsquo;re trying to run something as an always-on service, since
passing &lt;code&gt;--restart=always&lt;/code&gt; to your &lt;code&gt;run&lt;/code&gt; invocation or Docker Compose
configuration ensures that running containers start back up after reboots or
failures, and seems to involve a little less &amp;ldquo;black magic&amp;rdquo; than actually
configuring software to run as services directly on a host.&lt;/p&gt;
&lt;p&gt;The downside to this is the approach is that running a service in a container
leads to significantly longer startup times, more memory and CPU overhead, lost
logs, and in my opinion offer a false sense of security and isolation since
most images are still configured to run as root, and more often than not large
swathes of the host filesystem are mounted as volumes to achieve simple tasks.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also a belief that your software will magically run anywhere - but if
you&amp;rsquo;re writing Java (or any JVM language) code - that&amp;rsquo;s one of Java&amp;rsquo;s biggest
selling points - it already has its own VM your code is running in, no most
platforms!&lt;/p&gt;
&lt;p&gt;Therefore, let&amp;rsquo;s see how easy it actually is to configure our software to run
as a standard system service, providing us with the ability to run it as a
separate restricted user, complete with standard logging configuration, and
give us control over via standard &lt;code&gt;service myservice start|status|restart|stop&lt;/code&gt;
commands.&lt;/p&gt;</description></item><item><title>Simple HTTP Server in Java</title><link>/2013/12/17/simple-http-server-in-java/</link><pubDate>Tue, 17 Dec 2013 21:28:42 +0000</pubDate><guid>/2013/12/17/simple-http-server-in-java/</guid><description>&lt;p&gt;Some thing I&amp;rsquo;ve been using for a while, and which recently became useful
at work as well, is a simple HTTP service written in plain Java with
existing JRE functionality, using an
&lt;a href="http://docs.oracle.com/javase/7/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/HttpServer.html"&gt;HttpServer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a simple &amp;ldquo;main()&amp;rdquo; which sets up two basic &amp;ldquo;pages&amp;rdquo;, a root (/) and
one which echoes your browser&amp;rsquo;s request headers (/headers/).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8be9fd;font-style:italic"&gt;public&lt;/span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;class&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;SimpleHTTPService&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;public&lt;/span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;static&lt;/span&gt; &lt;span style="color:#8be9fd"&gt;void&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;main&lt;/span&gt;(String&lt;span style="color:#ff79c6"&gt;[]&lt;/span&gt; args) &lt;span style="color:#8be9fd;font-style:italic"&gt;throws&lt;/span&gt; IOException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HttpServer server &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; HttpServerProvider.&lt;span style="color:#50fa7b"&gt;provider&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;createHttpServer&lt;/span&gt;(&lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; InetSocketAddress(8080), 0);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; server.&lt;span style="color:#50fa7b"&gt;createContext&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;, &lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; HttpHandler() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @Override
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;public&lt;/span&gt; &lt;span style="color:#8be9fd"&gt;void&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;handle&lt;/span&gt;(HttpExchange he) &lt;span style="color:#8be9fd;font-style:italic"&gt;throws&lt;/span&gt; IOException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd"&gt;byte&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;[]&lt;/span&gt; output &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; &lt;span style="color:#f1fa8c"&gt;&amp;#34;Hello world!&amp;#34;&lt;/span&gt;.&lt;span style="color:#50fa7b"&gt;getBytes&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; he.&lt;span style="color:#50fa7b"&gt;sendResponseHeaders&lt;/span&gt;(200, output.&lt;span style="color:#50fa7b"&gt;length&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; he.&lt;span style="color:#50fa7b"&gt;getResponseBody&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;write&lt;/span&gt;(output);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; server.&lt;span style="color:#50fa7b"&gt;createContext&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;/headers&amp;#34;&lt;/span&gt;, &lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; HttpHandler() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; @Override
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;public&lt;/span&gt; &lt;span style="color:#8be9fd"&gt;void&lt;/span&gt; &lt;span style="color:#50fa7b"&gt;handle&lt;/span&gt;(HttpExchange he) &lt;span style="color:#8be9fd;font-style:italic"&gt;throws&lt;/span&gt; IOException {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StringBuilder result &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;new&lt;/span&gt; StringBuilder(&lt;span style="color:#f1fa8c"&gt;&amp;#34;Request Headers&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;for&lt;/span&gt; (Entry&lt;span style="color:#ff79c6"&gt;&amp;lt;&lt;/span&gt; String, List&lt;span style="color:#ff79c6"&gt;&amp;lt;&lt;/span&gt; String&lt;span style="color:#ff79c6"&gt;&amp;gt;&amp;gt;&lt;/span&gt; header : he.&lt;span style="color:#50fa7b"&gt;getRequestHeaders&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;entrySet&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result.&lt;span style="color:#50fa7b"&gt;append&lt;/span&gt;(String.&lt;span style="color:#50fa7b"&gt;format&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;, header.&lt;span style="color:#50fa7b"&gt;getKey&lt;/span&gt;()));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ff79c6"&gt;for&lt;/span&gt; (String val : header.&lt;span style="color:#50fa7b"&gt;getValue&lt;/span&gt;()) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result.&lt;span style="color:#50fa7b"&gt;append&lt;/span&gt;(String.&lt;span style="color:#50fa7b"&gt;format&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;, val));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result.&lt;span style="color:#50fa7b"&gt;append&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd"&gt;byte&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;[]&lt;/span&gt; output &lt;span style="color:#ff79c6"&gt;=&lt;/span&gt; result.&lt;span style="color:#50fa7b"&gt;toString&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;getBytes&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; he.&lt;span style="color:#50fa7b"&gt;sendResponseHeaders&lt;/span&gt;(200, output.&lt;span style="color:#50fa7b"&gt;length&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; he.&lt;span style="color:#50fa7b"&gt;getResponseBody&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;write&lt;/span&gt;(output);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; server.&lt;span style="color:#50fa7b"&gt;setExecutor&lt;/span&gt;(Executors.&lt;span style="color:#50fa7b"&gt;newCachedThreadPool&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; server.&lt;span style="color:#50fa7b"&gt;start&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; System.&lt;span style="color:#50fa7b"&gt;out&lt;/span&gt;.&lt;span style="color:#50fa7b"&gt;println&lt;/span&gt;(&lt;span style="color:#f1fa8c"&gt;&amp;#34;HTTP Listening on port &amp;#34;&lt;/span&gt; &lt;span style="color:#ff79c6"&gt;+&lt;/span&gt; server.&lt;span style="color:#50fa7b"&gt;getAddress&lt;/span&gt;().&lt;span style="color:#50fa7b"&gt;getPort&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running this as-is will allow you to load up the URLs
&lt;code&gt;http://localhost:8080/&lt;/code&gt; and &lt;code&gt;http://localhost:8080/headers/&lt;/code&gt; and see
some output generated by the two registered contexts.&lt;/p&gt;</description></item></channel></rss>