Thursday, 15 December 2016

Subclassing Custom Java Class in Clojure

Here are the ways to subclass a your custom Java class from Clojure. I have been fiddling to get this to work with lein for some time now and SO to the rescue of course. In your lein project say you have Java source at src/java. You want to extend a class from clojure, call super class method etc. There are two ways to extend, proxy and gen-class.
It's important to note that you need to have a package structure for the Java classes. Naked classes don't work because it's getting qualified to java.lang namespace when you try to run giving a ClassNotFoundException.
// src/java/com/example/
package com.example;

public class BaseClass {
    public String greet() {
        return "Hello from BaseClass";
You need to specify the Java source location using :java-source-paths in project.clj. If you are using :gen-class to extend, then you need to aot compile your clojure file. When running project with :java-source-paths added under Windows, I am getting the following error even if JAVA_HOME is set to JDK location and bin is in path.
Java compiler not found; Be sure to use java from a JDK
rather than a JRE by modifying PATH or setting JAVA_CMD.
Adding JAVA_CMD env variable to point to java_home-path\bin\java works.
; project.clj
(defproject subclass "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :java-source-paths ["src/java"]
  :main subclass.core
  :target-path "target/%s"
  :aot [subclass.core]
  :profiles {:uberjar {:aot :all}})
Extending using :gen-class use :extends keyword. If you want to call a super class method, use :expose-methods to specify an alias under which that method will be available locally. Here the greet from BaseClass is locally referred as pgreet
; src/subclass/core.clj
(ns subclass.core
   :extends com.example.BaseClass
   :exposes-methods {greet pgreet}))

;; greet method override. gen-class prefixes generated classes with '-' by default.
(defn -greet [this]
  ;this arg is the object of this class, i.e., subclass.core.
  (.pgreet this) ;calls super class' greet()
  (println "hi from clj"))

(defn -main [& args]
  (.greet (subclass.core.)))
Running the above gives
$ lein run
subclass.core=> (-main)
Hello from BaseClass
hi from clj
Extending using proxy.
; src/subclass/core.clj
(ns subclass.core
  (:import com.example.BaseClass))

(defn my-greet [] 
  (proxy [BaseClass] [] ;the class to extend
    ;override greet()
    (greet []
      (proxy-super greet) ;call super class method
      (println "hi from my-greet"))))

(defn -main [& args]
  (.greet (my-greet))) ;calling my-greet returns a proxy object. Invoke greet method on it.
Running the proxy version gives
$ lein repl
subclass.core=> (-main)
Hello from BaseClass
hi from my-greet
Using proxy or gen-class for extending depends on your use case.

Thursday, 8 December 2016

Slideshare Upload Failing With 307 Internal Redirect

If you try to upload files to slideshare from Chome and the upload fails with a status code of 307 Internal Redirect (in Network tab of dev console) with Non-Authoritative-Reason: Delegate as response header and you get XMLHttpRequest cannot load Response for preflight is invalid (redirect) error, means that your browser is redirecting an http request to https and it is failing. In my case it was because of the HTTPS Everywhere chrome extension. You want to uncheck Amazon Web Services from the extension for the upload to work. Also, if you have PrivacyBadger, then adjust it for the site if login fails.

Use .gitattributes to Override Language Detection in Github

Github uses linguist library to detect the languages used in a repository. It ignores library codes from counting towards the language percentage. So if you have files that are not part of the main code which are not in the vender specific path and you wanted to ignore them from the statistics, you can tell github to not count them by specifying it in .gitattributes file. Say I have a public folder which contains documentation or support files which I wanted to ignore, then the .gitattributes file will look like below.
public/js/libs/* linguist-vendored
public/* linguist-documentation
You can add linguist-vendored or linguist-documentation to ignore the files from counting. You can see the difference in the language statistics bar of your repository.

PrivacyBadger - Commenting on Blogger using Google Account

If you are using PrivacyBadger, your comments at blogger using Google account won't work. Also you cannot preview the comments as this extension blocks cookies. You need to enable cookie from in PrivacyBadger for this to work.

Wednesday, 7 December 2016

Configuring Leiningen and Git to Work Behind Proxy Under Windows

If you are behind a corporate proxy, you need to add the proxy details before lein or git can work.

Add the following environment variable name with value as given.
# env name
# env value
# env name
# env value
After setting the above, lein will be able to connect through the proxy.

Add the following in a file called .gitconfig under C:\Users\username.
    proxy = http://username:password@proxyurl:port
    proxy = http://username:password@proxyurl:port
If the ssh protocol and port is blocked, you can use the https version to clone and push changes to github. Give the github username and password when prompted. However if you have 2FA enabled, you need to first create an access token. Go to Personal access token under github settings and generate one. Under permissions, only repo needs to be enabled to push the changes to github. When you push, a github popup will prompt for authentication, where you enter your github credentials. Next the git bash will prompt for authentication where you should enter the generated access token for your password. It should get through the proxy.

Sunday, 4 December 2016

Download All Your Emails The Easy Way

You can have offline copy of all your emails with attachments using just Thunderbird.
1. Connect to your webmail account using IMAP (so that the server retains a copy of your mail).
2. Enable "Allow remote content in messages" under Privacy section of the Preference if you want images in the email to be downloaded as well. (See note below).
3. Make sure that the you have the following settings under "Synchronization & Storage" of your Account Settings.
    3.1 Enable "Keep messages for this account on this computer".
    3.2 Under "Advanced" enable all the folders that needs to be synchronized.
    3.3 Under "Disk Space" choose "Synchronize all messages locally regardless of age".
    3.4 Enable "Don't delete any messages".
4. Now click the computer icon on the lower bottom corner of Thunderbird or choose File->Offline->Work Offline. A popup will be displayed. Choose "Download Now".
Thunderbird will now download all your emails and attachments offline.

NB: The only caveat is that Thunderbird won't download remote contents like images from unknown senders even if you enable remote content (step 2). The sender has to be present in your address book or you need to whitelist the domains. See instructions here. This is for privacy reasons.

1. It's better to have full disk encryption (LUKS) and home directory encryption enabled or at least the later to keep your mails safer.
2. Enable master password in Thunderbird. Install StartupMaster extension. It fixes the multiple password prompt if you have multiple email accounts added.

Lisp for High Performance Transaction Processing

Lisp for High Performance Transaction Processing is a talk given by Daniel Weinreb on Aug 2009. The original video is not available now as it was later set as private and now taken down. You can watch or download the talk here or read the excerpt.
It's mainly about the use of Lisp at ITA which now is a part of Google. ITA's products are QPX which is an airline fare search program and res which is the airline reservation system. They use Common Lisp and Clozure CL for their business layer. The presentation is in Java and Oracle for their database. C++ is used for bit manipulation, cryptography, and other performance critical areas. Couple of Python, Perl, Shell etc. He just mentions that computational linguistics algorithm, rule based expert system and diversity algorithms are being used. He also talks about the future direction of Lisp especially with Clojure towards the end of the talk. In general, it's an interesting talk.
Watch or download.

Thursday, 1 December 2016

Chrome App Identity Authentication Not Working Issue

When you try to authenticate the user using OAuth 2.0, to access Google APIs from your chrome app and if it loads a URL like chrome://chrome-signin/?access_point=5&reason=0 means that there is issue with validating your client_id and your extension id. When you are developing chrome app, the extension id of the loaded unpacked extension might not be the same as the id generated by the chrome webstore. So when you create a chrome app oauth 2.0 client id from Google APIs console, instead of giving the chrome webstore URL id which it suggests, give your local extension id. Then use the obtained client_id in your manifest. Next time when you call the chrome identity API, it should show the OAuth permission popup. Basically, your chrome extension id should match the id used for generating the oauth credentials. Before publishing, use a different client id generated from the chrome webstore URL.