Thursday, September 7, 2017

macOS How to create an ISO from a CD or DVD

Put in your CD or DVD, Open Terminal, type:

>ls /Volumes

Find the volume in the list, then type where /path/to/volume is the CD or DVD you want:

>hdiutil makehybrid -iso -joliet -o Image.iso /path/to/volume

Thursday, August 24, 2017

Java Packager and Custom Resources

The Java Packager allows for resources within the app bundle to be replaced by your own custom resources. For example, on macOS the default Info.plist may not work for you. Here is a JDK 9 example that demonstrates replacing the default Info.plist. It's worth noting there is difference between JDK 8 and JDK 9. JDK 8 uses the classpath to search for the resources and JDK 9 requires a new argument. The argument documented here. The documentation about this feature is here:

https://docs.oracle.com/javase/9/deploy/self-contained-application-packaging.htm#JSDPG593

However, note that resource handling is different in the modular world (as I mentioned above about the differences between JDK 8 and JDK 9), and the docs weren't updated (at the time of writing this post, and we didn't catch the bug until recently, sorry). It is no longer possible to load resources via the classpath with the Java Packager. The correct way to do this is with the following ant task so specify the custom resource directory:

<fx:bundleArgument arg="dropinResourcesRoot" value=directory/>

Or if you are using the CLI use the following argument:

-BdropinResourcesRoot=directory

If you add this bundler argument the example in the docs will function the same; The current directory will be where custom resources such as the Info.plist searched for.

Here is the example:


>ls -R

build.xml package src

./package:
macosx

./package/macosx:

Info.plist

./src:

HelloWorld.java

HelloWorld.java

import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class HelloWorld {

  private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("Hello World");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    frame.setBounds(0, 0, dim.width/2, dim.height/2);

    //Add the ubiquitous "Hello World" label.
    JLabel label = new JLabel("Hello World");
    JPanel panel = new JPanel();
    panel.setBorder(BorderFactory.createEmptyBorder(30, 10, 30, 30));
    panel.add(label);

    frame.getContentPane().add(panel);

    //Display the window.
    frame.setVisible(true);
  }

  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }

}

build.xml:

<project name="Test" default="package"  xmlns:fx="javacom.sun.javafx.tools.ant">

<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
         uri="javacom.sun.javafx.tools.ant"
         classpath="${java.home}/lib/ant-javafx.jar"/>

<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/hello.world"/>
<property name="bundles.dir" value="output"/>

<target name="clean">
  <delete dir="${build.dir}"/>
  <delete dir="${bundles.dir}"/>
</target>

<target name="compile">
  <mkdir dir="${build.dir}"/>
  <mkdir dir="${classes.dir}"/>
  <javac includeantruntime="false"
         srcdir="${src.dir}"
         destdir="${classes.dir}"/>
  <copy todir="${classes.dir}">
    <fileset dir="${src.dir}">
      <exclude name="**/*.java"/>
    </fileset>
  </copy>
</target>

<target name="jar" depends="compile">
  <mkdir dir="${build.dir}/jars"/>
  <jar destfile="${build.dir}/jars/hello.world.jar" basedir="${build.dir}/hello.world">
    <manifest>
       <attribute name="Main-Class" value="HelloWorld"/>
     </manifest>
  </jar>
</target>

<mkdir dir="${bundles.dir}"/>

<target name="package" depends="jar">
    <fx:deploy outdir="${bundles.dir}"
               outfile="Test"
               nativeBundles="image"
               verbose="true"
               versionCheck="false">

        <fx:application id="Test"
                        name="Test"
                        version="1.0"
                        mainClass="HelloWorld">
        </fx:application>

        <fx:runtime strip-native-commands="false"/>

        <resources>
            <fileset dir="${build.dir}/jars" includes="**/*"/>
        </resources>

        <fx:info title="Test"
                  description="Java Packager Demo"
                  category="Test"
                  copyright="(c) 2017"
                  license="3 Clause BSD">
        </fx:info>

        <fx:bundleArgument arg="mainJar" value="hello.world.jar"/>
        <fx:bundleArgument arg="classpath" value="hello.world.jar"/>
        <fx:bundleArgument arg="win.exe.systemWide" value="true"/>
        <fx:bundleArgument arg="win.menuGroup" value="Games"/>
        <fx:bundleArgument arg="mac.dmg.simple" value="true"/>
        <fx:bundleArgument arg="signBundle" value="false"/>
        <fx:bundleArgument arg="mac.CFBundleName" value="Test"/>
        <fx:bundleArgument arg="dropinResourcesRoot" value="."/>
    </fx:deploy>
</target>

</project>

Now, I'll be honest, I don't like this method of copying custom files into an app bundle, and we have some ideas to simplify the Java Packager and make custom resource handling a lot easier in the future and not so error prone.

Wednesday, August 23, 2017

JavaOne Promotion

If you want to go to JavaOne you can go for a grand ($999 to be exact). Use the code DJFS2017 at registration. But wait there's more. It expires August 28th.

Cura on macOS Problems

I've run into this issue a few times so I figured others have too.

Once in a while Cura's main window doesn't show up. Here's what I think fixes the problem. I say I think because I don't entirely know because I've tried so many things.

1. Reboot the computer
2. Rename the file:

/Users/cbensen/Library/Application Support/Cura


to something else.

3. Download a newer version of Cura here:

https://www.lulzbot.com/cura

If there is no later version, then try the latest developer version here:

http://devel.lulzbot.com/software/Cura/mac/

4. Copy to the desktop because you don't want to loose the older version.

5. Run.

Hopefully it works.

Monday, August 21, 2017

vlog02 - Pringles eclipse viewer

This morning I made an eclipse viewer. If you can't make one, just go out and look under a tree. Where there should be sun spots you will see eclipse spots, which are crescent shaped unless you happen to be where there's a total eclipse.

vlog 02

Sunday, August 20, 2017

vlog01 - So I'm starting a vlog

This has been a long time coming, and it is no coincidence that this is my 500th blog post, but after multiple family emergencies and about 6 months, it's finally here. Introducing my vlog:



I plan to explore this new format, share a lot more, especially using more than just words. I have a lot of ideas, so if I can get even half or my ideas done I'd be more than happy. I hope you all enjoy.

P.S. I might be copying existing vloggers styles that I like until I get a style of my own.

Tuesday, June 13, 2017

How to Find The Entitlements a macOS App

Sandboxed apps have their entitlements embedded into the signing data. To see what any app's entitlements are, type the following in Terminal:

codesign -d --entitlements - /Applications/Some.app/
This will print out a plist. For example:
<?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>com.apple.security.app-sandbox</key>
 <true/>
 <key>com.apple.security.network.client</key>
 <true/>
</dict>
</plist>

Thursday, April 27, 2017

Bash Scripts Auto Download Dependencies

Often times bash scripts I run depend on other tools. Tools that are sometimes updated. So once in a while I add the following curl command to download the latest tool.

  curl -O [filenameURL]

Tuesday, April 25, 2017

Building a Raspberry Pi Security Camer - Part 1

1. Download motionEyeOS (https://github.com/ccrisan/motioneyeos/releases). For example I have a Raspberry Pi 2 so I downloaded "motioneyeos-raspberrypi2-20161125.img.gz".

2. Next, figure out which volume your SD card is. Insert your SD or micro SD card. On macOS, run terminal and type:

>diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *480.1 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage                         479.2 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Main                   *478.9 GB   disk1
                                 Logical Volume on disk0s2
                                 B465E1FC-701D-4C31-A2B9-F728FB903B40
                                 Encrypted
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.9 GB    disk2

   1:             Windows_FAT_32 NO NAME                 15.9 GB    disk2s1

3. If the card has already been partitioned and mounted then continue with this step. Run diskutil unmountDisk /dev[disk#]. For example: diskutil unmountDisk /dev/disk3 will unmount the SD card volume. Alternatively you can run Disk Utility and unmount the SD card volume.

4. Run:

>sudo dd if=motioneyeos-raspberrypi2-20161125.img of=/dev/disk2 bs=1048576

then wait a little while as the image is written to the SD card.

5. Put the SD card in the pi with a video camera installed and viola!

Next I'll post about some options for housings for the pi.

Monday, April 24, 2017

macOS Window of Application has gone off screen

Once in a while a window of an application goes off screen and it can't be moved or resized. I've seen various approaches to get the window back but by far the easiest is to change the resolution. Once you change the resolution all windows are moved to be back within the screen and you'll get the window back.

Tuesday, April 11, 2017

Super Awesome Debugging Technique with Comments

Here is a trick I learned many many years ago and it remains one of the best tools in my debugging toolbox for all programming languages. This example just happens to be in C++.


#include <iostream>


int main(int argc, const char * argv[]) {
    std::cout << "Hello\n";
    
//*
    std::cout << "Hello, World!\n";
    
/*/
    std::cout << "A different Hello!\n";
//*/
    return 0;

}

now remove the first slash in the front of the first comment and you get:


#include <iostream>


int main(int argc, const char * argv[]) {
    std::cout << "Hello\n";
    
/*
    std::cout << "Hello, World!\n";
    
/*/
    std::cout << "A different Hello!\n";
//*/
    return 0;

}


This is such a handy debugging technique.

Thursday, April 6, 2017

Programmatically Creating a Window on macOS

Programmatically creating windows without using a NIB file can be tricky on the Mac. Especially if you're developing in C or C++ instead of Objective-C. Here's one of the issue most common that may come up.

Assuming you got the window creation code right, you may be thinking everything is going to work, but you get this error:

Oct 30 17:34:39  myapp[48617] : kCGErrorInvalidConnection: CGSGetCurrentCursorLocation: Invalid connection
Oct 30 17:34:39 myapp[48617] : kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged.



This means your NSApplication is not being initialized. In other words, the Objective-C side of your system needs to be properly initialized. Adding the following line may help:

[NSApplication sharedApplication];

Most likely you aren't trying to do this so it is never an issue, but for those few souls out there this might just save you some serious time.