Glimmer

Faint insights into (mostly) the worlds of automation and productivity

Update to Using Maven to Build Executable Jar Files

| Comments

This is an update to an earlier post.

At the time of writing, Apache NetBeans is at version 12.4 and there are several suppliers of JDKs. The latest LTS (Long Term Support) version is JDK 11 and the latest MTS (Medium Term Support) is JDK15.

Apache Maven remains the preferred build automation from for new projects.

One area that is remains unpolished (IMO) is the building of a jar file that can be run from the command line. The menu process “Run ▶ Clean and Build Main Project” will build a jar file but it won’t configure the manifest so that

1
java -jar jarfile.jar

works even when the JDK (or JRE) is on the command line.

The solution discussed in the earlier post involving the modification of POM (Project Object Model) file is still viable. It is under the Project Files folder in the Project View in NetBeans. Load the pom.xml file into the NetBeans editor.

Quoting from the source article:

You need to add the following XML snippet to your pom.xml, it can go anywhere inside the <project> element, I usually put it after the <properties> element:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>MAIN CLASS GOES HERE</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Just replace MAIN CLASS GOES HERE with your main class (with it’s package prefix), rebuild and your JAR is now runnable. If you are unsure what to put here, just copy the Main Class settings from the Run tab in your Netbeans Project Properties.

The version number above has been updated to 3.2.0 matching the latest version of the maven-jar-plugin.

After you do this, you can use “Run ▶ Clean and Build Main Project” in NetBeans to build the jar file. By changing to the Files view (instead of the Project View), you can see the target directory.

The name of the jar file will be dependent on your configuration, your project setup but in my habits project, it was habits-1.0-SNAPSHOT.jar which one can run from the terminal with

1
java -jar habits-1.0-SNAPSHOT.jar

assuming that Java has been set up to run at the command line (or you are using the terminal inside NetBeans.)

Note that the target directory is erased as part of the clean process of “Run ▶ Clean and Build Main Project” so you will need to close anything that has files in that space open before re-running the clean process.

Maven Shade plugin

In a baeldung article, other solutions for making executable jar files are discussed. The Maven Shade Plugin allows one to include dependent jar files inside the executable jar although you still need the JDK/JRE installed on the execution machine.

To use this approach, you edit the pom.xml as above but include the following instead

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <shadedArtifactAttached>true</shadedArtifactAttached>
                <transformers>
                    <transformer implementation=
                      "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>MAIN CLASS GOES HERE</mainClass>
                </transformer>
            </transformers>
        </configuration>
        </execution>
    </executions>
</plugin>

and insert the full name with package (but not .class) of the class contains the main method inside the container.

Big Sur’s Finder Copy Change Broke My Keyboard Maestro Macro

| Comments

In Catalina, Copy in Finder gets the path of a file.  In Big Sur, it only gets the filename.  One can hold down ⌥+⌘+C (or ⌥ and select Copy from the Finder menu) to copy the pathname but Keyboard Maestro does not “Copy as pathname” as an action or option of its Copy action.

I had built  ⌃+⌥+⌘+U to put a URL style address of a file or folder currently select in  Finder to the clipboard.  I used to paste in file references that I could later reference as noted in a prior note but the upgrade to Big Sur broke this.

Dark Sky - Weather App

| Comments

Like many, I have started looking at the additional detail on data privacy on my iOS apps. I was shocked to see that my Weather App was tracking my Health & Fitness in ddition to more reasonable information such as location. And, it was sharing this information with other companies websites according to their self-reporting. I decided to look for alternatives.

I found Dark Sky — an unusual name for a weather app but it reported only linking identifiers and location to me and not sharing that with other companies. It had recently become an Apple app as well.

It, of course, was different from the App I had been using and the preinstalled Apple Weather App. I have grown to like it over the last week as I figured how to find the things I wanted to see.

"Dark Sky's Main Screen"

Dark Sky’s Main Screen

The Dark Sky main screen has present temperature including “Feels Like” and an icon, any warnings, a small map, rain (or snow), and cloud forecast for the next several hours as a graph down the page. At the top is the location which can be selected (as it is this example) or driven by the present location. Hitting the magnifying glass lets one choose other locations. Saved locations can be accessed by swiping right or left on the main screen.

"Dark Sky's Upcoming Forecast"

Dark Sky’s Upcoming Forecast

Scrolling down this screen gets you to the forecast for the next 7 days which includes the same information in a compact form. Any of the days may be tapped to expand them to look like the present day detail. Note towards the bottom is a “TIME MACHINE” link which will allow one to see forward or back in time.

"Dark Sky's Radar View"

Dark Sky’s Radar View

One can tap on the map of the main screen or on the Map at the bottom of screen to see the precipation or temperature map for the current area. At the bottom is a player control that one see the history of the last three and a half hours and the prediction for the next half hour play out on the screen.

"Dark Sky's Radar View (zoomed out)"

Dark Sky’s Radar View (zoomed out)

Using the pinch (or unpinch if that is the opposite), one can adjust the zoom level of the map. As you can see, it is possible to get a world view of the weather. One can also drag to move what area the map is showing which turns into spinning the globe when one is at zoomed out far enough to get the world view.

All in all, it was successful migration in terms of features as well as privacy.

Open Selection by Highlighted URL

| Comments

In Evernote 10, I have lost the ability to include general URLs as linked items. The links already in a note still work but Evernote 10 does not allow the insertion of new links. While not perfect, Keyboard Maestro on macOS can mitigate some of the missing behavior for Mac users.

I chose to add a shortcut ⌃⌥⌘O (O for open) to open the highlighted text treating it as a URL. It easily accomplished with Keyboard Maestro.

Keyboard Maestro Command

This has made things much more bearable. I still hope Evernote will reconsider their decision on URLs since I think both macOS and Windows (at least) support this type of behavior and having the URL visible in the note distracts from the readability of the note.

Using Localstorage Between Browser Windows

| Comments

Overview

There are several ways to communicate between browser windows

  • Server conversation (async, network delays)
  • localstorage (sync)
  • BroadcastChannel (most modern, does not appear to be supported in Safari)
  • IndexedDB (async)

It looks like localstorage will do for the current application’s purposes of launching another window to do some work and then report back a limited amount of information and closing.

Structure

The remote client window uses localstorage.setItem(key,value) to talk back to main window. Both key and value must be strings. JSON.stringify(object) may help.

Main window uses window.addEventListener("storage", storageEventHandler, false) to register the function storageEventHandler(evt) to be notified when the storage is modified. The main window can then examine evt.key to get the key of the item in local storage that changed and evt.newValue to get the new value of the changed item. Alternately, if only one key is in involved, the main window can use localStorage.getItem(key).

Demo Code

The demo must run in a server context not file:// and the browser windows should not be in “private” mode.

Simulation of main window (launch this, then hit “read” link to launch client)

1
2
3
4
5
6
7
<body>
  <h1>Web localStorage (read)</h1>
  <p><a href="client.html" target="_blank">Load Client</a></p>
  <h1><span id='theString'></span></h1>
</body>

<script src="scriptRead.js"></script>

Body of HTML page

1
2
3
4
5
6
7
8
9
10
11
"use strict";

window.addEventListener("storage", storageEventHandler, false);
const answerFieldSpan = document.getElementById("theString");

function storageEventHandler(evt) {
  // let theString = localStorage.getItem("theString");
  // answerFieldSpan.innerText = theString;

  answerFieldSpan.innerText = `${evt.key} : ${evt.newValue}`;
}

JavaScript

Simulation of client window (launched by main window or manually)

1
2
3
4
5
6
7
8
9
<body>
  <h1>Graphic Page Writing Back via Local Storage</h1>
  <form action=""></form>
  <label for="the-string">String to store:</label>
  <input type="text" name="saveValue" id="the-string">
  <button id='save'>Save</button>
</body>

<script src="scriptSet.js"></script>

Body of HTML page

1
2
3
4
5
6
7
8
9
10
11
12
13
"use strict";

let theString = "stop";
let check;

const saveButton = document.getElementById("save");
const theStringField = document.getElementById("the-string");

saveButton.onclick = (ev) => {
  theString = theStringField.value;
  localStorage.setItem("theString", theString);
  check = localStorage.getItem("theString");
};

JavaScript

References

Making BookMarked PDFs From Google Docs

| Comments

Updated: 10 June 2020 removed LibreOffice as tool, comments about Word Online

This post focuses on ensuring that the Table of Contents, as set up using Google Docs index, are transferred into the bookmark metadata of the PDF file. This can not be done by simplifying downloading a Google Doc as a PDF. One must export to a .docx file and use Word, Writer, or Pages to produce the PDF file using the correct options for each program.

Using macOS Preview as the PDF reader, we want the left sidebar when one selects Table of Contents to show the Table of Contents as bookmarks that allow quick access to the page where the content is.

Choose Table of Contents in sidebar

Limping Along With Octopress and Catalina macOS

| Comments

I am still using the Octopress 2 framework for the website. This has been challenging as the dependencies for old obsolete software gets harder and harder to satisfy. However, it appears that I have succeed again for at least the Catalina release of macOS.

I found out I had a problem when I went to fix Disqus which had moved to https:// protocol. I found the files named disqus.html which had http:// and changed it to https:// but I was unable to regenerate the code due to a failure of the Octopress tool to run.

I use

1
chruby ruby-2.2.10

due to the yajl-ruby which won’t build under later rubies.

My already built ruby-2.2.10 would not run because the openssl 1.0 version that had been linked in had disappeared (either due to Catalina or my migration to a new MacBook Pro.) Rebuilding ruby with

1
ruby-install ruby-2.2.10

did not work nor did

1
ruby-install ruby-2.2.10 -- --with-openssl-dir=/usr/local/opt/openssl

did not work since the openssl was version 1.1.

After a fair bit of false steps, the successful approach was built around Chris Hobb’s December 3, 2019 solution (for RVM) posted on Stack Overflow.

First follow his steps (repeated here) to install openssl 1.0.2 by downloading openssl 1.0.2 from https://www.openssl.org/source/, and then building and installing it with

1
2
3
4
5
6
tar -xzf openssl-1.0.2t.tar.gz
cd openssl-1.0.2t
./Configure darwin64-x86_64-cc --prefix=/usr/local/opt/openssl@1.0
make
make test
sudo make install

and then adapting to chruby / ruby-install approach, build ruby 2.2.10

1
ruby-install ruby-2.2.10 -- --with-openssl-dir=/usr/local/opt/openssl@1.0

Then going to the directory where I have the blog system and having previously deleted Gemfile.lock, I re-ran the install of gems into the vendor directory.

1
bundle install

Of course, in making this post, I issue

1
bundle exec rake new_post["Limping along with Octopress and Catalina macOS"]

Catalina has moved to using zsh instead of bash for its default shell. Having taken the plunge, I found out that square brackets are used differently in zsh. I was able to escape them to continue working:

1
bundle exec rake new_post\["Limping along with Octopress and Catalina macOS"\]

Thanks to Qihuan Piao for this hint.

One less groan

Evidently the version of pigments used does not know about zsh so the code blocks have to be marked as bash instead of zsh.

Time to think about a supported framework. Perhaps a migration to the modern version of Jekyll or a broader research into other static site tools that allow markdown content.

Configuring CoolBeans 2019.6

| Comments

Now CoolBeans has been renamed OpenBeans

At JDK 8, JavaFX and the JDK were together, thus already configured to build applications with both. Since that time, they were split apart (by Oracle). Different groups took over the open-source versions of each (JDK, JavaFX, and the IDE). Each of these components needed work, which was done on different schedules, so at this point, one has to do a bit of work to set up CoolBeans (or NetBeans) for JavaFx work. Additionally, it has become apparent that developers need to ship the JVM with their products to reduce the pain to their users.

This Gist discusses the approach as well as provides the files used.

The approach features

  • use of modular Java
  • latest JavaFX
  • integration with CoolBeans (Run, Debug, Generate JavaDoc, Test with TestNG)
  • an image that contains everything (for the platform it was built on) to run the program

Testing is configured but not demoed.

Onward to Maven in Apache NetBeans

| Comments

An update to this article is available

At the time of writing, Apache NetBeans is at version 11.1 and about 90% moved from Oracle to Apache. As a project of the Apache Foundation, all source code must be licensed under the Apache Foundation License. Of course, not all open source is licensed that way (and it was not the open source license used by Oracle) so there are some challenges to putting together large systems. The CoolBeans project packages NetBeans, the JDK, OpenJavaFx and other components to create an integrated product that is easier to get up and running with. I will use NetBeans as the tool in the remainder of the post.

Another change made was changing the underlying preferred build automation from Apache Ant to Apache Maven for new projects. This changes the file structure of the code as well as some details underneath. NetBeans mostly allows the user to ignore this once the project is made.

One area that is not yet polished (IMO) is the building of a jar file that can be run from the command line. The menu process “Run ▶ Clean and Build Main Project” will build a jar file but it won’t configure the manifest so that

1
java -jar jarfile.jar

works.

The solution was posted by Steve Claridge is to modify the POM (Project Object Model) file. It is under the Project Files folder in the Project View in NetBeans. Load the pom.xml file into the NetBeans editor.

Quoting from the article:

You need to add the following XML snippet to your pom.xml, it can go anywhere inside the element, I usually put it after the element:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>MAIN CLASS GOES HERE</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

Just replace MAIN CLASS GOES HERE with your main class (with it’s package prefix), rebuild and your JAR is now runnable. If you are unsure what to put here, just copy the Main Class settings from the Run tab in your Netbeans Project Properties.

After you do this, you can use “Run ▶ Clean and Build Main Project” in NetBeans to build the jar file. By changing to the Files view (instead of the Project View), you can see the target directory.

The name of the jar file will be dependent on your configuration, your project setup but in my habits project, it was habits-1.0-SNAPSHOT.jar which one can run from the terminal with

1
java -jar habits-1.0-SNAPSHOT.jar

assuming that Java has been set up to run at the command line (or you are using the terminal inside NetBeans.)

Note that the target directory is erased as part of the clean process of “Run ▶ Clean and Build Main Project” so you will need to close anything that has files in that space open before re-running the clean process.

Finding Java and NetBeans

| Comments

Working with NetBeans 9 with an OpenJDK 10 install on a MacOS Mojave machine.

I teach a course EE333 where we use Java as the basis for our efforts in learning object-oriented design and programming. We had to migrate to NetBeans 9 as NetBeans 8.2 became unworkable in some environments and unsupported. We also went to Java 10. First with Oracle although on November 16, 2018 they started wanting to uninstall it and have users move to Java 11 which I gather is going to have long-term support.

Both the Oracle code and the OpenJDK code for MacOS have a new (to me at least) structure where it has a more Mac-like file structure with a “Contents” folder in between the JDK-name and the “Home” directory. There is also a MacOS folder and an info.plist.

/Library/Java Directory with JDK 10 on MacOS

This means that the JAVA_HOME should be set a bit differently (to /Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home) in the ~/.bash_profile configuration file.

There were several errors in the Ant-based building in NetBeans 9 which essentially were stating that it was not possible to find the java executable and that the RT (runtime) version would be used instead.

In the build.xml file (on lines 120, 121, 127, 362, and 378 on the file I had), there was a path error that may either be just an error or more likely something that is not built correctly for the later JDK versions. This removed a bunch of error messages.

An example (120, 121) of this in diff form (leading spaces removed) is

1
2
3
4
-  <available file="${java.home}${file.separator}${file.separator}bin${file.separator}java"/>
-  <available file="${java.home}${file.separator}${file.separator}bin${file.separator}java.exe"/>
+  <available file="${java.home}${file.separator}..${file.separator}bin${file.separator}java"/>
+  <available file="${java.home}${file.separator}..${file.separator}bin${file.separator}java.exe"/>

But then, it looks like on restart, NetBeans did not like it and in nbproject/UPDATED.TXT it says

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
============================================
Project ScheduleBuilder build script updated
============================================

Project build script file jfx-impl.xml in nbproject sub-directory has not been recognized
as compliant with this version of NetBeans JavaFX support module. To ensure correct
and complete functionality within this NetBeans installation the script file has been
backed up to jfx-impl_backup.xml and then updated to the currently supported state.

FX Project build script auto-update may be triggered on project open either after
NetBeans installation update or by manual changes in jfx-impl.xml. Please note that
changing jfx-impl.xml manually is not recommended. Any build customization code should
be placed only in build.xml in project root directory.

Remark: The auto-update mechanism can be disabled by setting property
javafx.disable.autoupdate=true
Automatic opening of this notification when project files are updated can be disabled by setting property
javafx.disable.autoupdate.notification=true
(in build.properties, private.properties or project.properties).

Remark: Files nbproject/jfx-impl_backup*.xml and this file nbproject/UPDATED.TXT
are not used when building the project and can be freely deleted.

which essentially undid the changes. Good news is that the error messages are not (yet) back. I removed the two files noted as removable.

I will try to remember to check the NetBeans 10vc3 to see if the issue still exists.

In the JDK11, JavaFX will be removed from the JDK and become a standalone package to maintain and install. Both NetBeans and Java are on multi-times a year release cycle making it challenging to keep up with things for a class baseline. Hopefully, a stability point is soon. I know many folks are working towards this goal.