Java Hello World With Visual Studio Code and Eclipse

Hello World in Java with Visual Studio Code

  • Download and install a JDK. (Look for “Java SE Development Kit”.) If you don’t get an error when you type “javac -version” at a Command Prompt (Terminal window in Mac), you already have a JDK.
  • Download and install Visual Studio Code (VSCode) from https://code.visualstudio.com/download
  • Launch VSCode
  • Tell VSCode to create a new file via File > New
  • Paste the following text
public class test1 {
    public static void main(String[] args) {
        System.out.println("Hello, World");
        System.out.println("Goodbye, World");
    }
}
  • File > Save As > test1.java
    • VSCode will prompt you to install the Java extension pack. Do so. It will take a few minutes.
      • When it finishes installing, it will show a “Reload” indicator. Click it.
      • It might give you a “Classpath is incomplete” warning.
        • This happens every time you work with a stand-alone Java file (i.e. a Java file that is not part of a project.)
        • For now, just dismiss the warning.
  • View > Integrated Terminal
    • cd to the directory where you saved test1.java
    • javac test1.java
      • ‘javac’ is the compiler. ‘java’ is command which used to run a compiled program.
    • Do a directory listing. Observe that javac compiled test1.java to test1.class.
    • java test1
      • It should display “Hello, World”

Note that you will almost never create a Java program this way. This is a special process for a single-source-file Java app. Typically, your app will be comprised of many files, and you’ll have to create a ‘project’ to tie them all together. Most Java projects are godawful complex things which require a ‘build tool’ to compile and assemble them into something you can run. There are multiple build tools which Java developers use because developers often say, “This is awful. I could build something better.”

We’re going to use Maven. Maven is good for our purposes because VSCode works with it and so does Eclipse, in case you later decide you have to suffer Eclipse. Maven revolves around a ‘POM file’ (Project Object Model), which is written in XML.

We’re going to abandon this stand-alone source file and create a hello-world Maven project; we’ll also set you up to use the Java debugger.

  • Close VSCode.
  • For Mac
    • Run “brew install maven”. It will install to /usr/local/bin/mvn.
    • Run mvn --version
    • Add this to .bash_profile, substituting the value for Maven home as reported by mvn (above).
      • export M2_HOME=/usr/local/Cellar/maven/3.5.2/libexec
      • export M2=$M2_HOME/bin
      • export PATH=$PATH:$M2_HOME/bin
  • For Windows, download and unzip Maven from http://maven.apache.org/download.cgi.
    • You want a “Binary zip archive”. Choose the link from the “Link” column to start the download.
    • Store it in a directory all by itself. Maybe name that directory “MAVEN”.
    • Set a M2_HOME environment variable to point to the MAVEN directory.
    • Set a M2 (not M2_HOME - just ‘M2’) environment variable to point to the bin subdirectory of the MAVEN directory.
    • Add the M2 (bin) directory to your PATH.
  • In your Terminal window (Command Prompt), navigate to an empty directory, where you wish to create your Java project.
    • mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
      • This may take a long time.
    • cd to my-app/src/main/java/com/mycompany/app. (If you’re on Windows, your slashes lean the other way.)
    • Run a directory listing and you’ll see App.java. Examine the contents. You’ll see that Maven created a hello-world app for you. This godawful directory structure – that’s how Java apps are built.
  • Launch VSCode and open the my-app directory from the File menu.
    • In the left panel of VSCode, navigate to my-app/src/main/java/com/mycompany/app, and open App.java
    • Find the line with System.out.println. Left-click with your mouse, just to the left of the line number. You should see a red circle. You’ve just set a breakpoint on this line.
    • Choose Debug > Start Debugging from the menu. If it asks what kind, select Java.
    • It will highlight the line with your breakpoint. It executed all the code before that point, and stopped.
    • Choose Debug > Step Over. It will execute your println, and you’ll see the output displayed in the bottom panel.
    • Choose Debug > Continue. It will ‘execute’ all those closing braces and terminate your program normally.

Hello World in Java with Eclipse

Install and Launch LiClipse

We’re going to use LiClipse, which is Eclipse bundled with some other tools.

  • Download and install a JDK. (Look for “Java SE Development Kit”.) If you don’t get an error when you type “javac -version” at a Command Prompt (Terminal window in Mac), you already have a JDK.
  • Download and install LiClipse from http://www.liclipse.com/download.html
  • Launch LiClipse (henceforth to be referred to simply as Eclipse).
  • Eclipse wants to use a “workspace”. That’s the root folder for all projects you develop using Eclipse. Pick one that suits you. On my Mac, I use /Users/kevin/Sync/code. Unless you want it to nag you each time you launch it, select “Use this as the default and do not ask again”.
  • Help > Install New Software > select “Eclipse x.x Release…”
    • In the “Type Filter Text” field, type “java” and press Enter.
    • “Select Eclipse Java Development Tools” and press Next; then work you way through the Wizard until it is installed.
    • Watch the progress dialog in the lower-right corner of Eclipse. Don’t proceed until it hits 100%. It may be sloooow.
    • When it wants to restart Eclipse, let it.

Create and Run a Single-file Java App

You really, really have to put your single-file Java app in a project. If you don’t, you’ll find yourself unable to save your file. Eclipse understands projects. It doesn’t really deal with stand-alone files.

  • File > New > Project > Java > Java Project. Press Next.
    • Enter a project name of test1.
    • Choose “Use Project folder as root for sources and class files”
    • Press Finish.
    • It will natter about opening a Java Perspective. Let it, and tell it to always do so. It is just going to open the panels which are relevant to Java.
  • File > New > Class
    • Source folder = test1
    • Package = (empty)
    • Name = test1
    • Superclass = (empty)
    • Clear ALL checkboxes
    • Press Finish
  • Make the test1.java file contain:
public class test1 {
    public static void main(String[] args) {
        System.out.println("Hello, World");
        System.out.println("Goodbye, World");
    }
}
  • File > Save
  • Locate the toolbar icon for “Run”. (One of the icons with a green circle with a triangle.) Press it.
    • It will natter at you about Run Configurations.
      • Double-click “Java Application” and choose test1 (under Java Application).
      • Press the Run button.
    • Notice your output at the bottom of the page.

Note that you will almost never create a Java program this way. This is a special process for a single-source-file Java app. Typically, your app will be comprised of many files, and you’ll have to create a ‘project’ to tie them all together. Most Java projects are godawful complex things which require a ‘build tool’ to compile and assemble them into something you can run. There are multiple build tools which Java developers use because developers often say, “This is awful. I could build something better.”

We’re going to use the built-in Eclipse build too. If you ever need to do so later, Eclipse can also work with Maven projects and it can export Eclipse projects into Maven ‘POM files’. Maven revolves around a POM file (Project Object Model), which is written in XML.

We’re going to abandon this stand-alone source file and create a new hellow-world project; we’ll also use the Java debugger.

  • File > New > Java Project. Note that because you are already in the Java Perspective, Eclipse has hoisted ‘Java Project’ into the top-level menu. You can get the same effect via File > New > Project > Java > Java Project
    • Project Name = my-app2
    • Use default location
    • JRE: use whatever it defaults to
    • Project Layout: Create separate folders…
    • Press Finish
  • Stop and look.
    • You should now see TWO Java projects in the Package Explorer panel at the left side of Eclipse.
    • Sometimes, if one Java project is not causing you enough pain, Eclipse figures you might want to work on multiple projects at the same time. Getting started, one at a time is enough.:
      • Select my-app2. Then right-click it and choose “Close Unrelated Projects”. Tell Eclipse that you really meant to, when it asks.
      • You will still see a single folder for test1, even though it is closed. That’s how Eclipse works.
  • Select the src folder under my-app2.
  • Right-click src and create a new package:
    • Name it com.mycompany.app and press Finish.
  • Right-click com.mycompany.app and create a new class:
    • Source folder: my-app2/src
    • Package: com.mycompany.app
    • Name: App
    • Modifiers: Public
    • Superclass: java.lang.Object
    • Select “public static void main…” but leave the other checkboxes empty.
    • Press Finish
  • Take a look at the generated App.java file. It is almost a complete hello-world. Replace the TODO comment with:
        System.out.println("Hello, World");
        System.out.println("Goodbye, World");
  • File > Save
  • Locate the toolbar icon for “Run”. (One of the icons with a green circle with a triangle.) Press it.
    • It will natter at you about Run Configurations.
      • Double-click “Java Application” and choose test1 (under Java Application).
      • Press the Run button.
    • Notice your output at the bottom of the page.
  • Double-click the gutter, to the left of the line number by the first line with System.out.println. It will add a small dot to indicate that you have set a breakpoint on this line.
  • Locate the toolbar icon of an insect and the flyover help “Debug App”. Press it.
    • Eclipse will ask permission to switch to the Debug Persipective. Approve it.
    • It will highlight the line with your breakpoint. It executed all the code before that point, and stopped.
    • Choose Run > Step Over. It will execute your println, and you’ll see the output displayed in the bottom panel.
    • Choose Run > Resume. It will ‘execute’ all those closing braces and terminate your program normally.
  • Note that if you ever find Eclipse in the ‘wrong’ Perspective, you can change Perspective via Window > Perspective > Open Perspective.

Programming Languages for the Occasional Programmer

Work in progress (a ‘living document’):

I’m an occasional programmer. I might code intensively for a few months, then do other things, then return to programming. I don’t get to spend all day, every day, coding on any project. I need to be able to productively pick up a project after having set it aside. I need to be able to program in an environment without being intimately familiar with every nook and cranny of the environment.

I need to be able to write code for Windows, Mac, and web (client and server side), and Linux server administration. I have an interest in data science, so the ability to work there would be helpful. Of necessity, a discussion of languages will also include a discussion of platforms related to those languages.

Fewer languages is better than many languages. I’ve dabbled in many. The fewer I have to try to stay current in, the more time I can spend coding, rather than re-learning.

Popularity

Current popular multi-platform general purpose languages (in many rankings):

  • JavaScript - way, way most popular at GitHub
  • Java
  • Python
  • Ruby
  • Much lower frequency: Go, C, TypeScript, Scala, Clojure, R, Perl, Julia, Haskell

Clojure and ClojureScript

Conceptually, I like Lisp. In reality, I run into a problem with un-typed languages. After I pass a string into a routine expecting an integer, and it bubbles down through a half-dozen layers before it blows up, and I spend a long time tracking down where the defect was injected (as opposed to where it was detected), I then start writing code to check the type of actual parameters. Checking type at runtime is stupid; it is more effective to check at compile/load time. An occasional programmer really needs typing of formal parameters.

Clojure/ClojureScript solves the problem of one language for client and server.

I find coding in Clojure to be pleasant and rewarding, but the moment I start trying to test/run the code, it gets real frustrating, real fast, because trivial changes result in run… damn… run… damn… run… cycles.

Slow startup is a problem for some categories of scripts. e.g. If you wanted to write a utility like ‘cat’ or ‘more’.

And Clojure doc is written for the person who already knows the answer. (I’m not the only person to notice this.)

I think the Clojure ecosystem might be really appealing if I coded in it all day, every day. It appears to serve the SME really well.

I did about 6 months of part-time programming in Clojure, writing an app to rebalance my complex investment portfolio.

Ruby

Ruby is a pleasing language for small projects. I really Matz’s notion that using the language should please the programmer.

In common platforms such as Rails, there is so much magic happening behind the scenes that it takes me a couple of weeks to refresh myself on what is really happening, every time I pick it up.

The absensce of typed formal parameters leads me back to run-type type checking. An occasional programmer really needs typing of formal parameters.

Ruby really has to be one of multiple languages. You can’t really do your browser UI in Ruby.

The gyrations (tools) necessary in order to effectively develop with multiple versions of Ruby on a single system is off-putting.

Java

Someone captured the essence of Java nicely. Java is the COBOL of the 21st century. Verbose. No fun to work in.

Yes, it does have typed formal parameters. Yes, you can write Java that compiles to JavaScript to run in the browser. Yes, you can write cross-platform GUI apps in Java.

Slow startup is a problem for some categories of scripts. e.g. If you wanted to write a utility like ‘cat’ or ‘more’.

I don’t want to write in Java, and, frankly, I don’t like running Java apps. Even if you use something to give you a native look and feel, they still feel like Java apps.

Python

I want to like Python. I don’t quite. I can live with the indentation thing. Maybe I just need to do more coding with it.

Python 3.6 does support optional typing of formal parameters. I like the concept of optional typing, if all of the published libraries come with typing. I want me to be able to dispense with typing while hacking, but I want to see typing whever I use someone else’s code, and I want to throw a switch and require typing when I begin to production-ize my code.

Pyjamas, Brython, Skulpt, PyPy, Transcrypt: might let you write your browser-side code in Python. Need to check which of those actually works on iPhone and Android browsers.

It runs on almost all platforms. It is used in data science (behind R in popularity, of course).

“Batteries included” is an effective philosophy. “There’s only one right way to do it,” chaps my butt. As philosophers, I like Matz and I’m not sure I like Guido. (Guido may be a fine person to know; I’m just referring to his programming philosophy.)

It doesn’t really fit well with functional programming, although you can bend it to your will. I wish it supported a flag to say “make data immutable.”

Python has similar virtual-environment issues as Ruby, when you need to develop with multiple different versions.

JavaScript, TypeScript

JavaScript has the appeal of one language for client and server sides. Yes, JavaScript has good stuff, but you have to know which pieces to avoid using. TypeScript supports optional types, solving my need for typed formal parameters (except that many JavaScript libraries don’t come with types).

Electron… I want to use Electron, without the footprint of electron. File size I can live with; huge RAM use, not good; high CPU use, exhausts my battery. Shucks, with the Chromium footprint, I’m reminded that I have to switch from Chrome to Safari on my Macbook whenever I go on battery power.

If you get node.js involved, slow startup is a problem for some categories of scripts. e.g. If you wanted to write a utility like ‘cat’ or ‘more’.

If you’re going to use JavaScript, use a lint.

I love this quote

The thing is, there is a mass psychosis about JS and it’s like everybody is pretending that it isn’t awful.

Pascal

Yeah, other than Delphi, nobody really programs in Pascal anymore. I really loved that “train track” syntax diagram. Pascal was the last language where I really felt, “I know every iota of this environment.”

VB5

Yeah, it is a dead language and Windows-only. It was really a spiffy tool for exploration. You could change code on the fly, half-way through a function, and continue execution. You could explore the methods of an object at run-time. Lots of support for the occasional programmer.

The language itself was not real interesting. The built-in bugs were frustrating. The environment support for tinkering has never been surpassed.

Windows Batch File Format Date as YYYY.MM.DD

I often need a variable containing a yyyy.mm.dd date in a Windows batch file. Instead of figuring it out anew each time, use this code:

REM --- Get current date into yyyy.mm.dd format.
REM
REM NOTE: You really must use the "if not defined" in order to skip the trailing blank line.

REM clear tmpDate
set tmpDate=

REM This gets the date in a locale-independent format.
REM e.g. 20171130101642.469000-300
for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined tmpDate set tmpDate=%%x


REM Extract from tmpDate:
REM    position 0 for 4 chars
REM    position 4 for 2 chars
REM    position 6 for 2 chars
REM Adding "." between them
set YYYYMMDD=%tmpDate:~0,4%.%tmpDate:~4,2%.%tmpDate:~6,2%

echo YYYYMMDD is %YYYYMMDD%

Cygwin ssh Daemon How-to, 2017

Enabling the cygwin ssh daemon has changed over the years. Here’s my 2017 edition of a how-to (howto).

  • Run the Cygwin setup and select openssh.
  • open Cygwin64 Terminal (run with ADMIN)

ssh-host-config

tell it:

  • strict modes = no
  • new local account = no
  • yes, install the service
  • CYGWIN = (empty. it is no longer needed)
  • User ID to use = your-personal-Windows-user-ID. (If you use a non-admin and an admin user ID, enter the admin one). If you let the config create a service account, that ID will NOT be able to access network shares. I really want to be able to access network folders when using Unison or rsync!

cygrunsrv.exe –stop sshd /usr/sbin/sshd.exe -D

Solve any error messages. If Windows firewall asks, permit the access. Test your connection. Run ssh from a remote machine and ensure you can connect.

^C cygrunsrv.exe –start sshd

Note: To totally start setup over, first you must:

cygrunsrv –stop sshd cygrunsrv –remove sshd

IF you have an /etc/passwd, delete any sshd or cyg_server user ID.

net user sshd /delete net user cyg_server /delete rmdir /var/empty


Note: Start/stop daemon with:

cygrunsrv –start sshd cygrunsrv –stop sshd

Markdown Toolset

Summary: GitHub Flavored Markdown, kramdown, Marked 2, Typora

I’ve been using a hodgepodge of Markdown tools. I’d like to try and make sense of what I’m using and why.

I’m using Jekyll and GitHub pages (GHP) for my blogs. Jekyll and GHP use the kramdown parser. Per GitHub: “GitHub Pages only supports kramdown as a Markdown processor” and “we’ve enabled kramdown’s GitHub-flavored Markdown support by default.”

See:

  • https://help.github.com/articles/configuring-jekyll/
  • https://kramdown.gettalong.org/parser/gfm.html

So the question of which Markdown flavor to use is either:

  • GFM
  • kramdown

For now, unless I encounter a compelling reason to use native kramdown, I’m using GFM because it is the default on GHP and on GitHub issues.

Other than my blogs,I am the chief consumer of my Markdown documents. I do more reading that authoring. Consequently, I’m less interested in side-by-side (source + rendered) tools than many Markdown fans. I mostly want WYSIWYG editing – a simple WordPad-like (or TextEdit-like) experience for rich text documents. For documents with lots of embedded images or documents where I need precise page layout, I don’t use Markdown.

Mandatory Markdown Features

  • Core Markdown
  • Tables (with some kind of table editor - not just source editing of pipes and spaces)
  • MathJax
  • YAML front matter. Either ignore it, or give me some way to view/edit it.

Summary of Current Tools

  • Github Flavored Markdown: Rationalle explained above.
  • GitHub Pages - Blog publishing: I moved to GHP after my dynamic web site was compromised, and I decided I wanted simple, secure blog hosting.
  • Jekyll - Local blog preview: Since I publish with GHP (which uses Jekyll), I preview locally with Jekyll.
  • Markdown Parser: kramdown. It is what Jekyll uses.
  • Marked 2 - Document viewer (Mac only): A first-rate Markdown renderer. It supports the use of custom Markdown parsers. Natively, it supports Discount for GFM. Someday, I’ll get around to configuring it to use kramdown plus options to make it totally GHP-compatible.
  • Typora - WYSIWYG Editor: I really want a single-pane GUI editor. I prefer one that works on Windows and Mac. The primary candidates are Texts.io and Typora. Texts is “based on Pandoc”. Typora clearly states that it supports GFM. I prefer the non-ambiguous flavor. Texts rewrites perfectly good hand-edited Markdown. Typora less so. I prefer the “full GUI” approach of Texts, but the you-type-Markdown-you-get-WYSIWYG approach of Typora isn’t so bad, and it still leaves me viewing a single-pane rendered document. Texts and Typora are both available for Windows and Mac. Typora also supports Linux. I use all three. (Mac is my primary OS.)
  • none - side-by-side editor: I think there may be cases where I really want side-by-side editing (although I haven’t encountered them yet).
    • Haroopad and MacDown look feasible on the Mac, except see Haroopad YAML problem. Haroopad also supports Windows.
    • I’ve seen some non-Haroopad sites say that Haroopad supports GFM and MathJax. MacDown can be configured to support GFM per https://macdown.uranusjr.com/faq/#gfm , and MacDown supports MathJax.
    • Another candidate is Atom. (markdown-preview-kramdown plugin just doesn’t work right!) I already use Atom for Clojure development.
    • This is an online option: https://kramdown.herokuapp.com/
    • IF I decide I need this, MacDown looks best.

YAML

  • In YAML front matter, if you need a comment, use space-#. If you begin a line with a #, most tools treats that as a title, even in front matter.
  • Marked 2 allows you to strip front matter before rendering. [good]
  • Typora put front matter in a gray box and uses typewriter font. [best]
  • MacDown has a “Detect Jekyll front-matter” option, and puts it in a table. [OK]
  • Haroopad treats front matter as Markdown. [unacceptable]
  • kramdown.herokuapp.com - treats front matter as Markdown. [unacceptable]

Hacks

  • kramdown.herokuapp.com seems to require a blank line between a title and a bullet list. This is reportedly common. My other tools render this as desired. I need to remember to add the blank line after the title.
  • Consider using lint - https://github.com/markdownlint/markdownlint/blob/master/docs/RULES.md#md013—line-length
  • Write portable Markdown - http://brettterpstra.com/2015/08/24/write-better-markdown/
    • Use an empty line:
      • after headlines
      • between paragraphs
      • before/after code/verbatim blocks
    • Use spaces after list markers *, -, +, \1
    • Use a space after the header marker # or ## or ###
    • Don’t put blank lines in your lists. It is ambiguous as to whether that starts a new list.
    • You can use blank lines above paragraphs within lists. Just follow the last paragraph immediately with another list item (or the end of the list). e.g.
* list item 1

    paragraph in list item 1
* list item 2
* Empty lines in block quotes are handled differently between flavors as well. The most common way to make a multi-paragraph block quote is to use a greater than symbol on each blank line:
> paragraph one
>
> paragraph two
>> nested paragraph
>>
>> nested paragraph two
* Use ATX Headers (i.e. hashmarks).
* four-space indentation is recognized across the board; when creating nested lists, always use four spaces instead of two.
* For code blocks, use \`\`\` and not \~\~\~ because they are more universal
*

Moving Jekyll to Docker

At this point, the only Ruby thing I’m using on my Macbook is Jekyll. Instead of installing an up-to-date ruby, chruby, bundler, and ruby-build (which was how I’d previously run Jekyll). This is the story of how I migrated my Jekyll sites (kleinfelter.com and k4kpk.com) into Docker containers.

 

Notes:

  • My local copy of my primary web site lives in the directory ‘kleinfelter.github.io’.

  • I launch my Jekyll via a Launch Agent, which runs the shell script runme-local.sh in the site directory.

 

Steps:

  • Install Docker for Mac.

  • Since I’m auto-starting Jekyll via a Launch Agent, I need to stop the existing one:

    • launchctl unload /Users/kevin/Library/LaunchAgents/com.kleinfelter.jekyll.kleinfelter.plist
  • Since I’m going to use the jekyll/jekyll image, I can stop using bundler. I’m not going to uninstall bundler, since that’s part of my Macbook’s ruby installs, but since I’m going to be using the gems provided in the image, I don’t need to be coordinating my own gems.

    • cd kleinfelter.github.io

    • git rm Gemfile

    • git rm Gemfile.lock

    • git rm -r vendor

    • rm -r vendor

  • Create a docker-compose.yml in kleinfelter.github.io containing:

jekyll-kleinfelter:
    build: .
    command: jekyll serve --watch --incremental
    ports:
        - 4000:4000
    volumes:
        - /Users/kevin/Sync/Sites/kleinfelter.github.io:/srv/jekyll
  • Strictly speaking, docker-compose is about running multiple containers. However, you can use it to run a single container, and it makes the command line for that container simpler, by allowing you to put some of your options in the docker-compose file. This config says:

    • Service is named ‘jekyll-kleinfelter’

    • Build per the ‘Dockerfile’ in the current directory.

    • Launch the process to run in the container with: the given ‘command’ line.

    • Connect host port 4000 to container port 4000.

    • Mount the given host volume onto /srv/jekyll

  • I’m using the jekyll-admin plugin. I was using the gem for it, with bundle. Now that jekyll runs in a container, I can install the gem into the container’s site-ruby. Create the file ‘Dockerfile’ in kleinfelter.github.io:

FROM jekyll/jekyll:pages
RUN gem install jekyll-admin
  • That says:

    • Base your image on the official jekyll plugin, the version designed to work with github-pages.

    • When building your image, run the given ‘gem’ command to add the gem.

  • Test it with:

docker-compose build --no-cache
docker-compose up --force-recreate
  • Edit runme-local.sh to contain:
#!/bin/bash
cd /Users/kevin/Sync/Sites/kleinfelter.github.io
/usr/local/bin/docker-compose up
  • Once you’re done testing: launchctl load /Users/kevin/Library/LaunchAgents/com.kleinfelter.jekyll.kleinfelter.plist

  • Occasionally, when Jekyll is running, I need to force a site rebuild.

    • Discover the proper container via: docker ps

    • Connect to the existing container: docker exec -it container_name_here /bin/bash

    • Run: jekyll build

Jekyll Not Updating Front Page With Incremental

When I used ‘–incremental –watch’, it looked like Jekyll was not updating. It turns out that it was rebuilding the page itself, but not the content which was loaded to the landing page (a.k.a. the front page). The solution is to add this to index.html in the main site directory:

regenerate: true

Works much better now.

Jekyll Daemon on Mac OS X

eee I wanted to have jekyll always running on my Macbook, so that I could preview my posts before pushing them to my Github Pages site. Here’s how I set it up with a Launch Agent. (The challenging parts were learning how to use Launch Agents to run shell scripts and learning how to run Jekyll from a non-login shell.)

I’m using chruby to manage multiple versions of Ruby, and bundle to manage multiple gem levels, and I use Homebrew as a package manager. YMMV if you use other tools. I’ve previously confirmed that I can manually launch Jekyll for both of my sites.

 

I have two sites: k4kpk.com and kleinfelter.com, at k4kpk.github.io and kleinfelter.github.io respectively.

 

create ~/Library/LaunchAgents/com.kleinfelter.jekyll.k4kpk.plist:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.kleinfelter.jekyll.k4kpk</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/kevin/Sync/Sites/k4kpk.github.io/runme-local.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/k4kpk.jekyll.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/k4kpk.jekyll.err</string>
</dict>
</plist>

 

Similarly, create ~/Library/LaunchAgents/com.kleinfelter.jekyll.kleinfelter.plist, with ‘kleinfelter’ substituted for ‘k4kpk’.

 

/Users/kevin/Sync/Sites/k4kpk.github.io/runme-local.sh should contain:

#!/bin/bash
source /Users/kevin/.bash_profile
cd /Users/kevin/Sync/Sites/k4kpk.github.io
chruby 2.4.2
bundle exec jekyll serve --incremental

 

  • Test it with: launchctl start com.kleinfelter.jekyll.k4kpk.plist

  • Check output in /tmp/k4kpk.jekyll.err and /tmp/kleinfelter.jekyll.err

 

I had to add this to my Gemfile to prevent an “invalid byte sequence in US-ASCII” error:

Encoding.default_external = Encoding::UTF_8

 

I also added this to my _config.yml

encoding: utf-8

Plotting Two Kinds of Points on Google Maps

(This story is an enhanced edition of this story from my ham radio site.)

Suppose you have a set of names and addresses, and you’d like to display them on a Google Map. Further suppose that you have two kinds of items to display – perhaps you’re displaying members of your family and you’d like red markers for the girls and blue markers for the boys. (It is a contrived example – what can I say?)

The first thing you need is to create a text file with names and addresses.

  • Column 1 should be Name.
  • Column 2 should be Address. Enter street address, a comma, city name, a comma, state name.
  • Column 3 should be Marker_Type. Girls get “large_red”. Boys get “large_blue”.

Separate your columns with TAB character. I’ll refer to this as a CSV file, but tab works better as a delimiter because you’ll have commas in your data. You really want the Address column to contain street address, city, and state, separated by commas.

Here’s an example:

NAME    Address Marker_Type
Fred Smith      123 Maple St,Anytown,OH large_blue
Mary Smith      246 Oak St,Anytown,OH   large_red
Jane Smith      100 Park Place,New York,NY   large_red

Save the file on your computer. (You could also store it on the web, but my example assumes it is stored locally.)

To load this data into Google Maps, we’re going to use something Google calls Fusion Tables. Navigate to drive.google.com. (You’ll have to sign up for a Google account, if you don’t have one.)

  • Choose New, then More, then Google Fusion Tables.
  • Tell it you want to load a file ‘From this computer’.
  • Select the data file you created (per above instructions).
  • Import the data. Importing goes pretty fast.
  • Select ‘Map of Address’. The first time you do this, Google must geocode your addresses. This is slow - about 1 second per address.
    • As this progresses, keep an eye on “Quality: 0% ambiguous”. If that 0 changes, it means Google had to guess where an address was. For me, it guessed that Rome, GA was really Rome, Italy. Bad guess. I fixed that by putting street, city, and state into a SINGLE field, as mentioned above. Google looks at only a SINGLE field for address.
  • On the left side of the page, you’ll see a “Configure map” panel. Press the “Change feature styles” button.
  • In the “Map marker icons” area, select the Column tab, to tell Google which column contains red/blue information.
  • Select “Use icon specified in a column”, select your Marker_Type column, and Save your update.
  • When you’re done, press the Done button.
  • In the upper-right corner is a Share button. I like to set my sharing option to “On - anyone with the link”, but your needs may differ.
  • Copy the URL from the “Link to share” field, press Done and save your changes.

Distribute the copied URL to people who you’d like to share with.