The Landscape is Changing

March 11th, 2019

cubeLifeView.gif

This morning I read a tweet that was re-tweeted by a guy I used to work with. The tweet said:

If anyone needed to hear it: I don't care about .dev domains or mechanical keyboards, I don't read Hacker News, I don't have a customized terminal, I don't spend all weekend coding, I sometimes use the Git GUI in my IDE, and I am valid in tech and so are you.

The person that wrote this isn't important - they are right - they are every bit as valid in this industry as anyone else. There isn't a "test" of "worthiness" to get, and keep, a job in this industry. And those that treat someone as less of a person, or less of a value to the organization are just missing the point. Badly.

Not everyone has to want to do these things. That's perfectly fine. Take another industry - doctors, lawyers, professional sports - there are all kinds of doctors that don't read up on the medical journals in their weekends... and plenty of lawyers that don't read briefs to stay up on things... and all kinds of different levels of pro sports.

But we can't then also insist that the very best surgeon work on our loved ones. Or that if we're in trouble, and need a lawyer, that you get the very best one you can get to get out of trouble. Right? And we certainly can't be disappointed in our favorite team for not winning - Right? They are just as valid as anyone else in that industry. Right?

Or is 'valid' the only metric we want to use here? I agree that the old Doc Hollywood story is about what you value - and sure, you're not doing amazing surgery saving lives, but that's not what you value - relationships are. But no one would call a Doc Hollywood to do heart surgery - and when you need a heart surgeon, you don't want to think that Doc Hollywood is your best alternative.

And when you feel you've been wrongly accused - you probably don't want to have to rely on the Public Defender. They are just as valid in the legal profession... and no one should make them feel like "less" of a lawyer because they are in the Public Defender's office... right?

As I read this tweet two things struck me:

  • This person works with some serious jerks - it's clear that this person has been working with, or working around, some major jerks that feel there is some litmus test to be a "good developer" - or even a "real developer". That's just wrong, and you can't change other people's attitudes, so my advice would be to find another job. There are better ones out there.
  • 'Valid' isn't the same thing as 'Value' - no one should be so marginalized that they feel that their fundamental worth is in question - but that's not to say that everyone is equal, either. Skills matter. Experience matters. Value isn't the same thing as validity. I can play basketball... but I have no business playing on the Lakers. And I shouldn't expect to.

I would like to tell this person: "Listen, you're right - you work with jerks - ignore them. Get a job that you like, and do your best." but at the same time, I can't say that this person should also expect to see the same paycheck as those that work 7 days a week. Or those that have devoted decades to their craft. Just recognize that choices matter.

Technology really has become the new workplace where classic blue-collar and white-collar jobs are mixed into the same pot. There's nothing wrong with picking what you want to do, and what's important to you - and you should not be made to feel your choices somehow make you less of a person. But they do have consequences.

An Old Knight – in a Rusted Suit of Armor

March 6th, 2019

Sad State of Affairs

This morning I was chatting with my Boss, and we were talking about the progress that was being made - and I had to admit, that we are starting to at least work together - as opposed to hold meetings where we disagree, but make no decisions, and just table the discussion for the next meeting. This works to simply make no progress, and it can be quite effective. But we're not there, and that's a really solid move in the right direction.

But that is not to say that yesterday wasn't a challenge. I understand how oppressive a job can be where you are not valued, where you are not listened to - I've worked in them. But the flip-side is no better - where every person in the company feels entitled to reject an assignment because they are self-empowered, and the management team does nothing to dissuade them of that opinion.

So I find myself in the position of, once again, patiently explaining requirements for a project to members of a team that simply will not accept it, and so won't be on the implementation team, and we'll simply have to get new folks. These guys can support the legacy stuff - it's all their stuff, and it'll be around for at least a year or so, so they have jobs, and comfortable ones, but they won't be on the new stuff - because they don't believe in it.

And that got me to make the statement:

I feel like an Old Knight - in a Rusted Suit of Armor. Way past his time.

and it struck me that this was a turning point for me. To see that Honor, Integrity, and Commitment are so vital to me, and so completely foreign to them. For example, I may not like what I'm doing, but it's the Job. It's the social contract on employment - I agree to do the job they ask me, and they agree to pay me the promised wage.

That's it.

No arguments.

My choice, and my power is to change jobs. That's perfectly acceptable. I can change jobs as often as I want, and for whatever reasons I wish. That's my choice and power. But if I'm here, and taking the wage, then by golly, if they ask you to do the job then you do it. Period.

This isn't about being hired as a Data Scientist, and being asked to pick up an AK-47 and defend the CEO's mansion from zombies... this is about accepting a job to develop software, and being asked do just that. It's simple.

But clearly, in today's environment, it isn't. Which is why I feel so completely out of time with many of my co-workers. They can't understand me because they don't have the same sense of what's important to me, and while I can understand why they feel entitled (too many Participation Trophies) it doesn't excuse the behavior.

Just like an Old Knight... in a rusted suit of armor.

Fixing up Clojure’s REPL Colorization and Formatting

February 20th, 2019

Clojure.jpg

A couple of days ago, I found out about the licensing rules for JDK 11 from Oracle, and wanted to install OpenJDK 11 with Homebrew. Sadly, Homebrew doesn't really like the idea of installing older versions of packages, so I'm going to live with JDK 1.8, and OpenJDK 11. But that's not what this is about. 🙂 This is about Clojure, and Leiningen's REPL, and the fact that in that post I found a known problem with the current version of Ultra, and Leiningen versions greater than 2.7.1

Well... a little digging, and I find that the core component of Ultra is another project, and that same author has a similar REPL formatter and colorizer - called whidbey. Now it turns out that whidbey also has issues with Leiningen 2.9.0 - but at least it works with 2.8.3, so I can upgrade to 2.8.3, and then let them figure out the issue with nREPL 0.6.0 - as it's already an issue on whidbey.

So until then, I have both in my ~/.lein/profiles.clj, and I can flip between the two as needed:

  {
   :user {:plugins [[lein-exec "0.3.7"]
  ;                  [venantius/ultra "0.5.4"]
                    [mvxcvi/whidbey "2.0.0"]
                    ]
          :middleware [whidbey.plugin/repl-pprint]
          :whidbey {:color-scheme {:delimiter [:bold :yellow]
                                   :tag [:bold :yellow]
                                   :nil [:cyan]
                                   :boolean [:bold :cyan]
                                   :number [:bold :green]
                                   :string [:bold :red]
                                   :character [:cyan]
                                   :keyword [:yellow]
                                   :symbol [:bold :magenta]
                                   :function-symbol [:bold :blue]
                                   :class-delimiter [:blue]
                                   :class-name [:green]
                                   :exception [:bold :red]}}
          :ultra {:color-scheme ;; :solarized_dark
                   {:delimiter [:bold :yellow]
                    :tag [:bold :yellow]
                    :nil [:cyan]
                    :boolean [:bold :cyan]
                    :number [:bold :green]
                    :string [:bold :red]
                    :character [:cyan]
                    :keyword [:yellow]
                    :symbol [:bold :magenta]
                    :function-symbol [:bold :blue]
                    :class-delimiter [:blue]
                    :class-name [:green]
                    :exception [:bold :red]}}
          }
  }

At this point, I can switch to 2.8.3 with:

  $ brew switch leiningen 2.8.3
  Cleaning /usr/local/Cellar/leiningen/2.7.1
  Cleaning /usr/local/Cellar/leiningen/2.9.0
  Cleaning /usr/local/Cellar/leiningen/2.8.3
  3 links created for /usr/local/Cellar/leiningen/2.8.3

and I'm good to go with Leiningen 2.8.3, and as soon as whidbey is updated, I'll be able to move up to 2.9.0. Really glad I found this project.

[3/6] UPDATE: it looks like ultra is getting an update that will allow it to work with Leiningen 2.9.0 - which is great! I just need to wait for ultra 0.6.0 to hit Clojars, and I can update and use it. That would be very nice!

Ordered a Chrome Duffel

February 20th, 2019

Chrome Bag

This morning I got an email that said that the Spectre Duffle Bag I'd ordered from Chrome Industries had shipped from California, and it should be at my door by the end of the day tomorrow - Thursday. The reason for the bag was that I've been using the same luggage that my delightful ex-wife bought for us - as a family, and while it's OK... it's two huge roller bags, and a cosmetic case, that I've been using for the few trips I have needed something.

But I'm old enough to get my own luggage - in fact, it's arguable that it's about time. So when I knew I had to make a trip to Seattle next week, I looked around and decided now is as good a time as any.

My top picks were Chrome bags - and Away Travel. The former made the messenger bag I use daily, and can't say enough good things about, and the latter is promoted on The Talk Show all the time. I like the hard exterior of the Away bags, but I wasn't sure how much they would hold, and they didn't give a lot of details on the size or what to expect.

Then I started looking at the Chrome bags, and I kinda ran into the same problem - What would it hold? Really not easy to see. So I measured the existing bag, and calculated the cubic inches, and then started comparing. Then I went to the airline carry-on page, and saw that the Chrome bag was exactly the right size to be a carry-on, and that you get one carry-on, and one laptop bag, and that would work great for me!

So I ordered the Chrome bag, and selected two-day shipping, because I wanted to make sure that I got it in time for this trip. And this morning, I found out that it would arrive! Fantastic!

Securing Google and Restoring GTalk

February 20th, 2019

Adium.jpg

Yesterday, I lost access to my GMail and GTalk accounts on my laptop - and it was saying that the password was bad. The first was covered in this post, and this morning I attacked the second. Overnight, I was just hoping that it was a transient thing, and that Google would restore whatever it decided to turn off, but that was not to be.

Given that Adium is now limited to just GTalk and ICQ, there really wasn't a lot of reason for me to keep it running, if I couldn't fix this authentication issue. So... knowing that Google wanted me to secure my account - but doing that would kill the old scheme for Adium, I decided to go ahead with it, and if it didn't work, then I'd just shut down Adium, and have to live with the loss of communication to my friends.

Securing Google

Police.jpg

So the first thing I needed to do was to turn off the Insecure Access in Google. This is just saying the old, plaintext, username and password being passed to Google. This was the only way the old Adium worked, and so I had to leave it like this. But that's all changing.

Once that was turned off, I knew I wanted to use Authy for the Authentication App for Google because I didn't like the SMS codes, and Authy is just a nice tool for exactly this purpose without worrying if your SIM card has been cloned. So I turned that on, and typed in the first code, and we're good to go.

Finally, I needed to generate a single Application Password for Adium, and that was all done from the Security tab in the Google Account Settings. Not bad at all, they generate a 16-character code, and you then use it for that app. You only get to see it once, so make sure you type it in correctly, but you can always make another.

Testing Adium

Once I had the 16-character application password for Adium, I pulled it up, typed it in, and BAM! it worked. I could almost not believe it! This was exactly like the POP3 issue - I'm guessing Google just got tired of the less-secure methods, and just shut them off. Period. Now with the 2FA on my account, the Application Password is as secure as Google wants to make it. 16 characters is gonna be really hard to guess.

And as I was testing Adium... still a little giddy that this all worked, and I had also locked down my account, I got a notice from Mail.app that I needed to enter my password.

Ah... IMAP was not using the 2FA, and I needed to pull up the accounts in Mail.app, and go through that login once to get the login using 2FA, and to to trust this device. When that was done, email was back online, and GTalk was too.

What a heck of a morning! Very good news!

Google Shutting Down POP3 Access

February 19th, 2019

Google Docs

Well... that was a heck of a realization! This morning, I notice that my Mail.app can't connect to GMail, and I wonder if it's something that is wrong with the account - or just Google. Oddly, Aduim also is not connecting to GTalk, and that's very strange. So I start digging into this.

I know that my password is valid. And I also know that I haven't had any Security Alerts from Google - so that's good. But still... both Gmail and GTalk are not allowing me to login.

I got caught up in a lot of other issues today, but got back to this, and on a lark, decided to look at the two Gmail entries in my Accounts for Mail.app - one was just for GMail, and the other was the more complete email/notes/contacts/calendar - and the latter had to be using IMAP, and I know the former was POP3. So let's disable POP3, and use the IMAP for mail.

Bingo!

It seems as though Google just shut off POP3 access. I looked at the settings, and it's still considered "on" in my GMail account settings, but that doesn't matter. I simply cannot connect to the POP3 site. OK... guess that's that.

At the same time, I'm wondering if the GTalk (XMPP) API is shut down as well? I'll give it a day, and then I'll have to accept that it's dead, and at that point, there's no need to have Adium running, as the only protocol it used anymore was GTalk, and with that gone, it's really pointless. Sad to see that happen. Very sad.

UPDATE: I downloaded Trillian from the App Store, and it doesn't connect to GTalk either. So this is not a single app or my credentials. This is just GTalk. We will have to see if it clears up tomorrow.

Neat Data Modeling Project

February 19th, 2019

Building Great Code

Today I've been having an email exchange with an old co-worker about an Open Source project that he's been working on - actually, it's pretty much done. It's all in Python, so it's not something that I'm really keen to use, but the design is good, and I can remember using something like it back at a previous job where we had to solve complex data modeling issues in as near real-time as possible.

The project is called dataflow and is really a compute/modeling system where you define Nodes and these nodes can be simple calculations on inputs, but they can be quite advanced - say rolling time averages, etc. and the key is that these Nodes can relate to one another in a simple Graph, that the user can describe, and then when any Node is updated, it fires off the updates of the dependent Nodes.

The nice thing is that these Nodes have a very simple API, and so they can do just about anything - averages of inputs, calculations, mean-square calls... it's really what the user wants to see. Tie this with a UI that displays the data, and you get something that is very powerful indeed. It can be a a Risk system where each Node can aggregate the child Nodes so that you can look across account, symbol, etc. and all updates as the input data updates.

It's been a nice reminder of some of the work I'd done at that job - but the work I did was in Java, and it was a bit more limited, but it still enabled some pretty nice apps to be built. Good stuff.

Moving to OpenJDK 11 – Kinda…

February 18th, 2019

java-logo-thumb.png

Well... today has been a very eventful day. I had noticed that Oracle dropped support for JDK 10, and mentioned it to some friends in Slack. I didn't know the details, so I decided to dig in and see if I could see anything on the net about it. I did. Lots. Changed my day.

Turns out, Oracle is changing it's licensing for JDK 11 - it's free for development and testing, but if you use it in production, it requires a license. A paid license. Yikes!

OpenJDK is also built by Oracle, and IBM, and RedHat - and it is Open Source - free for any use-case. So that's where people appear to be going. I can see that, but I've stayed away from OpenJDK because it's just the official JDK from Oracle. But now it seems Oracle is looking to cash in on the JDK, and this is just a lovely predicament.

But there is hope - kinda. Homebrew is supporting OpenJDK as a cask so that it can be versioned, and supported within the Homebrew ecosystem. That's good news. To install the latest, you simply need to:

  $ brew cask install java

and it will install it into:

  $ brew cask info java
  java: 11.0.2,9
  https://jdk.java.net/
  /usr/local/Caskroom/java/11.0.2,9 (64B)
  From: https://github.com/Homebrew/homebrew-cask/blob/master/Casks/java.rb
  ==> Name
  OpenJDK Java Development Kit
  ==> Artifacts
  jdk-11.0.2.jdk -> /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk
  (Generic Artifact)

and the tools I built for switching JDK versions work just fine:

  $ setjdk 1.8; echo $JAVA_HOME
  /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
  $ setjdk 11; echo $JAVA_HOME
  /Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home

That's the good news. What isn't really good is that there is an issue with the Java Collections where the toArray method added an additional arity and that breaks Clojure - badly. So it really doesn't help to have the OpenJDK 11 on the box - as Clojure can't make use of it.

However, that's not all... it appears that when I upgraded Leiningen, I broke one of the really nice plugins that I like to use with it - Ultra. The error is nasty as well:

  $ lein clean
  $ lein deps
  $ lein repl
  [WARNING] No nREPL middleware descriptor in metadata of
    #'clojure.tools.nrepl.middleware.render-values/render-values,
    see nrepl.middleware/set-descriptor!
  [WARNING] No nREPL middleware descriptor in metadata of
    #'clojure.tools.nrepl.middleware.render-values/render-values,
    see nrepl.middleware/set-descriptor!
  nREPL server started on port 54967 on host 127.0.0.1 - nrepl://127.0.0.1:54967
  ERROR: Unhandled REPL handler exception processing message
    {:id ad3092dd-8491-4d60-a1a9-5092d4d090a9, :op clone}
    java.lang.IllegalArgumentException: No implementation of method:
    :send of protocol: #'nrepl.transport/Transport

and if I removed Ultra from my ~/.lein/profiles.clj then everything worked fine again. But this was with Leiningen 2.9.0 - and that was an issue. In fact, it was an issue that's already been reported to Ultra. I added my notes, as the suggestion didn't work for me.

So now I'm left with downgrading Leiningen to get Clojure working again. This is not as easy as I'd hoped, but it's what needs to be done. First, get into where the Homebrew formulae are stored, :

  $ cd $(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-core/Formula
  $ git log --follow leiningen.rb
  commit 2be19f3787d811247095e704765fc33a8815d639
  Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
  Date:   Tue Feb 12 13:07:29 2019 +0000
 
      leiningen: update 2.9.0 bottle.
 
  commit 9ca7899818eb02cc8252d47cc32b5a42554a7655
  Author: Rahul De <rahul080327@gmail.com>
  Date:   Tue Feb 12 10:43:59 2019 +0100
 
      leiningen 2.9.0
 
      Closes #36927.
 
      Signed-off-by: Chongyu Zhu <i@lembacon.com>
 
  commit fd1c0ba8f162a3c41debef6143dca8ba19227f90
  Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
  Date:   Sat Dec 15 10:45:41 2018 +0000
 
      leiningen: update 2.8.3 bottle.
 
  commit 40553be0b01710db9e16cff978f593b83ecdfe3b
  Author: Rahul De <rahul080327@gmail.com>
  Date:   Sat Dec 15 11:27:08 2018 +0100
 
      Leiningen 2.8.3
 
      Closes #35151.

at this point we heed the git SHA for the version we want to move to. In the case of Leiningen, the SHA for 2.8.3 is fd1c0ba8f162a3c41debef6143dca8ba19227f90 and the SHA for 2.7.1 is cdddd1094b26d0092e0030051dac97a286bb3fc4. I started with 2.8.3, and that didn't work, so I had to go back to 2.7.1. This is a big difference.

Then make a branch for that version, and reinstall Leininden from the Ruby file:

  $ git checkout -b leiningen-2.8.3 fd1c0ba8
  $ brew reinstall ./leiningen.rb
  $ brew switch leiningen 2.8.3
  $ git checkout master

for 2.8.3 and, for 2.7.1:

  $ git checkout -b leiningen-2.7.1 cdddd109
  $ brew reinstall ./leiningen.rb
  $ brew switch leiningen 2.7.1
  $ git checkout master

At this point, we can see that both versions are installed:

  $ brew info leiningen
  leiningen: stable 2.7.1 (bottled), HEAD
  Build tool for Clojure
  https://github.com/technomancy/leiningen
  /usr/local/Cellar/leiningen/2.7.1 (9 files, 14.7MB) *
    Poured from bottle on 2019-02-18 at 13:29:34
  /usr/local/Cellar/leiningen/2.8.3 (9 files, 13MB)
    Poured from bottle on 2019-02-18 at 13:22:14

Now it's possible to run Leiningen and Ultra - again. It has to be JDK 8, and Leiningen 2.7.1... but until Ultra is fixed for the change in Leiningen, this is as far as I can go.

What was even more annoying was that my new work laptop has a very recent version of Homebrew on it, and the git repo has been trimmed, and so there is no git SHAs for the previous versions. However, with tar and copying the tarball over, I was able to get the 2.7.1 and 2.8.3 versions there, and things are now working OK.

Wow! What a mess to get back to where I thought I started the day!

Really Enjoying the New Apple TV 4K

February 18th, 2019

TV.jpg

A few months ago, I got a new Apple TV 4K, primarily because my old Apple TV was getting very slow in selecting ESPN, and in the morning, I just want to get on the treadmill and start running. So I invested in a new one, and I'm very glad I did. It's just amazing.

First, I really like the remote. I like the touch pad, and while it took a little getting used to, it's nice to have it on the remote, as opposed to the four direction buttons. A very nice upgrade. Add to that, the remote is rechargeable with a Lightening cable. This is great because I can then charge my AirPods, the Remote, or my iPhone all from the one cable that's connected to my Thunderbolt Display. Very nice.

Second, it's fast. That's what I expected from it, and that was not a disappointment. Exactly as advertised, it is zippy, and I don't have the multi-minute waits switching channels on ESPN. That was expected.

Third, and this was a surprise - the TV App that exists on my iPhone and the new Apple TV 4K is really almost something to drop cable over. It allows me to focus on the Shows I want to watch, and not the networks they appear on. I can look at my iTunes Movies as well, and it remembers the position in each movie, and show, so that I can move to my iPhone and watch a little bit, and then transfer back to the Apple TV 4K. This isn't Rocket Science, but it's an excellent implementation of the iCloud storage, and syncing. It's just great.

Now I've heard there are games for the Apple TV 4K, but I am not a big game player, but I will admit that I've purchased a lot more movies now that I have the Apple TV 4K than I did before. Which is good for me, and good for Apple.

It's not the most amazing thing Apple makes, it'll never have the attention that the iPhone or iPad has, but it's a fantastic little box, that is absolutely what I was looking for. Nice.

Interesting Wrinkle with Homebrew and git

February 15th, 2019

Homebrew

This morning I was working to upgrade my laptop from Postgres 10.3 to 11.1, and I did the following, as part of the upgrade:

  $ brew update
  fatal: could not read Username for 'https://github.com': terminal
  prompts disabled
  Error: Fetching /usr/local/Homebrew/Library/Taps/homebrew
  /homebrew-boneyard failed!

I did a lot of googling, and came up with a couple of ideas. This was from GitHub:

  $ git config --global credential.helper osxkeychain

but that didn't work. Then I found another reference saying that the 2FA on GitHub was the problem, and that you needed to bypass that with:

  $ git config --global --add url."git@github.com:".insteadOf "https://github.com/"

and still that didn't work. So I took a different approach, I started looking at the Homebrew files on my laptop - specifically, the boneyard mentioned in the error. Turns out... if you looked at the .git/config file in that directory, it points to a directory in GitHub that no longer exists! OK... this might be something.

So I removed the nearly empty directory, and tried again:

  $ brew update
  Already up-to-date.

Success! It wasn't the config of git - it was that Homebrew was trying to update something that no longer existed. Lesson learned.