Signing a JavaFX Maven project for MacOS’ Guardkeeper

When creating a JavaFX application for MacOS as an “.app” file it is important to sign it correctly. If it isn’t signed correctly, the message “YourApp can’t be opened because it is from an unidentified developer.” will appear when a user tries to start the downloaded “.app” file: To fix this one can use the … Continue reading “Signing a JavaFX Maven project for MacOS’ Guardkeeper”

When creating a JavaFX application for MacOS as an “.app” file it is important to sign it correctly. If it isn’t signed correctly, the message “YourApp can’t be opened because it is from an unidentified developer.” will appear when a user tries to start the downloaded “.app” file:

To fix this one can use the javafx-maven-plugin. When using it you just have to add some information about your configuration to your pom.xml file. You can find further information on the project’s website but here is an example:

<plugin>
    <groupId>com.zenjava</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>8.7.0</version>
    <configuration>
        <vendor>YourCompany</vendor>
        <updateExistingJar>true</updateExistingJar>
        <mainClass>YourMainClass</mainClass>
        <appName>YourAppName</appName>
        <verbose>true</verbose>
        <jvmArgs>
            <argument>-Djava.library.path=. -Xms168m -Xmx1024m -XX:+UseG1GC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=30</argument>
        </jvmArgs>
        <bundleArguments>
            <mac.signing-key-developer-id-app>ABC</mac.signing-key-developer-id-app>
            <mac.signing-key-app>ABC</mac.signing-key-app>
            <mac.signing-key-developer-id-installer>DEF</mac.signing-key-developer-id-installer>
            <mac.signing-key-pkg>GHI</mac.signing-key-pkg>
        </bundleArguments>
        <additionalAppResources>libs</additionalAppResources>
    </configuration>
    <executions>
        <execution>
            <id>create-jfxjar</id>
            <phase>package</phase>
            <goals>
                <goal>build-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The important part is in the bundleArguments section. There you can define some parameters for the javapackager, which creates the native application. Depending on if you would like to distribute your application directly or via the Mac AppStore you have to enter different keys here. You can either enter the key’s name or its SHA-1 number (without spaces). Both can be found in the “Keychain Access” program.

After you have finished creating your “.app” file you can check if Guardkeeper will accept it:

# spctl -a -vvvv YourApplication.app

YourApplication.app: accepted
source=Developer ID
origin=Developer ID Application: YourName (YourID)

If it says “accepted” then it should work.

Using Antlr to parse date ranges in Java and Kotlin

I wanted to parse date ranges that could occur as e.g. “01.01.” or “01.01.-05.01.” or “01.01.-05.01./09.01.” or similar combinations. To make it easier to correctly parse all possible combinations I have used Antlr to parse the dates. First I had to create rules in a file that I named “Dates.g4” that define what is a … Continue reading “Using Antlr to parse date ranges in Java and Kotlin”

I wanted to parse date ranges that could occur as e.g. “01.01.” or “01.01.-05.01.” or “01.01.-05.01./09.01.” or similar combinations. To make it easier to correctly parse all possible combinations I have used Antlr to parse the dates.

First I had to create rules in a file that I named “Dates.g4” that define what is a valid date range:

grammar Dates;
r: (element (divider? element)*);
element: (daterange | singledate);
daterange: date minus date;
singledate: date;
minus: '-' | '–';
divider: '/';
date: day '.' month ('.')?;
day: INT;
month: INT;
INT: [0-9]+;
WS: [ \t\r\n]+ -> skip ;

Let’s see what this does. The “grammar” line just defines a name. The next line defines a token “r” that can consist of an “element” and an arbitrary number of “divider” objects (or no divider) and another element. The next line defines what such an “element” is. It is either a “daterange” or a “singledate”. And so on, all tokens are defined this way. A question mark makes the element optional, i.e. it does not need to be in the parsed text.

The rules in uppercase letters are lexer rules, i.e. they don’t use self defined tokens to define the structure of the parsed text but they define characters that should be allowed.

I have used the Intellij IDEA IDE with the Antlr plugin. So to generate the necessary Java classes from the *.g4 file above I just had to right click the *.g4 file and choose “Generate ANTLR Recognizer”:

This creates several classes in the directory and package that you can change by clicking on “Configure ANTLR” in the menu above.

The generated classes are easy to use, e.g. in Kotlin:

val lexer = DatesLexer(CharStreams.fromString(text))
val parser = DatesParser(CommonTokenStream(lexer))

val parsed = parser.r()
for (element in parsed.element()) {

Inside the loop you can now access the dates e.g. with

element.daterange()

and

element.singledate()

because as defined in the *.g4 file above an element contains either a “daterange” or a “singledate”. As you can see the generated functions use the names that were specified in the *.g4 file.

Parsing PDF files with Java or Kotlin

Often information is not available in a computer readable format like JSON, XML or CSV. When only a human readable PDF file is available, one can try to use a PDF parser to retrieve the needed information. There is e.g. Apache Tika that can read PDF files and return the contents as tokens. It can … Continue reading “Parsing PDF files with Java or Kotlin”

Often information is not available in a computer readable format like JSON, XML or CSV. When only a human readable PDF file is available, one can try to use a PDF parser to retrieve the needed information. There is e.g. Apache Tika that can read PDF files and return the contents as tokens. It can be quite useful but it doesn’t return tabular information so if you have a table with empty cells you don’t see which cells are empty and it can be difficult to know to which cell the returned data belongs to.

For this purpose another library called Tabula exists. It provides an easy to use local web page that allows to the tables of a PDF file and export them as CSV or JSON files:

Tabula screenshot running on localhost

You can also embed tabula-java into an own program to use it e.g. in batch jobs. E.g. this Kotlin snippet loads a PDF file pdfFile and writes its contents as JSON into tmpfile:

val tmpfile = File.createTempFile("pdfparser", "json")
val args = arrayOf(pdfFile.absolutePath, "-g", "-l", "-f", "JSON", "-o", tmpfile.absolutePath)

val parser = DefaultParser()
val cmd = parser.parse(CommandLineApp.buildOptions(), args)

val stringBuilder = StringBuilder()
CommandLineApp(stringBuilder, cmd).extractTables(cmd)

From there you can parse the JSON to process it further.