tag:blogger.com,1999:blog-16003416191622576572024-02-21T14:12:14.023+05:30A WindowHere I write about various events I was involved in and ideas that inspired me. Recently, it is more of a linux blog because I have been doing a lot of work on it. However, off and on I write on various other things that my mind just can't let go easily.Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.comBlogger258125tag:blogger.com,1999:blog-1600341619162257657.post-64785404991036197662020-11-25T20:12:00.000+05:302020-11-25T20:12:40.634+05:30Smallest missing positive integer in an unsorted array<p>The question is to find the smallest missing positive integer, given an unsorted integer array. Consider the following table of arrays and their corresponding outputs for examples.</p>
<style>
table, tr, th, td {
border: 1px solid gray;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
th {
background-color: #f1f1c1;
}
</style>
<table>
<tbody><tr>
<th>Input array</th>
<th>Output value</th>
</tr>
<tr>
<td>1,2,3,3</td>
<td>4</td>
</tr>
<tr>
<td>3,4,-1,1</td>
<td>2</td>
</tr>
<tr>
<td>7,8,9,11,12</td>
<td>1</td>
</tr>
<tr>
<td>-1,-2</td>
<td>1</td>
</tr>
</tbody></table>
<p>The simple solution is to sort the array and get the missing value. The challenge is to do it in O(n) and with constant space. Modifications to the array are allowed.<br /></p><p>The complexity requirement indicates that we need an approach with multiple passes on the same array. Since modifications are allowed, we need a way of storing information within the array. The smallest output of the function is 1 and the largest output of the function will obviously be the length of the array + 1. So, we can see the possibility of some 1 to 1 mapping between the indices and the possible outputs of the function. The idea is if the value at an index can be modified to store information about whether the value (index + 1) is present in the array, we could use that information to reach the smallest index whose corresponding value , i.e. (index + 1), is not present in the array. That would be the answer we are looking for.</p><p>As seen from the input set, the numbers are signed and we know that sign bit is not part of the value of the number so we have to utilize that to store the availability information. As the availability information is boolean, the space required and available match.</p><p>Negative values in the array do not change the output at all and if all elements are negative we can just return 1 as the value we are looking for. So, we just need to focus on how we can use positive integers. So, we store information by marking the positive integers as negative to mark presence. We can map a positive integer to the index of its value - 1.</p><p>Let us consider 3 in the second array above. The presence of 3 will be marked by marking the value at index 2 (= 3 - 1) as negative. We have a problem here though. The value there is already negative. So, we need a way of knowing whether a value was already negative or we marked it so.</p><p>To overcome that problem, we modify the array a bit. We can move all negative values to the end of the array and store the index distinction. Now, while marking if we want to mark a value that is already negative, we don't care because that value does not contribute to the output anyway. From the remaining positive ones, whichever remains positive after this pass gives the indication of the result, i.e. the index of the value + 1.</p><pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'JetBrains Mono',monospace; font-size: 9.8pt;"><span style="color: #cc7832;">public class </span>SmallestMissingPositive {<br /> <span style="color: #cc7832;">public static void </span><span style="color: #ffc66d;">main</span>(String[] args) {<br /> System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="font-style: italic;">leastPositive</span>(<span style="color: #cc7832;">new int</span>[]{<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">2</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">3</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">3</span>}))<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="font-style: italic;">leastPositive</span>(<span style="color: #cc7832;">new int</span>[]{<span style="color: #6897bb;">3</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">4</span><span style="color: #cc7832;">,</span>-<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">1</span>}))<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="font-style: italic;">leastPositive</span>(<span style="color: #cc7832;">new int</span>[]{<span style="color: #6897bb;">7</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">8</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">9</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">11</span><span style="color: #cc7832;">,</span><span style="color: #6897bb;">12</span>}))<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="font-style: italic;">leastPositive</span>(<span style="color: #cc7832;">new int</span>[]{-<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span>-<span style="color: #6897bb;">2</span>}))<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="font-style: italic;">leastPositive</span>(<span style="color: #cc7832;">new int</span>[]{<span style="color: #6897bb;">1</span><span style="color: #cc7832;">, </span>-<span style="color: #6897bb;">1</span><span style="color: #cc7832;">,</span>-<span style="color: #6897bb;">2</span>}))<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /><br /> <span style="color: #cc7832;">private static int </span><span style="color: #ffc66d;">leastPositive</span>(<span style="color: #cc7832;">int</span>[] nums){<br /> <span style="color: #cc7832;">int </span>beginNegative = nums.<span style="color: #9876aa;">length </span>-<span style="color: #6897bb;">1</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"><br /></span><span style="color: #cc7832;"> </span><span style="color: grey;">// sequence of negatives at the end<br /></span><span style="color: grey;"> </span><span style="color: #cc7832;">for</span>(<span style="color: #cc7832;">int </span>i = nums.<span style="color: #9876aa;">length </span>-<span style="color: #6897bb;">1</span><span style="color: #cc7832;">; </span>i >= <span style="color: #6897bb;">0</span><span style="color: #cc7832;">; </span>i--){<br /> <span style="color: #cc7832;">if</span>(nums[i] < <span style="color: #6897bb;">0</span>){<br /> beginNegative = i<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /> <span style="color: #cc7832;">else</span>{<br /> <span style="color: #cc7832;">break;<br /></span><span style="color: #cc7832;"> </span>}<br /> }<br /><br /> <span style="color: grey;">// all negative values in nums<br /></span><span style="color: grey;"> </span><span style="color: #cc7832;">if</span>(beginNegative == <span style="color: #6897bb;">0</span>){<br /> <span style="color: #cc7832;">return </span><span style="color: #6897bb;">1</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /><br /><br /> <span style="color: grey;">// can transfer to beginNegative index now<br /></span><span style="color: grey;"> </span>beginNegative--<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> for</span>(<span style="color: #cc7832;">int </span>i = <span style="color: #6897bb;">0</span><span style="color: #cc7832;">; </span>i < nums.<span style="color: #9876aa;">length</span><span style="color: #cc7832;">; </span>i++){<br /> <span style="color: #cc7832;">if</span>(i == beginNegative){<br /> <span style="color: #cc7832;">break;<br /></span><span style="color: #cc7832;"> </span>}<br /> <span style="color: #cc7832;">else</span>{<br /> <span style="color: #cc7832;">if</span>(nums[i] <<span style="color: #6897bb;">0</span>){<br /> <span style="color: #cc7832;">int </span>temp = nums[i]<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>nums[i] = nums[beginNegative]<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>nums[beginNegative] = temp<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"><br /></span><span style="color: #cc7832;"> </span><span style="color: grey;">// swap<br /></span><span style="color: grey;"><br /></span><span style="color: grey;"> </span>beginNegative--<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> if</span>(beginNegative ==i){<br /> <span style="color: #cc7832;">break;<br /></span><span style="color: #cc7832;"> </span>}<br /> <span style="color: grey;">// now we search for next index for beginNegative<br /></span><span style="color: grey;"> </span><span style="color: #cc7832;">for</span>(<span style="color: #cc7832;">int </span>j = beginNegative<span style="color: #cc7832;">; </span>j > i<span style="color: #cc7832;">; </span>j--){<br /> <span style="color: #cc7832;">if</span>(nums[j] < <span style="color: #6897bb;">0</span>){<br /> beginNegative = j<span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /> <span style="color: #cc7832;">else</span>{<br /> <span style="color: #cc7832;">break;<br /></span><span style="color: #cc7832;"> </span>}<br /> }<br /> }<br /> }<br /> }<br /><br /><br /> <span style="color: #cc7832;">for</span>(<span style="color: #cc7832;">int </span>i = <span style="color: #6897bb;">0</span><span style="color: #cc7832;">; </span>i <= beginNegative<span style="color: #cc7832;">; </span>i++ ){<br /> <span style="color: #cc7832;">int </span>idx = Math.<span style="font-style: italic;">abs</span>(nums[i]) - <span style="color: #6897bb;">1</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> if </span>(idx >= nums.<span style="color: #9876aa;">length</span>){<br /> <span style="color: #cc7832;">continue;<br /></span><span style="color: #cc7832;"> </span>}<br /> <span style="color: #cc7832;">if </span>(nums[idx] > <span style="color: #6897bb;">0</span>){<br /> nums[idx] = nums[idx] * -<span style="color: #6897bb;">1</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /> }<br /> <span style="color: #cc7832;">for </span>(<span style="color: #cc7832;">int </span>i = <span style="color: #6897bb;">0</span><span style="color: #cc7832;">; </span>i <= beginNegative<span style="color: #cc7832;">; </span>i++) {<br /> <span style="color: #cc7832;">if </span>(nums[i] > <span style="color: #6897bb;">0</span>){<br /> <span style="color: #cc7832;">return </span>i+<span style="color: #6897bb;">1</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /> }<br /> <span style="color: #cc7832;">return </span>beginNegative + <span style="color: #6897bb;">2</span><span style="color: #cc7832;">;<br /></span><span style="color: #cc7832;"> </span>}<br /><br />}<br /></pre><div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-83453780294250326122020-11-24T18:57:00.000+05:302020-11-24T18:57:23.101+05:30Intersection of two sorted arrays<p> In an interview, I was asked to find the intersection of two sorted arrays. My initial approach was to iterate over each element in first array and use binary search for it in the second array and handle the second array similarly. This solution has complexity of O(N * lg N). It also has one problem that when an element is common, it is found twice: when searched in second from iteration over first and vice versa. This can be easily avoided by searching in the output.</p><p>A simpler solution is to just use two pointers.</p><code><p>List<Integer> intersection(int[] a, int[] b){<br /> List<Integer> result = new ArrayList<>();<br /> <br /> int i = 0;<br /> int j = 0;<br /> for(; i< a.length && j < b.length;){<br /> if(a[i] == b[j]){<br /> result.add(a[i]);<br /> i++;<br /> j++;<br /> }else if (a[i] < b[j]){<br /> i++; <br /> }else {<br /> j++;<br /> }<br /> }<br /> return result;<br /> }</p></code><p>This solution works in linear time. The solution can be further improved for the average case keeping the worst case complexity same.</p><p>Consider a large array as follows:</p><p>a = [10,11,12,13,14,15,16,17,...10000,1000000]</p><p>Now let's consider the case of finding intersection with a small array as follows:</p><p>b = [10000,1000000]</p><p>After we initialize the two pointers to the beginning of the arrays, we keep moving in the first array for a long time. We can improve this by jumping to the next element higher or equal to the element being compared it. We could use binary search for that.</p><code><p>List<Integer> intersection(int[] a, int[] b){<br /> List<Integer> result = new ArrayList<>();<br /> <br /> int i = 0;<br /> int j = 0;<br /> for(; i< a.length && j < b.length;){<br /> if(a[i] == b[j]){<br /> result.add(a[i]);<br /> i++;<br /> j++;<br /> }else if (a[i] < b[j]){<br /> //i++;<br /> int low = i + 1;<br /> int high = a.length - 1;<br /> int mid = low + (high - low) / 2;<br /> while(low < high){<br /> if(a[mid] == b[j]){<br /> i = mid;<br /> break;<br /> }else if(a[mid] > b[j]){<br /> high = mid - 1;<br /> }else{<br /> low = mid + 1;<br /> }<br /> mid = low + (high - low) / 2;<br /> }<br /> if (low >= high){<br /> i = low;<br /> }<br /> <br /> }else {<br /> //j++;<br /> <br /> int low = j + 1;<br /> int high = b.length - 1;<br /> int mid = low + (high - low) / 2;<br /> while(low < high){<br /> if(b[mid] == a[i]){<br /> j = mid;<br /> break;<br /> }else if(b[mid] > a[i]){<br /> high = mid - 1;<br /> }else{<br /> low = mid + 1;<br /> }<br /> mid = low + (high - low) / 2;<br /> }<br /> if (low >= high){<br /> j = low;<br /> }<br /> }<br /> }<br /> return result;<br /> }</p></code><p>This improves the average case performance, especially for skewed inputs as mentioned earlier.<br /></p><div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-61711525709831470092020-11-21T18:02:00.002+05:302020-11-21T18:02:26.006+05:30Elasticsearch shard allocation failure<p> Recently, I found a shard allocation failure in an Elasticsearch cluster. Checking the reason for the failure, I found the reason to be the following:</p><p><code>"Validation Failed: 1: this action would add [4] total shards, but this cluster currently has [4000]/[4000] maximum shards open;"</code></p><p>It is a bit unclear from the error message why the cluster considers 4000 as the maximum number of shards it should consider. Especially, given that on a different cluster I get 16000 as the maximum number of shards.</p><p>Looking at my cluster settings (including defaults), I found a property called <code>"max_shards_per_node"</code> and it was set to <code>"1000"</code>. Since, I had 4 nodes, it added up perfectly.</p><p>Generally, this setting is put in so that the nodes have a proper balance between different types of work loads. However, we knew our scenarios of more shards was temporary so increasing the value to 1500 worked for the short term.</p><div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-51704177483016572242020-09-14T15:24:00.000+05:302020-09-14T15:24:13.245+05:30Gitk permissions on Alacritty<p>Recently, I started using <a href="https://github.com/alacritty/alacritty/wiki">Alacritty</a> instead of the Terminal app provided by Apple. It sure is much faster.</p><p>There seems to be a new and annoying security feature introduced by Apple that has granular permissions for applications downloaded from the internet. So, Alacritty does not start with the same permissions as Terminal. Setting that up is a bit of a hassle. When I started <code>gitk</code>, it asked for some permission and I could not understand it then so I denied it. So, <code>gitk</code> did not work. I thought restarting Alacritty might request permissions again but that is not the case. The error I was getting is as follows:</p><code><p> % gitk<br />Error in startup script: 58:102: execution error: Not authorised to send Apple events to System Events. (-1743)<br /> while executing<br />"exec osascript -e [format {<br /> tell application "System Events"<br /> set frontmost of processes whose unix id is %d to true<br /> end te..."<br /> invoked from within<br />"if {[tk windowingsystem] eq "aqua"} {<br /> exec osascript -e [format {<br /> tell application "System Events"<br /> set frontmost of processes ..."<br /> (file "/usr/local/bin/gitk" line 12261)</p></code><p>So, I had to find the right permission and grant that to get gitk working. The System Events permission is apparently under Automation section. Once that is granted, Alacritty can run <code>gitk</code>.<br /></p><div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-51036874528995700512020-01-20T19:12:00.000+05:302020-01-20T19:12:49.678+05:30Learning Puppet III: Installing modules<div dir="ltr" style="text-align: left;" trbidi="on">
In my previous <a href="https://intosimple.blogspot.com/2020/01/learning-puppet-ii-applying-classes.html" target="_blank">post</a>, we took a look at creating classes in Puppet and applying them locally. Let us look at installing Puppet modules next. Puppet does not install <code>stdlib</code> by default unlike other programming environments.<br />
<br />
Common functionalities like reading a JSON file are part of <code>stdlib</code> module. It can often come in handy. Installing it is <a href="https://forge.puppet.com/puppetlabs/stdlib" target="_blank">straightforward</a>. However, after installation the modules are not loaded at run time.<br />
<br />
Let us consider an example of reading a JSON file in a Puppet manifest. It can be an example of reading some config from an external resource.<br />
<br />
Let us consider the module <code>mod</code> which we created in the previous post.<br />
<br />
<code>class mod::test_json{<br />
include mod<br />
<br />
$hash = loadjson('/tmp/load.json')<br />
[$message, $return_value] = $hash['output']<br />
notice("$message, $return_value")<br />
<br />
}</code><br />
<br />
To test, let us create a file at with the following content.<br />
<br />
<code>{<br />
"output": {<br />
"message": "The value is: ",<br />
"return_value": "0"<br />
}<br />
}</code><br />
<br />
To apply the manifest, we can try running the following:<br />
<br />
<code>puppet apply --modulepath=/path/to/parent/of/module -e "include mod::test_json"</code><br />
<br />
This fails because <code>loadjson</code> is in <code>stdlib</code>. We need to enhance the module path to include stdlib as well. Modules are installed to the path <code>/etc/puppetlabs/code/environments/production/modules</code>. So, we need to modify our command as follows:<br />
<br />
<code>puppet apply --modulepath=/etc/puppetlabs/code/environments/production/modules:/vagrant/puppet -e "include elk::test_json"</code></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-55904369781627059742020-01-20T10:13:00.000+05:302020-01-20T10:13:02.059+05:30Learning Puppet - II: Applying Classes<div dir="ltr" style="text-align: left;" trbidi="on">
In my <a href="http://intosimple.blogspot.com/2019/04/learning-puppet.html" target="_blank">previous post</a> about learning Puppet, I left a few open questions that I will attempt to answer as I continue learning.<br />
<ol style="text-align: left;">
<li>How can I apply Puppet classes?</li>
<li>How can I install modules?</li>
<li>How can I define functions in Puppet?</li>
</ol>
In the last post, I was unable to apply a class so I moved ahead without it. Let us look at that in this post.<br />
<br />
To apply a class, I created a module, created its <code>init.pp</code> file and added a class in it.<br />
<br />
Let us consider the module name to be <code>mod</code>. The <code>init.pp</code> will be located at <code>mod/manifests/init.pp</code>. I just keep it empty to begin with. The name of the class in that file has to match the module name though.<br />
<br />
<code>class mod{<br />
}</code><br />
<br />
Moving on to create a class of interest, let us add one to install Openjdk. The file would be <code>mod/manifests/jdk.pp</code>.<br />
<br />
<code>class mod::jdk () {<br />
notice("Installing openJDK")<br />
# Install java<br />
package { 'openjdk':<br />
ensure => installed,<br />
name => 'java-1.8.0-openjdk-headless',<br />
alias => 'openjdk',<br />
}<br />
}</code><br />
<br />
To apply the manifest, the command would be as follows:<br />
<br />
<code>puppet apply --modulepath=/path/to/parent/of/module -e "include mod::jdk"</code></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-40025295257831455142019-12-18T01:34:00.002+05:302019-12-18T01:34:54.462+05:30jruby-launcher upgrade<div dir="ltr" style="text-align: left;" trbidi="on">
Logstash uses JRuby. So, while trying to read the code regarding an issue I was having in Logstash, I had installed JRuby and I had set up multiple Ruby versions using <code>rbenv</code>.<br />
<br />
To check whether the right version of Ruby is being used, I tried <code>ruby -v</code>. I was getting an error as follows.<br />
<br />
<span style="font-family: monospace;">2019-12-17T19:44:52.167+05:30 [main] WARN FilenoUtil : Native subprocess control requires open access to sun.nio.ch</span><br />
<span style="font-family: monospace;">Pass '--add-opens java.base/sun.nio.ch=org.jruby.dist' or '=org.jruby.core' to enable.</span><br />
<span style="font-family: monospace;">java.lang.IllegalCallerException: sun.nio.ch is not open to module org.jruby.dist</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at java.base/java.lang.Module.addOpens(Module.java:763)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/com.headius.backport9.modules.impl.Module9.addOpens(Module9.java:28)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/com.headius.backport9.modules.Modules.addOpens(Modules.java:22)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.util.io.FilenoUtil$ReflectiveAccess.<clinit>(FilenoUtil.java:140)</clinit></span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.util.io.FilenoUtil.getFilenoUsingReflection(FilenoUtil.java:111)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.util.io.FilenoUtil.filenoFrom(FilenoUtil.java:107)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.util.io.ChannelFD.initFileno(ChannelFD.java:42)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.util.io.ChannelFD.<init>(ChannelFD.java:32)</init></span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.RubyIO.<init>(RubyIO.java:174)</init></span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.RubyFile.<init>(RubyFile.java:281)</init></span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.parser.Parser.parse(Parser.java:99)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Ruby.parseFileAndGetAST(Ruby.java:2709)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Ruby.parseFileFromMainAndGetAST(Ruby.java:2702)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Ruby.parseFileFromMain(Ruby.java:2686)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Ruby.parseFromMain(Ruby.java:642)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Ruby.runFromMain(Ruby.java:588)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Main.doRunFromMain(Main.java:415)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Main.internalRun(Main.java:307)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Main.run(Main.java:234)</span><br />
<span style="font-family: monospace;"><span style="white-space: pre;"> </span>at org.jruby.dist/org.jruby.Main.main(Main.java:206)</span><br />
<span style="font-family: monospace;">jruby 9.2.7.0 (2.5.3) 2019-04-09 8a269e3 OpenJDK 64-Bit Server VM 11.0.5+10 on 11.0.5+10 +jit [darwin-x86_64]</span><br />
<br />
It didn't stop the printing of the version though.<br />
<br />
A bit of googling pointed to the <a href="https://github.com/jruby/jruby/issues/5736" target="_blank">discussion at JRuby Github repo</a> which further pointed to another <a href="https://github.com/jruby/jruby-launcher/issues/27" target="_blank">discussion in jruby-launcher repo</a>. I was not aware of the reason of the existence of <code>jruby-launcher</code> but it is an interesting take on a difficult situation.<br />
<br />
From the discussion, it seemed that the fix was available in version <code>1.1.10</code>. So, I tried looking at my <code>Gemfile.lock</code> to check the version I am using; but there was no version mentioned in that. However, it was present in the list of installed gems. I added the fixed version in the <code>Gemfile</code> and the issue was fixed.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-2317999750160114052019-08-28T11:30:00.001+05:302019-08-28T11:30:28.660+05:30Setting up jEnv<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
With OpenJDK, there is a need to have multiple JDK versions installed as there are many releases that are used by different projects. More and more projects are supporting multiple Java versions as well. This problem was not as prevalent in the Java ecosystem but the Ruby ecosystem had it long back. There are multiple tools to manage Ruby versions. The approach of <a href="https://github.com/rbenv/rbenv" target="_blank">rbenv</a> is probably the simplest. On the same lines, we have <a href="https://www.jenv.be/" target="_blank">jEnv</a> for Java.<br />
<br />
To setup jEnv, the steps are simple<br />
<br />
<ol style="text-align: left;">
<li>Install jEnv (<code>brew install jenv)</code></li>
<li>Setup shell profile (<code>~/.bash_profile</code>)</li>
<code>export PATH="$HOME/.jenv/bin:$PATH"<br />
eval "$(jenv init -)"</code>
<br />
<li>Install Java</li>
<li>Set local or shell version of Java (<code>jenv local openjdk64-1.8.0.192</code>)</li>
</ol>
</div>
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-75915970829101258372019-08-22T16:56:00.003+05:302019-08-22T16:56:37.552+05:30Jacoco instrumentation error<div dir="ltr" style="text-align: left;" trbidi="on">
In a Java project build, I was getting an error complaining about Jacoco failing to instrument a particular class. Looking at the complete stack trace of the error, it was an exception about index going out of bounds.<br />
<br />
<code>Caused by: java.lang.ArrayIndexOutOfBoundsException: 6<br />
<span style="white-space: pre;"> </span>at org.jacoco.core.internal.BytecodeVersion.get(BytecodeVersion.java:41)<br />
<span style="white-space: pre;"> </span>at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:87)<br />
<span style="white-space: pre;"> </span>at org.jacoco.core.instr.Instrumenter.instrument(Instrumenter.java:123)<br />
<span style="white-space: pre;"> </span>... 25 more<br />
</code>
Fortunately, a little bit of search <a href="https://github.com/jacoco/jacoco/issues/585" target="_blank">showed</a> that it is related to Java. My initial version of Java was '1.8.0.121'. The fix was backported to '1.8.0.172'. I also had '1.8.0.192' installed. So, I switched versions and tried a clean build. It worked fine.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-62994083979639584852019-04-16T22:38:00.004+05:302019-11-28T16:38:28.998+05:30Learning Puppet: Idempotence<div dir="ltr" style="text-align: left;" trbidi="on">
I am learning Puppet so I wanted to try out the manifests on a local VM. So, I created a Vagrant based Arch linux VM.<br />
<br />
<code>Vagrant.configure("2") do |config|<br />
config.vm.box = "archlinux/archlinux"<br />
config.vm.hostname = "learn.box"<br />
config.vm.synced_folder "puppet/", "/home/vagrant/puppet"<br />
end</code><br />
<br />
When I tried to bring the VM up, I got the following error.<br />
<br />
<code>Vagrant was unable to mount VirtualBox shared folders. This is usually<br />
because the filesystem "vboxsf" is not available. This filesystem is<br />
made available via the VirtualBox Guest Additions and kernel module.<br />
Please verify that these guest additions are properly installed in the<br />
guest. This is not a bug in Vagrant and is usually caused by a faulty<br />
Vagrant box. For context, the command attempted was:<br />
<br />
mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant<br />
<br />
The error output from the command was:<br />
<br />
: Invalid argument</code>
<br />
<br />
It did not stop the VM from coming up so I was able to test. I created the following manifest to start with and it worked fine.<br />
<br />
<code>file {<br />
'/tmp/motd': content => 'hello puppet'<br />
}</code>
<br />
<br />
I moved on to actually installing a package.<br />
<br />
<code>class logstash{<br />
package{<br />
"logstash":<br />
name => "logstash",<br />
alias => "logstash",<br />
ensure => "7.0"<br />
}</code><br />
<code>}</code>
<br />
<br />
I tried to apply it using the following:<br />
<br />
<code>puppet apply logstash.pp -v</code>
<br />
<br />
The package was not installed. I soon figured out it was because, I was not applying the class. So, I modified the manifest to the following:<br />
<br />
<code> package{<br />
"logstash":<br />
name => "logstash",<br />
alias => "logstash",<br />
ensure => "7.0"<br />
}</code>
<br />
<br />
Now Puppet tried to install the package but it failed with the following error.<br />
<br />
<code>Error: Parameter ensure failed on Package[logstash]: Provider pacman must have features 'versionable' to set 'ensure' to '7.0' (file: /home/vagrant/logstash.pp, line: 2)</code>
<br />
<br />
Arch linux uses <code>pacman</code> as its package manager and Puppet was trying to install a specific version of the package using that. However, <code>pacman</code> does not support different versions of the same package. So, Puppet can't ensure a specific version. So, I changed the manifest to the following:<br />
<br />
<code> package{<br />
"logstash":<br />
name => "logstash",<br />
alias => "logstash",<br />
ensure => "installed"<br />
}</code>
<br />
Now, Puppet attempted to install the package again and hit the following error.<br />
<br />
<code>Error: Execution of '/usr/bin/pacman --noconfirm --needed --noprogressbar -Sy logstash' returned 1: error: you cannot perform this operation unless you are root.<br />
Error: /Stage[main]/Main/Package[logstash]/ensure: change from 'absent' to 'present' failed: Execution of '/usr/bin/pacman --noconfirm --needed --noprogressbar -Sy logstash' returned 1: error: you cannot perform this operation unless you are root.</code>
<br />
<br />
So, I attempted using sudo. The process was taking time. I waited for some time then interrupted it and tried to see the logs. The logs seemed fine so I started again and the this time I got the following error.<br />
<br />
<code>Error: Execution of '/usr/bin/pacman --noconfirm --needed --noprogressbar -Sy logstash' returned 1: :: Synchronizing package databases...<br />
error: failed to update core (unable to lock database)<br />
error: failed to update extra (unable to lock database)<br />
error: failed to update community (unable to lock database)<br />
error: failed to synchronize all databases<br />
Error: /Stage[main]/Main/Package[logstash]/ensure: change from 'absent' to 'present' failed: Execution of '/usr/bin/pacman --noconfirm --needed --noprogressbar -Sy logstash' returned 1: :: Synchronizing package databases...<br />
error: failed to update core (unable to lock database)<br />
error: failed to update extra (unable to lock database)<br />
error: failed to update community (unable to lock database)<br />
error: failed to synchronize all databases</code>
<br />
<br />
This is specific to <code>pacman</code>. As I had interrupted the execution, the lock file was not deleted, i.e. <code>pacman</code> had not cleaned up properly. I manually removed the lock file from <code>/var/lib/pacman/db.lck</code> and tried to apply the manifest again. It completed successfully and logstash was installed on the VM. Now, it is established that the script works but it might need manual intervention. In other words, the manifest needs to be idempotent so that manual intervention is minimal.<br />
<br />
To achieve that, I modified the manifest as follows.<br />
<br />
<code> package{<br />
"logstash":<br />
name => "logstash",<br />
alias => "logstash",<br />
ensure => "installed"<br />
}<br />
file{<br />
"/var/lib/pacman/db.lck":<br />
path => "/var/lib/pacman/db.lck",<br />
name => "/var/lib/pacman/db.lck",<br />
ensure => "absent"<br />
}</code>
<br />
To test that the manifest is idempotent, I removed logstash and applied the manifest. Midway, I interrupted the execution and re-applied the manifest. This time re-application succeeded. The logs show that the lock file was created when the manifest was applied the previous time and interrupted. It was deleted when the manifest was applied again.<br />
<br />
<code>Info: Applying configuration version '1555432879'<br />
Info: Computing checksum on file /var/lib/pacman/db.lck<br />
Info: /Stage[main]/Main/File[/var/lib/pacman/db.lck]: Filebucketed /var/lib/pacman/db.lck to puppet with sum d41d8cd98f00b204e9800998ecf8427e<br />
Notice: /Stage[main]/Main/File[/var/lib/pacman/db.lck]/ensure: removed<br />
Notice: Applied catalog in 0.25 seconds</code>
<br />
<b><br /></b>
<b>Key take-aways:</b><br />
<ol style="text-align: left;">
<li>Puppet is a framework that depends on providers to install packages and its capabilities are as good as the providers.</li>
<li>Without idempotent behaviour, Puppet manifests will not be achieve much of automation.</li>
</ol>
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-61409775365568173852019-01-21T18:56:00.000+05:302019-01-21T18:56:10.725+05:30Finding where a package is installed<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Recently, I faced an issue on a CentOS box where I had to find the location of a package. My application was running on it and I wanted to modify its config. I was unable to pick the config in <code>/etc</code> so I figured it must be in the folder in which the application is installed.<br />
<br />
The application was installed as a daemon but it seems the <code>PATH</code> was not updated. I searched in the usual locations of binaries and packages but I could not find it. The only option left for me was to find out where it was installed.<br />
<br />
Using the following command showed all the files of the application package.<br />
<br />
<code>rpm -ql <my application></code></div>
<br />
From the list, I could see where my config file was placed during install.
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-26344825616922544892019-01-18T03:18:00.003+05:302019-01-18T03:18:59.000+05:30Unexpected exit of Elasticsearch container<div dir="ltr" style="text-align: left;" trbidi="on">
I was trying the Elasticsearch container image on docker hub. I was disappointed by the complete lack of error message in the following scenario.<br />
<br />
I had my setup defined in a compose file. When I tryed to start the container, I got only the following log line.<br />
<br />
<code>OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.</code>
<br />
<br />
As it is a warning, I expected the container to start but it had not started. Digging a bit more, I found that the exit code was 137 which meant the container needed more memory than the docker daemon was configured for. The fix is quite easy of course but I think it could have been communicated better.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-45497188436989821472018-10-05T17:16:00.001+05:302018-10-05T17:16:24.235+05:30Correctly restarting syslog on Mac OS X<div dir="ltr" style="text-align: left;" trbidi="on">
For some experimentation, I was recently looking at restarting syslog daemon. I expected it to be as simple as Linux system daemons. The init system of Mac appeared to be more like systemd in my initial searches. A few <a href="http://blog.bekyarov.info/restart-syslog-daemon-on-mac-os-x/" target="_blank">blogs</a> instructed unload followed by load operation which sounded strange to me.<br />
<br />
In systemd parlance, I expected unload operation to disable the daemon from starting up during initial booting. If you try to follow the process suggested in these blogs, you end up with an error stating "Operation not permitted while System Integrity Protection is engaged". This leaves two options:<br />
<br />
<ol style="text-align: left;">
<li>Disable System Integrity Protection</li>
<li>Restart the system for every change in config</li>
</ol>
<div>
Of course, the answer is far too simple and none of these complexities need to handled. The right way of restarting the syslog daemon is as follows (using stop and start operations instead of unload and load):</div>
<div>
<br /></div>
<code>
</code>
<div>
<code>sudo launchctl stop /System/Library/LaunchDaemons/com.apple.syslogd.plist</code></div>
<code>
<div>
sudo launchctl start /System/Library/LaunchDaemons/com.apple.syslogd.plist</div>
</code>
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-40495102081745137732018-09-25T00:47:00.000+05:302018-09-25T00:47:22.622+05:30Hello OSGi<div dir="ltr" style="text-align: left;" trbidi="on">
I found existing guides for OSGi to be a bit outdated. So, it is probably better to document the basic setup.<br />
<br />
The plan is to first create a consumable bundle, i.e. a service bundle followed by a consumer bundle that uses the former.<br />
<br />
I am also using maven for creating the projects so that the maven toolchain can be used for proper packaging.<br />
<br />
For the consumable bundle, we start with defining an interface that exposes functionality of the bundle.<br />
<br />
<code>package main.java.interfaces;<br />
<br />
public interface TestService {<br />
void hello();<br />
}<br />
</code>
<br />
<div>
<br /></div>
<div>
We then implement it.</div>
<div>
<br /></div>
<div>
<div>
<code>package main.java.impls;</code></div>
<code>
</code>
<br />
<div>
<code><br /></code></div>
<code>
</code>
<br />
<div>
<code>import main.java.interfaces.TestService;</code></div>
<code>
</code>
<br />
<div>
<code><br /></code></div>
<code>
</code>
<br />
<div>
<code>public class TestServiceImpl implements TestService {</code></div>
<code>
</code>
<br />
<div>
<code> @Override</code></div>
<code>
</code>
<br />
<div>
<code> public void hello() {</code></div>
<code>
</code>
<br />
<div>
<code> System.out.println("Hello Duniya");</code></div>
<code>
</code>
<div>
<code> }</code></div>
<code>
<div>
}</div>
</code>
</div>
<div>
<br /></div>
We then add the activation logic for the bundle.<br />
<br />
<code>
package main.java.provider;<br />
<br />
import org.osgi.framework.BundleActivator;<br />
import org.osgi.framework.BundleContext;<br />
import org.osgi.framework.ServiceRegistration;<br />
<br />
import main.java.interfaces.TestService;<br />
import main.java.impls.TestServiceImpl;<br />
<br />
public class ServiceActivator implements BundleActivator {<br />
private ServiceRegistration registration;<br />
<br />
@Override<br />
public void start(BundleContext bundleContext) throws Exception {<br />
registration = bundleContext.registerService(<br />
TestService.class.getName(),<br />
new TestServiceImpl(),<br />
null);<br />
System.out.println("ServiceActivator started");<br />
}<br />
<br />
@Override<br />
public void stop(BundleContext bundleContext) throws Exception {<br />
registration.unregister();<br />
}<br />
}<br />
</code><br />
<div>
<code><br /></code></div>
<code>
</code>
<br />
<div>
We complete this bundle by adding a POM for building it.</div>
<br />
<code>
</code>
<br />
<div>
<code><br /></code>
<br />
<div class="p1">
<code><?xml version="1.0" encoding="UTF-8"?></code></div>
<div class="p1">
<code><project xmlns="http://maven.apache.org/POM/4.0.0"</code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span>xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><modelVersion>4.0.0</modelVersion></code></div>
<div class="p2">
<code><br /></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><groupId>felix_test</groupId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><artifactId>felix_test</artifactId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><version>1.0</version></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><packaging>bundle</packaging></code></div>
<div class="p2">
<code><br /></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><dependencies></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><dependency></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><groupId>org.osgi</groupId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><artifactId>org.osgi.core</artifactId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><version>6.0.0</version></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></dependency></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></dependencies></code></div>
<div class="p2">
<code><br /></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><build></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><plugins></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><plugin></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><groupId>org.apache.maven.plugins</groupId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><artifactId>maven-compiler-plugin</artifactId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><version>2.0.2</version></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><configuration></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><source>1.6</source></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><target>1.6</target></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></configuration></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></plugin></code></div>
<div class="p2">
<code><br /></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><plugin></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><groupId>org.apache.felix</groupId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><artifactId>maven-bundle-plugin</artifactId></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><extensions>true</extensions></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><configuration></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><instructions></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><Bundle-SymbolicName>felix_test</Bundle-SymbolicName></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><Export-Package>main.java.interfaces</Export-Package></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><Bundle-Activator>main.java.provider.ServiceActivator</Bundle-Activator></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span><Bundle-Vendor>Amitav Mohanty</Bundle-Vendor></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></instructions></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></configuration></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></plugin></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></plugins></code></div>
<div class="p1">
<code><span class="Apple-converted-space"> </span></build></code></div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
</style><code>
</code>
<br />
<div class="p1">
<code></project></code></div>
<code><br /></code></div>
<code>
</code>
<br />
<div>
The package of interfaces that are to be exposed are called out along with the activator so that the maven toolchain can build our bundle properly.<br />
<br />
We move on to create the consumer bundle next. We start with the bundle activator.<br />
<br />
<code>
package main.java.consumer;<br />
<br />
import main.java.interfaces.TestService;<br />
import org.osgi.framework.BundleActivator;<br />
import org.osgi.framework.BundleContext;<br />
import org.osgi.framework.ServiceReference;<br />
<br />
public class FelixTestActivator implements BundleActivator {<br />
@Override<br />
public void start(BundleContext bundleContext) throws Exception {<br />
ServiceReference reference = bundleContext.getServiceReference(TestService.class.getName());<br />
consumer = new TestConsumer((TestService)bundleContext.getService(reference));<br />
consumer.startTimer();<br />
}<br />
<br />
@Override<br />
public void stop(BundleContext bundleContext) throws Exception {<br />
consumer.stopTimer();<br />
}<br />
<br />
private TestConsumer consumer;<br />
}</code></div>
<div>
<br /></div>
<div>
We then add the consumer.</div>
<div>
<br /></div>
<code>
</code>
<br />
<div>
<div>
<code>package main.java.consumer;</code></div>
<div>
<code><br /></code></div>
<div>
<code>import main.java.interfaces.TestService;</code></div>
<div>
<code><br /></code></div>
<div>
<code>import javax.swing.Timer;</code></div>
<div>
<code>import java.awt.event.ActionEvent;</code></div>
<div>
<code>import java.awt.event.ActionListener;</code></div>
<div>
<code><br /></code></div>
<div>
<code>public class TestConsumer implements ActionListener {</code></div>
<div>
<code> @Override</code></div>
<div>
<code> public void actionPerformed(ActionEvent e) {</code></div>
<div>
<code> service.hello();</code></div>
<div>
<code> }</code></div>
<div>
<code><br /></code></div>
<div>
<code> public TestConsumer(TestService service){</code></div>
<div>
<code> super();</code></div>
<div>
<code> this.service = service;</code></div>
<div>
<code> timer = new Timer(1000, this);</code></div>
<div>
<code> }</code></div>
<div>
<code><br /></code></div>
<div>
<code> public void startTimer(){</code></div>
<div>
<code> timer.start();</code></div>
<div>
<code> }</code></div>
<div>
<code><br /></code></div>
<div>
<code> public void stopTimer(){</code></div>
<div>
<code> timer.stop();</code></div>
<div>
<code> }</code></div>
<div>
<code><br /></code></div>
<div>
<code> private final TestService service;</code></div>
<div>
<code> private final Timer timer;</code></div>
<div>
<code><br /></code></div>
<div>
<code>}</code></div>
</div>
<code>
</code>
<br />
<div>
<br /></div>
<div>
The initiation of the consumer happens when the bundle is started.<br />
<br />
The POM for building the consumer bundle is as follows:<br />
<br />
<code>
<?xml version="1.0" encoding="UTF-8"?><br />
<project xmlns="http://maven.apache.org/POM/4.0.0"<br />
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><br />
<modelVersion>4.0.0</modelVersion><br />
<groupId>consumer</groupId><br />
<artifactId>consumer</artifactId><br />
<version>1.0</version><br />
<packaging>bundle</packaging><br />
<br />
<dependencies><br />
<dependency><br />
<groupId>org.osgi</groupId><br />
<artifactId>org.osgi.core</artifactId><br />
<version>6.0.0</version><br />
</dependency><br />
<br />
<dependency><br />
<groupId>felix_test</groupId><br />
<artifactId>felix_test</artifactId><br />
<version>1.0</version><br />
<scope>system</scope><br />
<systemPath>${basedir}/../target/felix_test-1.0.jar</systemPath><br />
</dependency><br />
</dependencies><br />
<br />
<build><br />
<plugins><br />
<plugin><br />
<groupId>org.apache.maven.plugins</groupId><br />
<artifactId>maven-compiler-plugin</artifactId><br />
<version>2.0.2</version><br />
<configuration><br />
<source>1.6</source><br />
<target>1.6</target><br />
</configuration><br />
</plugin><br />
<br />
<plugin><br />
<groupId>org.apache.felix</groupId><br />
<artifactId>maven-bundle-plugin</artifactId><br />
<extensions>true</extensions><br />
<configuration><br />
<instructions><br />
<Bundle-SymbolicName>consumer</Bundle-SymbolicName><br />
<Bundle-Activator>main.java.consumer.FelixTestActivator</Bundle-Activator><br />
<Bundle-Vendor>Amitav Mohanty</Bundle-Vendor><br />
</instructions><br />
</configuration><br />
</plugin><br />
</plugins><br />
</build><br />
</project></code></div>
<div>
<br /></div>
<div>
The dependency on the other bundle is called out.<br />
<br />
The "packaging" node in the POMs is essential for creating OSGi bundles.</div>
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-74447984176409084482018-05-09T03:21:00.000+05:302018-05-09T03:21:07.531+05:30Backward compatibility in user experience<div dir="ltr" style="text-align: left;" trbidi="on">
Gmail recently launched a new design. I tried it out of curiousity. The first thing I noticed was that my muscle memory started failing me. Every time a new design comes, people focus on the look and feel of the design, its intuitiveness and other such factors but its compatibility with old design is not taken into account ever.<br />
<br />
Power users tend to build muscle memory even for UIs. I tend to move my mouse to a particular location on the screen for the delete button for example.<br />
<br />
With a product that has so many existing users, I think GMail should pay attention to these details as well when planning a new design. So, should other companies with similar products. An epic failure in the same lines is removal of start button by Microsoft. Of course a button position is not as critical; but the point is to have this criterion included in the design process.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-75845826236117271292018-01-31T01:50:00.000+05:302018-01-31T01:50:42.700+05:30Testing filebeat<div dir="ltr" style="text-align: left;" trbidi="on">
For testing codecs like multiline, the <a href="https://www.elastic.co/guide/en/beats/filebeat/current/_test_your_regexp_pattern_for_multiline.html" target="_blank">recommendation</a> is to try the Go playground website. However, before making a config live, it can be tested locally also; using input from stdin and printing output to the console. The following config can be used as skeleton.<br />
<br />
<code>filebeat.prospectors:<br />
- input_type: stdin<br />
<br />
output:<br />
console:<br />
pretty: true</code></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-85960549757746568162018-01-12T16:13:00.001+05:302018-01-12T16:13:28.635+05:30Ola does not support Amex<div dir="ltr" style="text-align: left;" trbidi="on">
As per their FAQs, Ola claims to support Amex cards.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkPTlfhHL8SLN8KHD6Uz5pGeu224_iZ5Pb-vGD-E8M-D7aL7dZ45aje_ASwtS5_ATU5kQ6IXDmC7v9O4hU-89sXD1hBF1oQ9umWnOy58C8jmAqjysC05i3jvg_tF9HnJxTLr6VDFf0JF4/s1600/Screenshot_20180110-111947.png" imageanchor="1"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkPTlfhHL8SLN8KHD6Uz5pGeu224_iZ5Pb-vGD-E8M-D7aL7dZ45aje_ASwtS5_ATU5kQ6IXDmC7v9O4hU-89sXD1hBF1oQ9umWnOy58C8jmAqjysC05i3jvg_tF9HnJxTLr6VDFf0JF4/s640/Screenshot_20180110-111947.png" width="360" /></a><br />
<br />
However, when an attempt is made to add an Amex card, an error is shown as following.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_WrmY4A4_x8v-vsr4oIVnXA_vnOcd4S728PJ6IJkuAovJypT-EGVATdlBRoPieY6va2APgnvogTNyEw4L5PCLZLVENms5j6oGFNHdKqjzXoyJj5BxzIj_JylyuO6fWuA9MJUOaZES-1M/s1600/Screen+Shot+2018-01-12+at+3.44.34+PM.png" imageanchor="1"><img border="0" height="253" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_WrmY4A4_x8v-vsr4oIVnXA_vnOcd4S728PJ6IJkuAovJypT-EGVATdlBRoPieY6va2APgnvogTNyEw4L5PCLZLVENms5j6oGFNHdKqjzXoyJj5BxzIj_JylyuO6fWuA9MJUOaZES-1M/s400/Screen+Shot+2018-01-12+at+3.44.34+PM.png" width="400" /></a><br />
<br />
The explanation provided by Ola is as follows.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Y2d66-vrW-geXB0pMjxWzTgp71VYTamD89Nk600ljJoG_wjlAnLTxyH67aD4Sf7EeN9ft2WFjUjr8kTFIBldmqZHyb6XsxpW_3XJIL30PHA0Ei469ksGk-qLBcgM-q-ELYVGidr2IaM/s1600/Screen+Shot+2018-01-12+at+4.02.18+PM.png" imageanchor="1"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6Y2d66-vrW-geXB0pMjxWzTgp71VYTamD89Nk600ljJoG_wjlAnLTxyH67aD4Sf7EeN9ft2WFjUjr8kTFIBldmqZHyb6XsxpW_3XJIL30PHA0Ei469ksGk-qLBcgM-q-ELYVGidr2IaM/s400/Screen+Shot+2018-01-12+at+4.02.18+PM.png" width="386" /></a><br />
<br />
I don't understand why is this clarity is not provided in the FAQ.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-69612803915803708852018-01-02T23:28:00.000+05:302018-01-02T23:28:31.799+05:30KActivityManager blocking unmounting<div dir="ltr" style="text-align: left;" trbidi="on">
While un-mounting a partition to safely remove the external hard drive, I got an error about the device being busy. Both <a href="https://www.kde.org/applications/system/dolphin/" target="_blank">Dolphin</a> and the command line said the same thing.<br />
<span style="font-family: monospace;"><span style="background-color: white;"><br /></span></span>
<span style="font-family: monospace;"><span style="background-color: white;">umount /run/media/myuser/New\ Volume/
</span><br />umount: /run/media/<span style="background-color: white;">myuser</span>/New Volume: target is busy.</span><br />
<span style="font-family: monospace;"><br /></span>
It seems <a href="https://github.com/KDE/kactivitymanagerd" target="_blank">kactivitymanagerd</a> was using it.<br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;"><span style="background-color: white;">[root@clown myuser]# fuser -vm /run/media/myuser/New\ Volume/
</span><br /> USER PID ACCESS COMMAND
<br />/run/media/<span style="background-color: white;">myuser</span>/New Volume:
<br /> <span style="background-color: white;">myuser</span> 612 ..c.. kactivitymanage<br />
</span><br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;"><span style="font-family: Times;">I tried to stop the daemon but I got the following error.</span></span><br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;"><span style="background-color: white;">root@clown myuser]# /usr/bin/kactivitymanagerd
</span><br />QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0<br />
</span><br />
<span style="font-family: monospace;"><br /></span>After some discussion on Freenode, I got to know that when graphical apps are run with escalated priviledges, similar error is found. I guessed I was getting the error because I was trying to stop the daemon as root user. I tried changing back to my regular user and stopping the daemon. It worked and I was able to unmount the drive after that.<br />
<span style="font-family: monospace;"><br /></span>
<span style="font-family: monospace;"><span style="background-color: white;">/usr/bin/kactivitymanagerd stop
</span><br />Service stopped
<br />Cleaning up...<br />
</span><br />
<span style="font-family: monospace;"><br /></span></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-75092622400115652432017-12-05T22:07:00.000+05:302017-12-05T22:07:04.883+05:30Benchmarking elasticsearch and logstash pipeline<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Elasticsearch and logstash pipelines can be elaborate or simple. Depending upon the setup, end to end benchmarking should be done time to time. One way to do it is to have a marker document (log line). We need to track when the marker is introduced into the pipeline and finally when it becomes available to query.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<code>import urllib2</code></div>
<code>
</code>
<br />
<div style="text-align: justify;">
<code>import json</code></div>
<code>
</code>
<br />
<div style="text-align: justify;">
<code>from datetime import datetime</code></div>
<code>
</code>
<br />
<div style="text-align: justify;">
<code>import sys</code></div>
<code>
</code>
<br />
<div style="text-align: justify;">
<code>import time</code></div>
<code>
</code>
<div style="text-align: justify;">
<code><br /></code></div>
<code>
<div style="text-align: justify;">
print "Started at " + str(datetime.now())</div>
<div style="text-align: justify;">
if len(sys.argv) < 2:</div>
<div style="text-align: justify;">
print "URL not specified.\nUsage: watch.py <url query="" to="">"</url></div>
<div style="text-align: justify;">
exit(1)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
count = 0</div>
<div style="text-align: justify;">
while count < 1:</div>
<div style="text-align: justify;">
resp = urllib2.urlopen(sys.argv[1]).read()</div>
<div style="text-align: justify;">
count = json.loads(resp)["hits"]["total"]</div>
<div style="text-align: justify;">
if count > 0:</div>
<div style="text-align: justify;">
print "Found at " + str(datetime.now())</div>
<div style="text-align: justify;">
break</div>
<div style="text-align: justify;">
time.sleep(2)</div>
</code><br />
<div>
<br /></div>
The above script can be used as follows:<br />
<div>
<br /></div>
<div>
<code>python <script_file> "http://<host_name>:<port_number>/_search?q=message:<markerMessage>"</code>
</div>
</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-84857164177519040482017-11-16T21:19:00.005+05:302017-11-16T21:19:59.689+05:30Toggle Read-only behaviour of buffer in Emacs<div dir="ltr" style="text-align: left;" trbidi="on">
When a file to which you have read access as regular user is opened in emacs, the buffer is marked read-only. If the user escalates to root and opens the same file in emacs, the buffer still remains read-only. To modify the file, the user needs to toggle the read-only behaviour of the buffer (for which the default key binding is C-x C-q) first.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-3280655973263962752017-11-16T17:25:00.001+05:302017-11-16T17:25:40.457+05:30Increasing the maximum number of file descriptors allowed per user on Cent OS 6<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
For some applications like elasticsearch, the maximum number of file descriptors needs to quite high. The way of modifying the value varies from distro to distro. In Cent OS6, the following did not work.<br />
<br />
1. Using <code>sysctl</code> as root<br />
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;"><code>sysctl -w fs.file-max=100000</code></span><br />
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;"><br /></span>
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;">2. Using <code>ulimit</code> as root</span><br />
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;"><br /></span>
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;">After the above approaches, when you check the value using the following, the value will show up.</span><br />
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;"><br /></span>
<span style="background-color: white; font-family: "calibri"; font-size: 14.6667px;"><span style="font-size: 14.6667px; text-size-adjust: auto;"><code>cat /proc/sys/fs/file-max</code></span></span><br />
<br />
However, setting the values as root, does not change the values for other regular users. To set it specifically for any user, change the value in <code>/etc/security/limits.conf</code> file. Setting only the soft or hard limit will not be sufficient. Therefore, the following lines should be added.<br />
<br />
<user> soft nofile <value></div>
<br />
<user> hard nofile <value>
<br />
<br />
After the modifications, it is required to logout and log back into the system.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-23333331035102569712017-10-30T23:43:00.001+05:302017-10-30T23:43:23.335+05:30Manually install maven dependency<div dir="ltr" style="text-align: left;" trbidi="on">
Error messages from Maven are often useless. The root cause is mostly never captured. Debugging issues might require manually installing a dependency. The way to do it is as follows:<br />
<br />
<code>mvn install:install-file -DgroupId=jnuit -DartifactId=junit -Dversion=3.8.1 -Dpackaging=jar -Dfile=/path/to/file</code></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-65000882891477880682017-10-15T18:12:00.001+05:302017-10-15T18:12:54.417+05:30Correct do...while in Ruby<div dir="ltr" style="text-align: left;" trbidi="on">
Rubyists use the <code>.each</code> or <code>.map</code> way of looping frequently. However, when there is a need of a <code>while</code> loop, the following is the <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745" target="_blank">correct way</a>.<br />
<code>loop do<br />
# statements<br />
break if condition<br />
end</code></div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-34986405776214932972017-05-07T12:58:00.000+05:302017-05-07T12:58:10.254+05:30Getting method name within the same method<div dir="ltr" style="text-align: left;" trbidi="on">
For logging in some server side javascript, I had the need of getting the name of the method within the same method. There are 2 ways of doing this:<br />
- accessing <code>arguments.callee.toString()</code> and applying regex extraction to get the name<br />
- accessing <code>arguments.callee.name</code><br />
<br />
It does not always work though. ECMA strict mode does not allow it but their is no alternative either.</div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0tag:blogger.com,1999:blog-1600341619162257657.post-22476317183800535772017-03-01T22:12:00.000+05:302017-03-01T22:21:07.272+05:30Unable to locate "adwaita" theme engine<div dir="ltr" style="text-align: left;" trbidi="on">
While running KDE on Arch linux, on a number of occassions, I get to see the following error.<br />
<br />
<code>(java:20732): Gtk-WARNING **: Unable to locate theme engine in module_path: "adwaita"</code><br />
<br />
<code>[828:828:0708/183334:ERROR:browser_main_loop.cc(249)] GTK theme error: Unable to locate theme engine in module_path: "adwaita"</code><br />
<br />
The mitigation of the issue is installation of <code>gnome-themes-standard</code> package. </div>
<div class="blogger-post-footer">I would like to hear your suggestions and feedback.</div>Phoenixhttp://www.blogger.com/profile/18150624810921348256noreply@blogger.com0