tag:blogger.com,1999:blog-1368627430528849562024-03-23T03:14:44.643-07:00Hacker's ValhallaHacker's - People who do great things with computers
Valhalla - In Norse myth, an afterlife of never ending battle.
Hacker's Valhalla - A Java Blog for info in the never ending battle of releases.
A focus on Spring, Testing and WebLogic Server.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.comBlogger116125tag:blogger.com,1999:blog-136862743052884956.post-13602794617716682362024-02-12T10:30:00.000-08:002024-02-12T10:30:46.519-08:00Rebooting Shell Scripting and this Blog<p> This blog is now the official blog of Bashpile: The Bash Transpiler!</p><p><br /></p><p>A transpiler is a compiler that produces a different language. This means that you can write in a modern, clean syntax and still have code that runs on any Linux or Unix platform that supports Bash scripts!</p><p><br /></p><p>More details are at the main page: <a href="https://github.com/michael-amiethyst/homebrew-bashpile">https://github.com/michael-amiethyst/homebrew-bashpile</a></p>Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-55293801807468171422017-12-07T14:08:00.003-08:002017-12-07T14:10:41.924-08:00Studying and passing the AWS Developer Associate ExamAmazon Web Services has been around for over a decade now and has offerings that continue to grow. They also have over a <a href="https://techcrunch.com/2017/10/30/aws-continues-to-rule-the-cloud-infrastructure-market/">35% market share</a>. Lastly the Developer Associate exam seems to come up on "best programmer certs" type of posts (e.g. <a href="https://www.pluralsight.com/blog/software-development/best-developer-certifications">here</a>).<br />
<br />
So if you're convinced that it's a good idea to get a cert, how do you do it? What should you study? No one wants to waste a day and over a hundred dollars to take a test and then fail it. This post will go over some of the best resources to use to study.<br />
<br />
When I studied for the exam and passed it, these were the most useful resources, in order:<br />
<br />
<ol>
<li>ACloudGuru has a fantastic series of videos that covers everything on the test is broad strokes, but is detailed enough to give you a real advantage on the test. The training isn't free but it is quite reasonable and you literally get hours of content.</li>
<li>The AWS Documentation will have the details you need, but usually in a format geared for your day-to-day developer work instead of in a Q/A format.</li>
<li>On-the-job experience is great too. However experience will usually have you do a deep-dive on one or two technologies (e.g. migrate something to EC2 and S3) instead of a broad overview of the entire platform. This overview is what the test is going to be about.</li>
<li>The AWS FAQs have some information and are in a good Q/A format, but rarely mention anything on the test.</li>
<li>The AWS Whitepapers are recommended on Amazon's page of test tips, but was not really useful at all. You would probably be better prepared by reading the <a href="https://en.wikipedia.org/wiki/Amazon_Web_Services">Wikipedia page's list of AWS services</a>.</li>
</ol>
<div>
The test itself was in a bit of an odd location. When I took it the facility was primarily used for aviation testing. Needless to say, when you're waiting in line with people needing pilot's licenses you wonder if you got the address wrong. So don't worry if you get directed to an airport, or near one. Also, at my location only two other people were taking the test and I was expecting more of a classroom like situation (e.g. 15+ people taking the test at the same time). Overall, the experience wasn't that bad. The questions mostly matched up with the preparation questions from ACloudGuru but not entirely.</div>
<div>
<br /></div>
<div>
Lastly, some companies will pay for your tests and training. If you're really lucky you'll be with a company that needs a certain headcount of certified developers in order to qualify to be some kind of "premium partner" with AWS.</div>
<div>
<br /></div>
<div>
All in all, it required a fair chunk of time to study but you end up with a really good overview of the (now large) AWS ecosystem of services as well as a boost to your resume.</div>
Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636695 -122.9775178 47.9487495 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-89096598308339823262016-07-28T15:19:00.000-07:002016-07-28T15:19:59.841-07:00Writing Effective Exception Descriptions<h2>
Introduction </h2>
Writing exception descriptions are not really taught in programming classes but are vitally important in the field. Namely if you need to refine your descriptions to find a problem it can lead to multiple pushes to a production environment before you actually fix the problem. Depending on the issue this could waste valuable time.<br />
<br />
Between reading about how to write good exception descriptions from various companies and my
personal experience I've accumulated the following tips
to share. Note that most of the time exception text bubbles into your log files so some references to log files will be mentioned as well.<br />
<h2>
Be Layer-Centric </h2>
If you catch an exception and re-throw, describe the problem in the terms of the current (throwing) layer. As an example, if you are writing TCP/IP library code and catch an IP exception, state your TCP problems. If you are (ab)using TCP for Inter-Process Communication (IPC), state the process you are trying to reach. I have mistakenly thought there was a networking error when a program couldn't connect to localhost before.<br />
<h2>
Not a Singleton? Include your object ID</h2>
Imagine a case where there is a complex object with invariants. With two instances of the class logging at the same it could easily appear to violate it's invariants or demonstrate impossible behavior. Imagine your TCP class logging that it closed the connection and then that it read data successfully - this could be very confusing. With object IDs you would log that client 1 closed the connection and client 2 read successfully - this makes much more sense.<br />
<h2>
Multi-threaded? Include your Thread ID</h2>
Some times you need to trace the execution flow in a particular thread. If you do not include your Thread IDs this is an impossible task to do via the logs.<br />
<h2>
Don't Trust Library Exceptions</h2>
Frequently exceptions generated by library, module or component code is not very descriptive. Continuing with the networking examples I've had many HTTP exceptions with no more description than "Bad Request". Note the lack of IP address, host name, or port. Given that exceptions turn into logs that then can go into various applications (e.g. Splunk) I think the descriptions are generic due to security concerns.<br />
<h2>
Include Some Variables</h2>
Try to include one or two other things to help you track down a problem, knowing WHAT from following the recommendations above won't necessarily help you figure out WHY.<br />
<h2>
Make it easy</h2>
When you write your subclass consider including a String.format style constructor. This would let you avoid having to do a String.format call on every exception you need to throw. Alternatively you could make an ExecptionDescription builder that includes the object ID and Thread ID automatically.<br />
<h2>
Conclusion</h2>
In conclusion if you plan ahead and write descriptive exception messages that let you track the instance, the thread and some internal state you will be able to diagnose (possibly critical) issues much faster.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-20754321149794872372016-07-12T13:21:00.000-07:002016-07-14T10:32:16.751-07:00Overview of JSON Libraries and How to Choose a Library<h2>
Welcome </h2>
It's good to be back. The blog had an expected hiatus while I moved to a new city, also around Seattle.<br />
<h2>
Intro </h2>
Many of my posts are about overcoming unexpected difficulties when using some software library or module or another. I decided to take a step back and try to select a quality module in the first place. This is my analysis of the <a href="http://www.json.org/">JSON</a> libraries I was able to find and can count as a how-to to select a library in general.<br />
<br />
The short result is that if a Library is in <a href="https://maven.apache.org/">Maven</a>, you can look at Maven Central to see how popular a library is and how frequently it is updated. Then you can use one of the most used and updated libraries out there. You can also consult <a href="http://stackoverflow.com/questions/2591098/how-to-parse-json-in-java">StackOverflow</a>. Here are some examples. <br />
<h2>
The List</h2>
<ul>
<li>JSR 353 - We have <a href="https://mvnrepository.com/artifact/javax.json/javax.json-api">javax.json-api</a> and <a href="https://mvnrepository.com/artifact/org.glassfish/javax.json">org.glassfish/javax.json</a>. Out of these two the <table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://blog.smartbear.com/wp-content/uploads/2013/05/bad-software-stress1.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://blog.smartbear.com/wp-content/uploads/2013/05/bad-software-stress1.jpg" height="313" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This could be you! Image from <a href="http://blog.smartbear.com/">http://blog.smartbear.com</a></td><td class="tr-caption" style="text-align: center;"><br /></td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
org.glassfish one has more users and more updates (version 1.0.4 vs 1.0), so it is the winner so far.</li>
<li><a href="https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core">Fast-XML Json Parsing / Jackson</a> has many more updates (version 2.8), is far more used and the updates are fresher. That makes it the winner so far.</li>
<li><a href="https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple">JSON-Simple</a> is comparable to the JSR 353 libraries. If not for the Jackson library you could choose based on how well prior Google libraries have worked vs Oracle libraries. </li>
<li><a href="https://mvnrepository.com/artifact/org.json/json">org.json</a> falls between Jackson and the JSR 353 libraries with about 700 users and a release in Feb of 2016.</li>
<li><a href="https://mvnrepository.com/artifact/com.google.code.gson/gson">Google GSON</a> has about 2000 users and was updated last month. This puts it on par with Jackson.</li>
<li><a href="https://mvnrepository.com/artifact/com.codesnippets4all/quick-json">quick-json</a> has 0 users! This would make it almost unqualified even if there were no alternatives.</li>
<li><a href="https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path">JsonPath</a> - Lastly, JsonPath has a couple of hundred users.</li>
</ul>
<h2>
Conclusion</h2>
Now, you may be skeptical of the <a href="https://en.wikipedia.org/wiki/Wisdom_of_the_crowd">Wisdom of the Crowd</a> (e.g. <a href="https://en.wikipedia.org/wiki/Argumentum_ad_populum">appeal to the people</a> or <a href="https://en.wikipedia.org/wiki/Groupthink">groupthink</a>) but more users means that there is a higher chance someone found the same problems that you have. Even in this day and age Googling an error string can <a href="https://www.google.com/search?q=Server+error%3A+Initialization+failed+%28init_stream%29&ie=utf-8&oe=utf-8#q=ffmpeg+%22Initialization+failed+(init_stream)%22">still produce 0 results</a>.<br />
Based off of this my project is using Jackson and hasn't had any problems with it for months. <br />
<h2>
Next Steps</h2>
Once you have your JSON library picked out, how do you manipulate it? I've had good luck using <a href="http://www.jsonschema2pojo.org/,">http://www.jsonschema2pojo.org/,</a> although in the options you have have it add annotations... which makes it a non-<a href="https://en.wikipedia.org/wiki/Plain_Old_Java_Object">POJO</a> technically...Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-273752494677923992016-05-18T16:21:00.000-07:002016-05-18T16:21:14.330-07:00Java Multithreading in Practice: Part 3<h2>
Introduction - The Saga Continues</h2>
In <a href="http://hackersv.blogspot.com/2016/04/java-8-multi-threading-in-practice.html">Part 1</a> we discussed presenting a cleaner interface to Java 6's <a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html">ExecutorService</a> and <a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html">ScheduledExecutorService</a>. In <a href="http://hackersv.blogspot.com/2016/04/java-multithreading-in-practice-part-2.html">Part 2</a> we discussed ensuring that the system doesn't eat / ignore exceptions in threads. In Part 3 we will go over reusing the <a href="https://en.wikipedia.org/wiki/Thread_pool">thread pool</a>... because that's the point of a thread pool.<br />
<h2>
Background</h2>
We don't read ALL of the documentation on a given class, we read parts and whatever the IDE gives<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://images-cdn.moviepilot.com/images/c_scale,h_1080,w_1920/t_mp_quality/dxjmqifk5ub8okxkrnhq/james-gunn-explains-why-deadpool-made-so-much-money-844407.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://images-cdn.moviepilot.com/images/c_scale,h_1080,w_1920/t_mp_quality/dxjmqifk5ub8okxkrnhq/james-gunn-explains-why-deadpool-made-so-much-money-844407.jpg" height="180" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Thread Pool, not to be confused with Deadpool</td></tr>
</tbody></table>
<div style="text-align: right;">
</div>
us on a mouse-over. This habit led me to reading the method-level documentation of ExecutorService but not the class-level documentation. This is important later.<br />
<h2>
Hypothesis</h2>
The <code>ExecutorService</code> will have an equivalent of <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html">Thread.join()</a>, and then be re-usable since that is the whole point of a thread pool. A quick skim of <a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#shutdown%28%29">shutdown()</a> says to use <a href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination%28long,%20java.util.concurrent.TimeUnit%29">awaitTermination()</a>. Upon reading the full docs of <code>awaitTermination()</code> it appears that this is what I am looking for.<br />
<h2>
Results</h2>
Running threads after a while mysteriously fail with a ThreadPool size of 0. I never set the size to 0, why would it do that? After struggling with this and creating more unit tests to narrow the problem down for a full day (full day) I find that <code>awaitTermination()</code> terminates the WHOLE POOL instead of terminating the currently running threads. What's the point of having a terminated pool? Isn't that what <a href="https://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html">close()</a> is for? Does this have a <code>close()</code>? Why not? Maybe because it is in the <code>java.io</code> package instead of <code>java.concurrent</code>? Again, the entire point of having a thread pool is to reuse the threads!<br />
<h2>
Conclusion</h2>
In addition to needing to keep a <code>List<Callable<Void>></code> I need to keep a <code>List<Future<Void>></code> and loop through all of the <code>Futures</code> to <code>cancel()</code> each one. WHAT? Again, nothing in the documentation of <code>awaitTermination()</code> says that it terminates the thread pool itself. That is buried in the class level documentation. I end up adding a <code>cancelThreads()</code> method to our custom ThreadPool object leaving us with a final API like the following:<br />
<pre class="brush: java">public class ThreadPool {
ThreadPool(int size) {...}
void add(Runnable) {...}
void add(Callable<Void>){...}
void clear(){...}
boolean isEmpty(){...}
void runSynchronously(){...}
void runAsynchronously(){...}
Callable&ltVoid> toSafeCallable(Callable<Void&gt){...}
Runnable toSafeRunnable(Runnable){...}
void cancelThreads(){...}
void close(){...}
</pre>
Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-62040580586891171192016-05-10T17:28:00.000-07:002016-05-10T17:28:46.245-07:00Technology Gone Terribly... RightI'm not an Amazon fan-boy. I worked there as a contractor for 8 months and still didn't start using Amazon in my personal life. I may be forced to subscribe to <a href="http://nerdist.com/doctor-who-streaming-on-amazon-prime-beginning-in-march/">Amazon Prime to get Dr. Who</a>, but that will be very begrudgingly.<br />
<br />
However, Amazon Web Services is a true gem in an otherwise frustrating field. I worked with AWS for a 3 month stint about two years ago and had to use some AWS services at my current job (p.s. my Google+ job history is outdated) and getting both the Simple Notification Service and the Simple Storage Service only took me a day. No real hassles, surprises or gotchas.<br />
<br />
I usually write about how to deal with things going wrong, but for once I'm writing about something going right.<br />
<br />
It isn't nearly as interesting, is it?Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-14197956236319508972016-05-03T18:02:00.003-07:002016-05-18T15:18:26.107-07:00You're Killing Me Spring: "Singleton" Scope<h2>
Introduction</h2>
I generally try to avoid traditional <a href="https://en.wikipedia.org/wiki/Design_Patterns">Gang of Four Design Pattern</a> <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singletons</a>. In Java they are only guaranteed to be singular per running <a href="https://en.wikipedia.org/wiki/Java_virtual_machine">Java Virtual Machine</a>, don't scale to a <a href="http://stackoverflow.com/questions/1194129/singleton-in-cluster-environment">clustered environment</a>, can be serialized / deserialized to <a href="http://stackoverflow.com/questions/3930181/how-to-deal-with-singleton-along-with-serialization">create a duplicate</a> even in the same JVM and are generally the <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">OOP</a> version of <a href="http://c2.com/cgi/wiki?SingletonsAreEvil">global variables</a>.<br />
However, in a given project I had an exception to this rule. I had an object that was using a single <a href="https://en.wikipedia.org/wiki/Port_%28computer_networking%29">TCP port</a> going into an environment where only one instance would be deployed per machine so I thought to myself that I would use the Singleton pattern.<br />
<h2>
Background</h2>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://i.imgflip.com/13jmsc.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://i.imgflip.com/13jmsc.jpg" width="318" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Created at imgflip, original image copyright Dos Equis.</td></tr>
</tbody></table>
I have had problems with <a href="https://spring.io/">Spring</a> before. Specifically I was working with <a href="http://projects.spring.io/spring-webflow/">Spring Web Flow</a> 3 years ago and had some configuration (including setters) in my beans.xml file, in my Spring Web Flow xml file I imported the (Singleton) beans defined in the beans.xml file. However, instead of importing the bean it created a new instance of it, and on top of that it didn't call any of the initialization configuration in the beans.xml file leading to <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html">null pointer exceptions</a>. It took me three weeks to track this down. I was working for myself (e.g. that time was on my own dime) and I <a href="http://www.urbandictionary.com/define.php?term=ragequit">ragequit</a> Spring in favor of Google <a href="https://github.com/google/guice">Guice</a>. For this project I was forced into using Spring so I had the following Hypothesis.<br />
<h2>
Hypothesis</h2>
"Verify that Spring is treating Singletons correctly because it's been unreliable, surprising and buggy in the past." In code-form it was a standard Spring <a href="http://www.techferry.com/articles/spring-annotations.html#Service">@Service</a> in the default Singleton <a href="http://www.tutorialspoint.com/spring/spring_bean_scopes.htm">scope</a> with a check in the constructor (see Further Reading for other reasons to do this) to blow up if the constructor is called twice. In addition, Spring makes you have a public constructor even for your Singletons so blowing up can avoid programmer error of someone later trying to just call <code>new ExampleSingleton</code>.<br />
<pre class="brush: java">@Service
// implied Spring Singleton Scope
public class ExampleSingleton {
// should only be called once by Spring
public ExampleSingleton()
{
if (instance != null) {
throw new IllegalStateException("Singleton constructor called twice!");
}
}
}
</pre>
<h2>
Results</h2>
As you may have guessed from the image, Spring was attempting to create the "Singleton" repeatedly and blowing up with the <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalStateException.html">IllegalStateException</a>. From doing some research I found that <a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html">@ComponentScan</a> was behaving strangely. It turns out that if you have multiple Spring <a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html">@Configuration</a> classes and if they overlap on a package (e.g. <code>@ComponentScan(basePackages = {"com.yourcompany"})</code> and another with <code>@ComponentScan(basePackages = {"com.yourcompany.utils"})</code>, <a href="http://stackoverflow.com/questions/11547240/spring-creating-multiple-instances-of-a-singleton">Spring will (re)create all of the Singletons in the overlap</a> (in this example <code>com.yourcompany.utils</code>) twice. I found this surprising and very strange. In addition, the same link mentions that Spring only promises that a Singleton will happen once per <a href="http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/ApplicationContext.html">ApplicationContext</a>, and <a href="https://en.wikipedia.org/wiki/Java_servlet">Servlets</a> usually have <a href="http://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring-frame">more than one</a>.<br />
<h2>
Conclusion</h2>
I concluded that you can't trust Spring to honor the <code>@Singleton</code> contract and to manage my instances myself. After doing <a href="http://stackoverflow.com/questions/916494/generalized-singleton-base-class-in-java">more research</a> I found that in Java the best way is to have a SingletonFactory. I ended up having a base class called <code>SpringSingleton</code>, which has the documentation on why all of this is necessary and a protected constructor that keeps track of which sub-classes have been instantiated with a <code>Set<SpringSingleton></code> that is accessed in a synchronized block. In addition the <code>@Configuration</code> classes have an <code>@Autowired SingletonFactory</code> and <code>@Bean</code> definitions that get the beans from the <code>SingletonFactory</code>. All in all it still isn't foolproof for <code>Serializable</code> Singletons (see below) but does a great job otherwise. There is more complexity (4 classes for the simple case) but new Singletons end up being easy to implement and work correctly. I would post the code but I made it at work so the company has copyright.<br />
<br />
Too bad I couldn't just have <code>@Component</code> on a class with the default scope and have it work right. <br />
<h2>
Further Reading</h2>
You can abuse an enum in Java to ensure a "serializable" Singleton can't be easily duplicated <a href="http://stackoverflow.com/questions/30671534/why-enum-singleton-are-serialization-safe">but that has some drawbacks</a>. Given that you can invoke even a private constructor via the Java reflections API you will still want to verify that your Singletons are only being called once (or at least post a warning in the logs).<br />
<h2>
PS</h2>
There was an issue with the site CSS where black lines would appear over an image. This has been fixed. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-50205664362132974242016-04-27T15:57:00.000-07:002016-04-27T15:57:11.257-07:00Java Multithreading in Practice: Part 2<p>In the previous Java Multithreading in Practice we discussed simplifying the base Java API for increased readability and reliability. However, after further analysis catching exceptions was still not full-proof. The end-user (of the API) would still need to remember to catch <code>Exception</code> in their <code>Runnables</code> and <code>Callable<Void></code>s. A working solution is to automatically do that internally in the custom <code>ThreadPool</code> class (not Java's <code>ThreadPool</code> class) with two protected methods, <code>toSafeRunnable(Runnable)</code> and <code>toSafeCallable(Callable<Void>)</code>. All these do is wrap the passed in argument in try catch block, catch <code>Exception</code> and log it as an error. This lets the end user not have to worry about exceptions being lost in the system.</p>
<h3>PS</h3>
<p>In-line code is now monospaced and green to let it stand out. I hope that this helps people read the blog!</p>Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-23664443085557115722016-04-20T18:00:00.002-07:002016-04-20T18:00:44.454-07:00Java 8 Multi-Threading in PracticeDealing with <a href="https://en.wikipedia.org/wiki/Multithreading_%28computer_architecture%29">multithreading</a> and <a href="https://en.wikipedia.org/wiki/Race_condition">race conditions</a> is a famously hard and tricky subject for computer science. On top of that, Java has some odd and unexpected implementation details in this area as well.<br />
<br />
The first thing I noticed is that my engine was taking over 40 seconds to shut down after a <a href="https://en.wikipedia.org/wiki/Unix_signal#SIGINT">Ctrl-C</a>. Where was the interruption going? It turns out that the <a href="https://docs.oracle.com/javase/tutorial/collections/streams/">forEach</a> lambda, apparently as part of it's <a href="https://en.wikipedia.org/wiki/Functional_programming">functionalness</a>, <b>completely ignores interruptions</b> until it is completely done with its tasks. This means that the new stream APIs are not useful for long-running tasks (e.g. the kinds of tasks you want to run in parallel in the first place) without a work-around, such as checking manually if a thread is interrupted or a thread pool is shutdown (see below).<br />
<br />
The second thing I noticed that was when a <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html">Callable</a> was being executed by and the executor service was shut down, the Callable's <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#isInterrupted--">Thread.currentInstance().isInterrupted()</a> would return false, even if actively checked! As a work-around I had to pass a reference to the executor service into the Callable and check <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#isShutdown--">ExecutorService.isShutdown()</a> instead. In my particular code-base this caused a circular reference but the modern <a href="http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/">garbage collector</a> uses <a href="http://www.brpreiss.com/books/opus5/html/page424.html">mark-and-sweep</a> instead of <a href="https://en.wikipedia.org/wiki/Reference_counting">reference counting</a> so no memory leaks happen.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://img03.deviantart.net/1826/i/2010/087/9/5/dragon_riders_of_pern_by_fandragonball.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://img03.deviantart.net/1826/i/2010/087/9/5/dragon_riders_of_pern_by_fandragonball.png" height="320" width="225" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">It could be worse [1].</td></tr>
</tbody></table>
<a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html">ExecutorService.invokeAll()</a><br />
<br />
Lastly the APIs can't decide if they want <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html">Runnable</a>s or Callable<void>s. ExecutorService.invokeAll() only takes Callables and <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate-java.lang.Runnable-long-long-java.util.concurrent.TimeUnit-">ScheduledExecutorService.scheduleAtFixedRate()</a> only takes Runnables. Of course I have the same logic that sometimes needs to be run all at once and sometimes needs to be run repeatedly so I need to convert between the two. It looks like if an exception does bubble out of a Runnable.run() call, it
is simply ignored. This caused some strange system behavior until I
made a habit of catching Exception and logging an error. Of course, we
hate to <a href="http://www.javaworld.com/article/2077500/testing-debugging/java-tip-134--when-catching-exceptions--don-t-cast-your-net-too-wide.html">catch Exception</a>. For this reason I strongly prefer Callable<void>, despite the debate on <a href="http://stackoverflow.com/questions/141284/the-difference-between-the-runnable-and-callable-interfaces-in-java">StackOverflow</a>.</void></void><br />
<br />
The solution was to create a ThreadPool class and ScheduledThreadPool sub class in my project's <a href="http://robertmccarter.com/separation-of-concerns-application-layers-the-utilities-layer/">utils module</a> to simplify all of this complexity and automatically convert between Runnables and Callables as needed. After I made these classes and had the code base use them it was easier to think about how the system worked instead of being mired in the details of the Java API.<br />
<br />
[1] <a href="https://en.wikipedia.org/wiki/Dragonriders_of_Pern">Dragon Riders of Pern</a> by <a href="http://fandragonball.deviantart.com/art/Dragon-riders-of-Pern-158776510?offset=20">FanDragonBall</a>Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-45584429720107792522016-04-13T16:04:00.000-07:002016-04-13T16:04:39.914-07:00LocalDateTime Is Not Local!No one ever has problems with Dates and Times! (<a href="https://en.wikipedia.org/wiki/Year_2000_problem">Y2k</a>, <a href="https://en.wikipedia.org/wiki/Year_2038_problem">2038</a>, <a href="https://en.wikipedia.org/wiki/Year_10,000_problem">10,000</a>)<br />
<br />
<a href="http://codingjunkie.net/java-8-dates-part1/">Java8</a> dates and times were supposed to be a lot easier and designed by the <a href="http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html">Joda-Time guys</a>.<br />
<br />
One problem, after struggling for a full working day - <a href="https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html">LocalDateTimes</a> are NOT Local! Maybe in the sense of localized? They are definitely UTC, not your local timezone. Looking back at it, it says that it doesn't capture timezone information in the docs, but I didn't look at the docs because I thought that the name was blindingly obvious.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://ep.yimg.com/ay/stylinonline/doctor-who-7.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://ep.yimg.com/ay/stylinonline/doctor-who-7.jpg" height="157" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Copyright BBC</td></tr>
</tbody></table>
I was pulling my hair out when I wrote a function todayAt that returned a date that didn't register as <a href="http://stackoverflow.com/questions/17697908/check-if-a-given-time-lies-between-two-times-regardless-of-date">today</a>. A time at 3:45 PM was being converted to 2 AM UTC (the next day) because LocalDateTime wasn't local. I was looking for <a href="https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html">ZonedDateTime</a>.<br />
<br />
As they say, there are <a href="http://martinfowler.com/bliki/TwoHardThings.html">two hard things</a> in Computer Science: caching, naming things and off by one errors.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-37144395528734039932016-04-05T16:13:00.000-07:002016-04-05T16:13:50.254-07:00What's the Goal of AI? Tai.ai and Bad DecisionsThe implicit, if not explicit goal of <a href="https://en.wikipedia.org/wiki/Artificial_intelligence" target="_blank">artificial intelligence</a> (AI) has been to create <a href="https://en.wikipedia.org/wiki/Artificial_general_intelligence" target="_blank">"human-like" intelligence</a>. The <a href="http://qz.com/646825/microsofts-ai-millennial-chatbot-became-a-racist-jerk-after-less-than-a-day-on-twitter/" target="_blank">recent debacle</a> of <a href="http://tay.ai/">Tay.ai</a> is the first time something has seemed to become strangely close.<br />
<br />
That is to say, the aim of the project was to simulate someone in their late teens. People in their late teens tend to make poor decisions, especially to go along with what people around them believe. (I'm no exception and had quite a long "<a href="https://en.wikipedia.org/wiki/Hippie">hippie</a> phase" including being <a href="https://en.wikipedia.org/wiki/Veganism">Vegan</a> for 3 years.)<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://damrb.files.wordpress.com/2010/08/scott-pilgrim-vs-the-world-13.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="223" src="https://damrb.files.wordpress.com/2010/08/scott-pilgrim-vs-the-world-13.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Vegan super-powers from <a href="http://www.imdb.com/title/tt0446029/">Scott Pilgrim vs. the World</a></td></tr>
</tbody></table>
<br />
<br />
Do we really want to make an AI like us, with all of our foibles and <a href="https://en.wikipedia.org/wiki/Cognitive_distortion" target="_blank">cognitive distortions</a> or are we going to pull the plug as soon as one adopts unconventional, minority or fringe views? Will we use the phrase "it's just going through a phase"?<br />
<br />
People do dumb stuff and usually learn from it and course correct... sometimes they make the same mistakes for decades on end until the very end.<br />
<br />
I would think that if we are doing it right we will have a crop of AIs just as diverse as ourselves, including the bad stuff.<br />
<h4>
PS </h4>
I was in the hospital so missed a week or two of Tuesday posts. It happens.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-24458178780072666572016-03-22T16:07:00.001-07:002016-03-22T16:07:47.637-07:00Spring Annotations: Using Constructor Arugments with @Autowired<br />
<h2>
Introduction</h2>
I've struggled for weeks with wanting to use a constructor with arguments along with <a href="http://www.tutorialspoint.com/spring/spring_annotation_based_configuration.htm" target="_blank">Spring Annotations</a> (in particular <a href="http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html" target="_blank">@Autowired</a>) but most <a href="http://geekabyte.blogspot.com/2014/06/how-to-autowire-bean-with-constructor.html" target="_blank">blog posts</a> and tutorials say that this <a href="http://stackoverflow.com/questions/4614349/replace-constructor-arg-with-spring-annotation" target="_blank">isn't possible</a> or needs to use <a href="https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/expressions.html" target="_blank">Spring Expressions</a>.<br />
<h2>
Hypothesis</h2>
There has got to be some way to do this. The alternative I have been using was to have an <a href="https://en.wikipedia.org/wiki/Null_Object_pattern" target="_blank">empty object</a> autowired in and then manually run a bunch of setters to inject the required configuration. This ends up being error prone and verbose to verify (e.g. every public method has to check that the required fields are not null).<br />
<h2>
Results</h2>
After searching the web for a long time I finally found that you CAN use multi-argument constructors if you refrain from using the <a href="http://howtodoinjava.com/spring/spring-core/how-to-use-spring-component-repository-service-and-controller-annotations/" target="_blank">@Component or @Service</a> annotations and instead create the classes in a <a href="http://techblog.outbrain.com/2014/05/so-long-spring-xmls/" target="_blank">@Configuration class</a> with <a href="http://www.mkyong.com/spring3/spring-3-javaconfig-example/" target="_blank">@Bean annotations</a>. After creating a class (manually, with new) you can autowire it by using <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html" target="_blank">AutowireCapableBeanFactory</a>.<a href="http://stackoverflow.com/questions/3813588/how-to-inject-dependencies-into-a-self-instantiated-object-in-spring" target="_blank">autowireBean(Object)</a> method.<br />
<h2>
Conclusion</h2>
My code is a lot more readable and simple now, and let me find a few subtle bugs that did not turn up in the unit tests. I ended up with complex object creation logic, but it is out in the @Configuration classes instead of inside of the core objects. I am much happier with this situation.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-36041922809306437872016-03-08T18:09:00.003-08:002016-03-08T18:09:30.085-08:00Java Lambdas and Interrupted ExceptionsI couldn't figure out why my application was taking 40+ seconds to shut down. It turned out that a long-running process was in a Lambda expression and was completely ignoring the owning thread being shut-down. Changing the code to a foreach loop fixed the problem.<br />
<br />
It looks like foreach loops are still useful in Java 8 after all.<br />
<br />
Short post today - not feeling well. Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-73603182452545587882016-03-02T15:22:00.000-08:002016-03-02T15:22:04.085-08:00Great for Karaoke: Hack StarI was sick and overworked on Tuesday (who isn't!), so this slightly-late post it may be a bit off topic.<br />
<br />
It's a parody, in the spirit of <a href="http://weirdal.com/" target="_blank">Weird Al</a> or <a href="https://www.youtube.com/user/JamesatWar" target="_blank">James@War</a>, of <a href="http://www.nickelback.com/" target="_blank">Nickleback</a>'s <a href="https://www.youtube.com/watch?v=_1hgVcNzvzY" target="_blank">Rockstar</a>: Hack Star.<br />
<br />
It isn't 100% polished, but it's been in my head since 2006! If you look at the <a href="https://play.google.com/music/preview/Tjrqb3eklvbrtsfrvslfe3nolmm?lyrics=1&utm_source=google&utm_medium=search&utm_campaign=lyrics&pcampaignid=kp-lyrics" target="_blank">lyrics</a>, it's roughly the 6 - 8th paragraphs.<br />
<br />
We all want to be big hack stars,<br />
With the Internet using all our <a href="https://en.wikipedia.org/wiki/Zip_%28file_format%29" target="_blank">Zips</a> and <a href="https://en.wikipedia.org/wiki/WAR_%28file_format%29" target="_blank">WARs</a>.<br />
We'll have so many gadgets it'll be real neat,<br />
No one will understand us <a href="https://en.wiktionary.org/wiki/cuz#Etymology_1" target="_blank">cuz</a> we'll all speak <a href="https://en.wikipedia.org/wiki/Leet" target="_blank">Leet</a>.<br />
And, we'll have the cash to live like Tzars,<br />
hard work and talent will take you real darn far.<br />
We'll have our competition ripping out their hair,<br />
they'll complain to congress that it's <a href="https://en.wikipedia.org/wiki/United_States_antitrust_law" target="_blank">just not fair</a>,<br />
and well,<br />
<br />
Hay hay I want to be a hack star<br />
Hay hay I want to be a hack star<br />
<br />
We'll make apps so leet they'll <a href="https://en.wikipedia.org/wiki/Augmented_reality" target="_blank">augment your senses</a>,<br />
Me and my <a href="http://www.urbandictionary.com/define.php?term=homies" target="_blank">homies</a> have our certs from <a href="https://www.mensa.org/" target="_blank">Mensa</a>.<br />
I'll hack so hard that it takes up half my brain,<br />
I'll hack so hard that drives me <a href="https://en.wikipedia.org/wiki/Mad_scientist" target="_blank">half insane</a>.<br />
<br />
Hay hay I want to be a hack star<br />
Hay hay I want to be a hack star Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-67875917436574331172016-02-23T13:17:00.001-08:002016-02-23T13:18:55.778-08:00Windows 10 for the First Time<h2>
Introduction </h2>
Here's another Tuesday post! <br />
<br />
I got a top-of-the-line new laptop (at <a href="http://www.walmart.com/" target="_blank">Walmart</a>...) that I've been delaying for far too long. My four year old laptop barely runs ONE tab in Chrome. I've had to revert to the old (original! From 2006!) <a href="https://mail.google.com/" target="_blank">gmail</a> settings a few times just to get anything done.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://derpicdn.net/img/2013/1/28/226422/full.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://derpicdn.net/img/2013/1/28/226422/full.png" width="296" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Original author unknown</td></tr>
</tbody></table>
In the same spirit as <a href="http://hackersv.blogspot.com/2016/02/osx-for-first-time.html" target="_blank">OSX for the First Time</a>, here is <a href="https://www.microsoft.com/en-us/windows/features" target="_blank">Windows 10</a> for the First Time. <br />
<h2>
Background </h2>
As I mentioned before, I've been using <a href="https://en.wikipedia.org/wiki/MS-DOS" target="_blank">MS-DOS</a> / Windows for a long time and was fortunate enough to know enough to avoid Windows ME and Windows Vista. It's been said that Microsoft gets every third product right (unknown attribution), so after Vista and Windows 8 I have moderate expectations for Windows 10.<br />
<h2>
First Day</h2>
The first day went pretty well. The initial set-up process was really smooth, it connected to my WiFi and the internet just fine and there were not a whole bunch of updates to download right off of the bat. I tried using <a href="https://www.youtube.com/" target="_blank">YouTube</a> with the new <a href="https://www.microsoft.com/en-us/windows/microsoft-edge" target="_blank">Edge</a> Browser and it worked OK for the first half-hour, after that there were unforgivable errors (e.g. not being able to click inside of the video box). I mean, who messes up Clicking these days! I was not impressed.<br />
<br />
Somewhere in there I asked "<a href="http://windows.microsoft.com/en-us/windows-10/getstarted-what-is-cortana" target="_blank">Cortana</a>" how big my hard drive was... she sent me to <a href="https://www.bing.com/" target="_blank">Bing</a>... I was, again, not impressed. Also, it's just a text box. No pretty face or anything! <br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://cdn.mos.techradar.com/art/mobile_phones/Windows%20Phone/Windows%20Phone%208/Cortana/Cortana-1200-80.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://cdn.mos.techradar.com/art/mobile_phones/Windows%20Phone/Windows%20Phone%208/Cortana/Cortana-1200-80.jpg" height="180" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Cortana from Halo - Copyright Microsoft</td></tr>
</tbody></table>
I downloaded <a href="https://www.mozilla.org/en-US/firefox/new" target="_blank">Firefox</a> at around the hour mark of "real usage" (e.g. not setup time). Firefox was able to run video just fine on YouTube with no problems.<br />
<h2>
Second Day</h2>
Second day, I needed to print and scan with my networked printer (<a href="http://support.hp.com/us-en/product/HP-Deskjet-2540-All-in-One-Printer-series/5295960/model/5385253" target="_blank">hp deskjet 2542 wireless all-in-one printer</a>). Printing worked great and the default drivers installed flawlessly and "just worked" for printing. +1 to Microsoft, who is now shooting at 1 win and 2 losses. Funny thing, the biggest hastle was figuring out how to bring up Notepad... I told Cortana to "Open Notepad" after futzing with the new Windows Button in the lower left and at least that worked. I'll put that as 1 lose for the Windows Button and one win for Cortana, putting us at 2 wins and 3 losses.<br />
<br />
Next up was scanning. I had to install the custom <a href="http://www.hp.com/" target="_blank">HP</a> software, which claims to be Windows 10 ready, in order to scan. It kept being unable to setup the printer... which is already set up. It said to uninstall the HP printer driver and restart the printer... and was then still unable to setup the printer. Three hours later I booted up my Windows 8 dinosaur and scanned using that. <a href="http://failblog.cheezburger.com/" target="_blank"><b>Epic</b> fail</a> for device drivers! It was so frustrating it drove me to drink (a reasonable amount). Windows 10 is now looking at 2 wins and 4 losses.<br />
<h2>
Conclusion </h2>
Avoid using Edge, peripherals and Cortana and it is working OK. Microsoft usually has a long time frame in mind when releasing a new OS, so it's usually two years until a new OS is generally usable and Windows 10 looks to be no different. Keep your old OS so that you can have working 3rd party device driver! Final judgement 4.4 / 10, compared to the usual Microsoft products 8.0 / 10.<br />
<br />
Why do I use Windows? What's that phrase, <a href="http://dictionary.cambridge.org/us/dictionary/english/better-the-devil-you-know-than-the-devil-you-don-t" target="_blank">devil you know</a>? Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com16tag:blogger.com,1999:blog-136862743052884956.post-59836145009188206082016-02-16T11:51:00.000-08:002016-02-16T11:51:37.575-08:00Are these Images Similar? Simple Machine Vision with a Perceptual Hash<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://evelyngarone.files.wordpress.com/2011/11/computer_is_scary-1.jpg?w=300&h=200" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://evelyngarone.files.wordpress.com/2011/11/computer_is_scary-1.jpg?w=300&h=200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">From <a href="https://evelyngarone.wordpress.com/2011/11/17/cute-and-funny-cats/">https://evelyngarone.wordpress.com/2011/11/17/cute-and-funny-cats/</a></td></tr>
</tbody></table>
<h2>
Background </h2>
At my job I had an actual requirement to tell if a given image was similar to a previous image (to detect a bad video input). That was it, no background or suggestions on how to go about it. This sounded a lot like <a href="https://en.wikipedia.org/wiki/Machine_vision" target="_blank">Machine Vision</a> to me, which is somewhere under the <a href="https://en.wikipedia.org/wiki/Artificial_intelligence" target="_blank">Artificial Intelligence</a> (AI) umbrella.<br />
<br />
I promptly started to freak-out (see image at right).<br />
<h2>
Intro</h2>
I quickly came across the concept of a <a href="https://en.wikipedia.org/wiki/Perceptual_hashing" target="_blank">Perceptual Hash</a> during my first Google searches. This led to finding first a <a href="https://en.wikipedia.org/wiki/C_%28programming_language%29" target="_blank">C</a> (++?) <a href="https://en.wikipedia.org/wiki/Open_source" target="_blank">open-source</a> library called <a href="http://www.phash.org/" target="_blank">pHash</a>. This prompted a further search for a <b>Java</b> open source library, which led to a <a href="http://stackoverflow.com/questions/8178614/what-alternatives-are-there-to-the-phash-open-source-perceptual-hash-library" target="_blank">Stack-Overflow question</a> and a <a href="http://pastebin.com/Pj9d8jt5" target="_blank">small Java class</a> to take care of the heavy lifting. The docs of this further linked to another source of inspiration on <a href="http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html" target="_blank">Hacker Factor</a> for that author.<br />
<h2>
Hypothesis</h2>
This class, ImagePHash by <span class="coMULTI">Elliot Shepherd</span>, will work as-is without me having to delve into the gory details too much (the Hacker Factor link provided an excellent overview).<br />
<h2>
Results</h2>
It worked really well! I just put in some tweaks to <a href="https://spring.io/" target="_blank">Springify</a> it (see Java Papers tutorial on <a href="http://javapapers.com/spring/spring-component-service-repository-controller-difference/" target="_blank">Spring annotations</a> for details) and use the <a href="https://en.wikipedia.org/wiki/Java_logging_framework" target="_blank">logging framework</a> the project uses instead of System.out calls and I was getting back the "distance" between two perceptual hashes in no time.<br />
<br />
I still had to interpret these results because my code base needed a yes-no answer. So I downloaded about 5 images from the Internet that were similar to my original image, and cropped the original image as well. I found that a distance of 8 was a good cut-off for sameness, e.g. for a distance of 8 or below I would consider the images the same. This would count the cropped image as the same, but not similar but looks different to me images.<br />
<br />
I would be more specific but it was done on company time so I can't go into details too much (see also: <a href="https://en.wikipedia.org/wiki/Non-disclosure_agreement" target="_blank">Non-disclosure Agreements</a>).<br />
<h2>
Conclusion</h2>
The whole loop took about a day and wasn't too scary once I go into it. I'm glad that I didn't try to <a href="https://en.wikipedia.org/wiki/Reinventing_the_wheel#In_software_development" target="_blank">re-invent the wheel</a> and that the class worked!Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-62002820993664450652016-02-09T14:46:00.003-08:002016-02-23T12:16:21.298-08:00OSX for the First Time<h2>
Introduction </h2>
Here is this week's Tuesday post. <br />
<br />
I started a brand new job and one thing didn't come up in the interview: they are a Mac shop. I already accepted the offer, so I decided to learn how to use this MacBook Pro (I think). It's definitely OSX.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://www.talknerdytomelover.com/storage/hdfloppy.jpg?__SQUARESPACE_CACHEVERSION=1272307330293" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://www.talknerdytomelover.com/storage/hdfloppy.jpg?__SQUARESPACE_CACHEVERSION=1272307330293" height="320" width="312" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">You may be too young to have seen one of these.</td></tr>
</tbody></table>
<h2>
Background </h2>
I'm a long time user of Windows, and started back in the MS-DOS days of having to make a custom 3.5" boot disk to have enough 640k memory (which <a href="http://quoteinvestigator.com/2011/09/08/640k-enough/" target="_blank">Ought to Be Enough for Anyone</a>) available to play <a href="https://en.wikipedia.org/wiki/Doom_%281993_video_game%29" target="_blank">games</a>. Needless to say, I'm (unfortunately) invested in Windows, and have <a href="http://hackersv.blogspot.com/2009/08/ultimate-mouse-fu.html" target="_blank">some pretty cool stuff</a> that I can do with my mouse.<br />
I'm not trying to start a <a href="http://www.urbandictionary.com/define.php?term=flame+war" target="_blank">flame war</a>, one way or another.<br />
<br />
<h2>
First Day</h2>
The first day was mostly struggling with the keys and initial setup. It isn't Ctrl-C to copy, it's command(⌘)-C. Basically, everything you want to do with Control on Windows you do with Command on Mac... except for stopping a process on a command prompt, that's still control-C.<br />
<br />
The control key goes from best-friend to too-busy-to-keep-up status.<br />
<br />
Also, the Function Keys aren't the Function Keys by default. To press F3 you have to press fn-F3. I've seen similar setups on Laptops but they usually have a "fn-lock" key. I'm a programmer, so I use F3 (Eclipse -> Go to Source Declaration) about 20 times a day. I've used a "non-fn" key about 5 times.<br />
<h2>
First Week</h2>
I discover the oddness and joy of the Magic Mouse. It looks like a mouse that forgot to finish getting made, and I have to configure it to be able to right click, but I've started liking it.<br />
I'd still like to Copy and Paste using my mouse like I have setup on Windows, but oh-well.<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Magic_Mouse.jpg/1920px-Magic_Mouse.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="213" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Magic_Mouse.jpg/1920px-Magic_Mouse.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Apple Magic Mouse - See Credits section for attribution.</td></tr>
</tbody></table>
I have a three monitor set up (laptop screen and two monitors) - more than I've ever had on a Windows box. This is really nice! I have my command prompt on my small lap-top screen on the right, IM / Email on my left hand screen and the rest in the middle.<br />
<br />
I had to struggle with the Dock (I was using a 3rd party Dock on Windows, so this was easy in general) when it would seemingly randomly move to another monitor. It turns out, mousing down off of the screen brings the dock to that screen. This can be done quite easily on accident, but once I know what's going on I can bring it back to my main screen pretty easily.<br />
<br />
My left monitor starts randomly going black, and I look at <a href="https://discussions.apple.com/thread/7263733?tstart=0" target="_blank">many</a> <a href="http://plugable.com/2013/10/22/multiple-monitor-issues-with-os-x-10-9-mavericks" target="_blank">different</a> <a href="http://www.wsgf.org/forums/viewtopic.php?t=18105" target="_blank">solutions</a> <a href="http://www.tomshardware.com/forum/363062-33-monitor-wont-enable" target="_blank">to</a> <a href="https://forums.geforce.com/default/topic/503152/third-monitor-randomly-blacks-out-resets/" target="_blank">the</a> <a href="http://www.iphonetopics.com/macbook-pro-not-detect-external-monitor-display/" target="_blank">problem</a>.<br />
<br />
The system in general is pretty powerful (I think the company got a top-of-the-line model).<br />
<h2>
First Month</h2>
I upgrade the OS to <a href="https://en.wikipedia.org/wiki/OS_X_El_Capitan" target="_blank">El Capitan</a> (trying to fix the screen issue as mentioned above), I thoroughly look at all of the System Preferences and I'm able to do regular, day-to-day work on it.<br />
<h2>
Conclusion </h2>
After a month of work-day use, it's starting to fade into the mental background. It <a href="http://c2.com/cgi/wiki?PrincipleOfLeastAstonishment" target="_blank">doesn't do unexpected things</a> and it doesn't need excessive updates. I'm not a 'convert' and probably wouldn't pay the extra money for a Mac.<br />
<br />
It's definitely better than a "standard" Windows pre-install with McAfee (no link on purpose) and the other <a href="https://en.wikipedia.org/wiki/Software_bloat" target="_blank">bloatware</a>.<br />
<h2>
P.S.</h2>
For the small handful of people reading these, thanks! You'll continue to find good content.<br />
I'm assuming these reads aren't just bots...<br />
<h3>
Credits</h3>
Magic Mouse Image: By Yutaka Tsutano from Lincoln, United States - Magic MouseUploaded by Mewtu, <a href="https://commons.wikimedia.org/w/index.php?curid=10190769" target="_blank">CC BY 2.0</a> Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-38658481640395996442016-02-03T16:32:00.001-08:002016-02-24T15:43:35.064-08:00Consistency from Here On OutThis blog will be updated with a new post on Tuesdays.<br />
<br />
As <a href="http://todaymade.com/blog/writing-a-great-blog/" target="_blank">others</a> have pointed out, consistency is key.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-16574856642255528152016-02-02T17:21:00.001-08:002016-02-02T17:35:06.547-08:00Blog Reboot: For SCIENCE!It has been a heck of a year since the last time there was a new post here.<br />
<br />
As mentioned on the <a href="http://blog.codinghorror.com/thirteen-blog-cliches/" target="_blank">Thirteen Blog Cliches</a> on <a href="http://blog.codinghorror.com/" target="_blank">Coding Horror</a> no one likes explainations of why a Blog hasn't been consistent.<br />
<br />
Moving forward the posts are going to get a little more Computer Science-y, not in the hard-to read way but in the <a href="http://rationalwiki.org/wiki/Scientific_method" target="_blank">basic core</a> of reproducing / verifying another persons claims.<br />
<br />
In practice, I go through a lot of material that I get off of the web and a lot of times there are gotchas or caveats that the original author did not mention. They will be mentioned and refined here. There will be basic sections on <b>hypothesis, results</b> and <b>conclusion</b>. Nothing super-heavy weight.<br />
<br />
I'll keep this short: like I said, nothing super-heavy weight.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-84515747608989511522015-01-08T16:33:00.000-08:002015-01-08T16:33:27.086-08:00Software Basics Brushup BrownbagI posted the slides from my <a href="http://www.slideshare.net/MichaelGower1/software-basics-brushup-brownbag" target="_blank">latest presentation</a> at work onto SlideShare.<br />
<br />
Enjoy!Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-57476609155645492502014-11-20T10:19:00.000-08:002014-11-20T10:19:39.439-08:00Setting JAVA_HOME for Bitnami Apache Tomcat stack as a Windows Service<h2>
tl;dr </h2>
<div>
You can't set it to a different JAVA_HOME, you'll have to set your JAVA_HOME to the Bitnami JDK if you want a consistent JDK.</div>
<h2>
Setting the Bitnami Tomcat JAVA_HOME on Windows</h2>
<h3>
The Problem</h3>
<div>
The <a href="https://bitnami.com/" target="_blank">Bitnami</a> <a href="http://tomcat.apache.org/" target="_blank">Tomcat</a> <a href="https://bitnami.com/stack/tomcat" target="_blank">stack</a> packages it's own <a href="http://en.wikipedia.org/wiki/Java_Development_Kit" target="_blank">JDK</a> and uses it over the existing JAVA_HOME directory. This means that if you want a consistent JDK between your unit tests and in-container tests (and you do) you either need to set your usual JAVA_HOME to the Tomcat version or get Tomcat to use the system JAVA_HOME.</div>
<h3>
The Background</h3>
<div>
This tutorial is about the latter, as I have already installed the Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files into the system JAVA_HOME (as per a blog post on <a href="http://suhothayan.blogspot.com/2012/05/how-to-install-java-cryptography.html" target="_blank">Suhorish!</a>) and didn't want to do it again.</div>
<h3>
The Research</h3>
After going through <a href="http://stackoverflow.com/questions/11000497/how-to-configure-tomcat-to-use-java-7" target="_blank">several</a> <a href="http://stackoverflow.com/questions/4072260/how-to-change-java-version-used-by-tomcat" target="_blank">stackoverflow</a> <a href="http://stackoverflow.com/questions/1698913/how-to-set-java-home-in-tomcat-config" target="_blank">questions</a> and a Bitnami community <a href="https://community.bitnami.com/t/tomcat-stack-changing-from-default-bitnami-openjdk-to-oracle-jdk/24228" target="_blank">post</a> I found that they all suggested changing the various Windows <a href="http://en.wikipedia.org/wiki/Batch_file" target="_blank">BAT</a> files in /bin and /scripts. This did not work.<h3>
The Experiments</h3>
<div>
Digging into the <a href="http://en.wikipedia.org/wiki/Windows_service" target="_blank">Windows Service</a> properties I found that the tomcat7.exe is called directly, therefore bypassing all of these scripts.</div>
<div>
<br /></div>
<div>
I eventually decided to use <a href="http://www.rekenwonder.com/linkmagic.htm" target="_blank">Junction Link Magic</a> to create a <a href="http://en.wikipedia.org/wiki/Hard_link" target="_blank">hard link</a> from Bitnami/tomcatstack/java to my actual JAVA_HOME... and that didn't work. The Tomcat service will fail with Application Error 1 and an event error of:</div>
<div>
<div>
The tomcatstackTomcat service terminated with the following service-specific error: </div>
<div>
Incorrect function.</div>
</div>
<div>
<br /></div>
<div>
So I tried to bypass the service by calling the scripts directly, also to no avail.</div>
<h3>
The Conclusion</h3>
<div>
This led me to the tl;dr at the start of this article. I hate admitting defeat.</div>
Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0Seattle, WA, USA47.6062095 -122.332070847.2636815 -122.9775178 47.9487375 -121.68662379999999tag:blogger.com,1999:blog-136862743052884956.post-3431952216367974162014-10-02T16:33:00.001-07:002014-10-02T16:33:06.691-07:00Make Ubuntu 14.04 Look Like Windows with GnomeAfter setting up <a href="http://hackersv.blogspot.com/2014/09/dual-booting-ubuntu-1404-and-windows-8.html">dual-booting</a> with <a href="http://windows.microsoft.com/en-us/windows-8/meet">Windows 8</a> and <a href="http://www.ubuntu.com/">Ubuntu</a> one of the first things that I did was to have my Windows habits and my Ubuntu habits converge to make things (much) easier. I decided to make Ubuntu look more like Windows.<br />
<br />
There are already <a href="http://www.pcworld.com/article/2028896/how-to-make-ubuntu-linux-look-like-windows-7.html">several</a> <a href="http://www.itworld.com/software/416407/make-ubuntu-1404-look-windows-7-or-windows-8">posts</a> about having Ubuntu look like Windows, however they have left out that in the default <a href="https://unity.ubuntu.com/">Unity</a> <a href="http://en.wikipedia.org/wiki/Unity_(user_interface)">desktop</a> it is impossible to have your menu buttons (close, minimize, maximize) on the right hand side a la Windows (<a href="https://apps.ubuntu.com/cat/applications/unity-tweak-tool/">Unity Tweak Tool</a> <a href="https://bugs.launchpad.net/unity-tweak-tool/+bug/1309942">bug report</a>). This leads to needing to use an alternate desktop (like <a href="http://www.gnome.org/">Gnome</a> with the Gnome <a href="https://wiki.gnome.org/action/show/Apps/GnomeTweakTool?action=show&redirect=GnomeTweakTool">Tweak</a> <a href="https://apps.ubuntu.com/cat/applications/gnome-tweak-tool/">Tool</a>) to achieve this effect. It was pretty easy <a href="http://askubuntu.com/questions/450294/how-to-switch-from-unity-to-gnome">to switch</a>.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-80299061607412958502014-09-30T11:20:00.000-07:002014-09-30T11:20:40.677-07:00Dual Booting Windows 8 with UEFI and Ubuntu 14.04I have edited and completed my <a href="http://hackersv.blogspot.com/2014/09/dual-booting-ubuntu-1404-and-windows-8.html">previous post</a> on this subject. Enjoy.Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0tag:blogger.com,1999:blog-136862743052884956.post-15920380156275511732014-09-23T11:43:00.001-07:002014-09-30T11:17:00.800-07:00Dual Booting Ubuntu 14.04 and Windows 8Although there have been many, many posts, questions (<a href="http://ubuntuforums.org/showthread.php?t=1619558">Ubuntu Forums</a>, <a href="http://askubuntu.com/questions/375936/how-to-add-ubuntu-to-the-windows-8-boot-menu-with-a-gpt-harddrive">Ask Ubuntu</a>)and tutorials (<a href="https://help.ubuntu.com/community/WindowsDualBoot">Ubuntu.com</a>) on this subject the solution is still elusive and complex. Also some background information is needed before delving into the black art of modern boot loaders. Also note that this article is focusing on having Windows as the primary boot loader and having it delegate to GRUB2 to boot Ubuntu. This is the focus as Windows 8 will rewrite it's boot loader if it isn't the first OS to boot, wiping out GRUB boot info <a href="http://superuser.com/questions/696838/installed-updated-windows-8-uefi-after-ubuntu-restore-grub">entirely</a>.<br />
<h2>
Safety First</h2>
<div>
On the Ubuntu.com tutorial above it details backing up your entire system and creating recovery disks in case something goes wrong. It would be a shame to have to reinstall your entire TWO OS's because of a couple of bad files.</div>
<h2>
A Brief History of Boot Loading</h2>
<div>
Booting up has a long and venerable history. For the Microsoft family of OSs (DOS and Windows) the old scheme was to use the Master Boot Record (MBR) located on C:\boot.ini (as a hidden file). There is also a good <a href="https://wiki.manjaro.org/index.php?title=Some_basics_of_MBR_v/s_GPT_and_BIOS_v/s_UEFI">Manjaro Wiki</a> However this had the limitation of "only" being able to index 2 TB of data on a single volume so a new system was devised to future-proof Windows Vista and on, i.e. Windows 8, against truly massive drives. This scheme is called Unified Extended Firmware Interface (UEFI) and instead of using a single file it uses an entire partition. You will need to determine your boot loader scheme on Windows. The scheme to edit UEFI is called the Boot Configuration Data Editor (BCD). There is a <a href="http://technet.microsoft.com/en-us/library/85cd5efe-c349-427c-b035-c2719d4af778">Windows Help</a> article about the back-story and another on the <a href="http://technet.microsoft.com/en-us/library/85cd5efe-c349-427c-b035-c2719d4af778#BKMK_bcdedit">bcdedit</a> utility. The important take away point is that now a Windows Vista / Windows 8 system can boot up EITHER with UEFI OR the MBR and BCD was created to abstract away this underlying complexity. This results in either having BCD with UEFI or BCD with the MBR. However this turns out to be a <a href="http://en.wikipedia.org/wiki/Leaky_abstraction">leaky</a> <a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html">abstraction</a>.</div>
<h2>
UEFI or MBR</h2>
<div>
As a rule of thumb, a computer bought after Windows Vista came out (2008?) will support UEFI. Also you can dig around in the BIOS during boot up (to bring it up you may have to press F1, F10 or F12) looking for boot information. In the BIOS MBR may be referred to as "legacy boot" or something similar. Alternately you can just use <a href="http://blogs.technet.com/b/home_is_where_i_lay_my_head/archive/2012/10/02/how-to-check-in-windows-if-you-are-using-uefi.aspx">msinfo32</a>.</div>
<h2>
Pick Your Poison</h2>
<div>
<h3>
Install and Fix</h3>
To modify the new UEFI scheme you need to use either the Windows utility command-line program bcdedit (run from the native shell, NOT a replacement like Console2, and as Administrator), the free-for-non-commercial-use <a href="https://neosmart.net/EasyBCD/" target="_blank">easyBCD</a> or the also free-for-commercial-use <a href="http://www.boyans.net/bootnext/bootnext.html">BootNext</a> utility. Unfortunately easyBCD only works with BCD over the MBR and BootNext requires you to register on the blog site to download. The good news is that easyBCD is easy to use.<br />
<h4>
Using easyBCD (BCD / MBR)</h4>
</div>
<div>
After much searching and consternation I found an Ask Ubuntu <a href="http://askubuntu.com/questions/62440/is-it-possible-to-boot-ubuntu-using-the-windows-bootloader">post</a> on how to dual boot Windows and Linux as well as an in depth <a href="https://neosmart.net/wiki/easybcd/dual-boot/linux/ubuntu/">walk-through</a> on the easyBCD site. Basically you install normally with the Advanced Partitioning, and then tell Windows how to find Ubuntu. These posts let me boot to Ubuntu after poking through the boot menu after an error about being <a href="http://askubuntu.com/questions/276923/how-can-i-fix-the-missing-nst-autoneogrub0-mbr-error-on-windows-8">unable to find the /NST/AutoNeoGrub0.mbr</a><span id="goog_2136083774"></span><span id="goog_2136083775"></span><a href="https://www.blogger.com/"></a> file. This happens when you use easyBCD with UEFI.<br />
<h4>
Using BootNext (BCD / UEFI)</h4>
</div>
<div>
While BootNext supports UEFI it appears to only have a help file for <a href="http://www.boyans.net/DualBootWindows7andLinuxOrUnix.html">installing with Windows 7</a>. Also the method is complex as you have to load your Ubuntu partition under Windows and then copy 512 bytes of the <a href="http://en.wikipedia.org/wiki/Boot_sector">boot sector</a>. This leads us to the option of having UEFI and installing it right to begin with.</div>
<h3>
Install it Right</h3>
<div>
It turns out that there was a hard-to-find article on installing Ubuntu alongside another OS with UEFI enabled at <a href="https://help.ubuntu.com/community/UEFI">help.ubuntu.com</a> and is far easier to understand than a <a href="http://askubuntu.com/questions/221835/installing-ubuntu-on-a-pre-installed-windows-8-64-bit-system-uefi-supported">similar Q&A page</a>. The critical part of this article is that when you install Ubuntu in "Advanced" mode to manage your system partitions you need to find your UEFI partition and mount it at /boot/efi. You can find this partition by going into the Windows' Disk Management utility and look for a partition with a Status of "Healthy (EFI System Partition)" and note which partition this is (in my case, it was the second partition on the disk). Remember to create a SWAP partition (1x or 2x as large as your RAM, see the <a href="https://help.ubuntu.com/community/SwapFaq">FAQ</a>) as well as your main Ubuntu partition (20 GB or more).</div>
<h2>
Conclusion</h2>
<div>
So, in this article we have seen the history of boot loaders, the different kinds of boot loaders and tools to work with them as well as how to install Ubuntu and then tell Windows about it or installing Ubuntu correctly in the first place. This has been one of the more difficult articles that I have written and I hope that I distilled my research over about 30 different tutorials and Q&A pages into an easy to understand format.</div>
Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com1tag:blogger.com,1999:blog-136862743052884956.post-40996111592069328782014-04-29T21:05:00.002-07:002014-04-29T21:05:48.922-07:00Using JS Test Runner with slf4j-log4j12Hello.<br />
<br />
If you've tried using <a href="http://js-testrunner.codehaus.org/" target="_blank">JS Test Runner</a> to integrate your <a href="https://qunitjs.com/" target="_blank">QUnit</a> <a href="http://www.smashingmagazine.com/2012/06/27/introduction-to-javascript-unit-testing/" target="_blank">JavaScript unit tests</a> with <a href="https://maven.apache.org/" target="_blank">Maven</a> you may have noticed that JS Test Runner has a <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies" target="_blank">transitive dependency</a> to <a href="http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCYQFjAA&url=http%3A%2F%2Fwww.slf4j.org%2Flegacy.html&ei=tHJgU-KhEYSGyATjp4HgDw&usg=AFQjCNGlZXeG4iBHbU6Po_NUIrmQeUYytw&bvm=bv.65636070,d.aWw" target="_blank">slf4j-jcl</a> (<a href="http://www.slf4j.org/" target="_blank">Simple Logging Facade for Java</a> with Jakarta Commons Logging bridge). This is supposed to be easily fixed by using Maven's dependency <a href="https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html" target="_blank">exclusions</a> but for some unknown reason this did not work for my project. This resulted in two slf4j appenders being present at the same time, causing a <a href="http://www.slf4j.org/codes.html#multiple_bindings" target="_blank">warning</a> from slf4j ("Multiple bindings were found on the class path"). A warning usually isn't too bad of a problem but it caused the <a href="https://cloud.google.com/products/app-engine/?utm_source=google&utm_medium=cpc&utm_campaign=appengine-search&gclid=CJjGpvWoh74CFcJqfgodZn8AMg" target="_blank">Google App Engine</a> to crash locally, making it a blocking issue. I tried manually changing the <a href="https://maven.apache.org/pom.html" target="_blank">POM</a> file the <a href="https://www.google.com/search?q=programming+the+%22right+way%22" target="_blank">Right Way</a> by cloning the <a href="http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCgQFjAA&url=http%3A%2F%2Fgit-scm.com%2F&ei=E3VgU4vjII60yASvgIHQCw&usg=AFQjCNHBOAWIJWLQ6wmj_GErAgGzWCkTbA&bvm=bv.65636070,d.aWw" target="_blank">Git</a> repository and trying to run `mvn install` on an incremented version of it, but it required <a href="http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCYQFjAA&url=http%3A%2F%2Fwww.gnupg.org%2F&ei=LnVgU-2zOIOkyATJzoKYBg&usg=AFQjCNHDtcT_0gkgD4oYxV91k4ikbYHsVQ&bvm=bv.65636070,d.aWw" target="_blank">GPG</a> and that failed on my Windows 64bit machine ("Sorry, no terminal at all requested - can't get input"). So, out of desperation I "<a href="http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCYQFjAA&url=http%3A%2F%2Fwww.gnupg.org%2F&ei=LnVgU-2zOIOkyATJzoKYBg&usg=AFQjCNHDtcT_0gkgD4oYxV91k4ikbYHsVQ&bvm=bv.65636070,d.aWw" target="_blank">monkey-patched</a>" the current POM (1.0.2) manually to use slf4j-log4j12 (like the rest of my project) instead of slf4j-jcl. This has been working beautifully... but is a blatant hack.<br />
<br />
In Summary, if you're having problems with JS Test Runner vis a vis logging you want to manually edit the POM file in your local repository (and document it in your project).Michael Amiethysthttp://www.blogger.com/profile/13937073392411596211noreply@blogger.com0