Thursday, 27 December 2018

Adding MariaDB JDBC Connector to Paraya 5

It's as easy as pie.

  1. start Payara
    $ cd ~/payara5/bin
    $ ./asadmin start-domain
    Waiting for domain1 to start ...............
    Successfully started the domain : domain1
    domain Location: /home/mrbear/payara5/glassfish/domains/domain1
    Log File: /home/mrbear/payara5/glassfish/domains/domain1/logs/server.log
    Admin Port: 4848
    Command start-domain executed successfully.
  2. install the database driver
    $ ./asadmin add-library /home/mrbear/software/mariadb-java-client-2.3.0.jar
    Command add-library executed successfully.
    or try:
    $ cp ~/Downloads/mariadb-java-client-2.3.0.jar ~/payara5/glassfish/domains/domain1/lib

    The last part will probably require a payara application server reboot, though.

  3. connect to http://localhost:4848
  4. surf to Resources -> JDBC -> JDBC Connection Pools
  5. Create a new one
  6. Settings:
    Pool name[obvious]
    Resource Typejavax.sql.DataSource
    Datasource classnameorg.mariadb.jdbc.MariaDbDataSource

    Leave the rest as default.

  7. Define the following additional properties:
    NameValue
    serverNamelocalhost
    URLjdbc:mariadb://localhost:3306/mmud
    databaseNamemmud
    userusername
    passworditsasecret
  8. Try the "Ping" button to verify that the connection is established.
  9. surf to Resources -> JDBC -> JDBC Resources
  10. Create a new one
  11. Settings:
    NameValue
    JNDI Namethis is the name as the resource is defined in your application
    Pool Namethe pool defined previously, it's a dropdown which is convenient.
  12. Press finish or OK or something
  13. Done!

References

Using MySQL with Payara Server
https://blog.payara.fish/using-mysql-with-payara
Payara - Using Hibernate 5 on Payara Server
https://blog.payara.fish/using-hibernate-5-on-payara-server

Thursday, 20 December 2018

Harddisks

I'm getting more and more harddisks in my computer nowadays. Some are really old, some I've managed to appropriate from family members, and of course when I upgraded to SSD, one more harddisk was added.

It's hard to keep them all straight, so I'm writing this stuff down.

For historical purposes, I guess.

It will be split up into "The New" and "The Old".

"The Old" being the original partition information at the time of acquirement.

The New

ATA Samsung SSD 860500 GBsda
The Operating System and everything essential.
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1026047 1024000 500M 7 HPFS/NTFS/exFAT
/dev/sda2 1026048 771002103 769976056 367.2G 7 HPFS/NTFS/exFAT
/dev/sda3 771002368 771969023 966656 472M 27 Hidden NTFS WinRE
/dev/sda4 771971072 976773119 204802048 97.7G 83 Linux

ATA WDC WD4003FZEX-04 TBsdb
Very important data regarding the /home directories.
DeviceStartEndSectorsSizeType
/dev/sdb12048409520481MBIOS boot
/dev/sdb2409610280951024000500MLinux filesystem
/dev/sdb31028096527343750052724094052.5TLinux filesystem
/dev/sdb45273438208742092185521474836481TLinux filesystem

ATA WDC WD5000AAKS-0500 GBsdc
Still empty for now.
DeviceBootStartEndSectorsSizeIdType
/dev/sdc12048976773167976771120465.8G83Linux

ATA ST2000DM001-1CH12 TBsdd
An old harddrive of my mother-in-law, part of a raid now.
DeviceBootStartEndSectorsSizeIdType
/dev/sdd1 2048 3907024895 3907022848 1.8T fd Linux raid autodetect

The Old

ATA Samsung SSD 860500 GBsda
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1026047 1024000 500M 7 HPFS/NTFS/exFAT
/dev/sda2 1026048 771002103 769976056 367.2G 7 HPFS/NTFS/exFAT
/dev/sda3 771002368 771969023 966656 472M 27 Hidden NTFS WinRE
/dev/sda4 771971072 976773119 204802048 97.7G 83 Linux

ATA WDC WD4003FZEX-04 TBsdb
DeviceStartEndSectorsSizeType
/dev/sdb12048409520481MBIOS boot
/dev/sdb2409610280951024000500MLinux filesystem
/dev/sdb31028096527343750052724094052.5TLinux filesystem
/dev/sdb45273438208742092185521474836481TLinux filesystem
/dev/sdb574209218567630637055209715200100GLinux filesystem
/dev/sdb67630637056763804467174076163.5GLinux swap

ATA WDC WD5000AAKS-0500 GBsdc
DeviceBootStartEndSectorsSizeIdType
/dev/sdc1*204820290317820290113196.8G7HPFS/NTFS/exFAT
/dev/sdc2202903552203876351972800475M27Hidden NTFS WinRE
/dev/sdc3203878400204799999921600450M27Hidden NTFS WinRE
/dev/sdc4204802048414517247209715200100G83Linux

ATA ST2000DM001-1CH12 TBsdd
DeviceBootStartEndSectorsSizeIdType
/dev/sdd1*204810240204710240000048.8G7HPFS/NTFS/exFAT
/dev/sdd21024020482000568319765478446.6G83Linux
/dev/sdd320005683220535418871853485056883.8Gfd Linux raid autodetect
/dev/sdd4205354188839070269431853485056883.8Gfd Linux raid autodetect

References

Binary Tides - 9 commands to check hard disk partitions and disk space on Linux
https://www.binarytides.com/linux-command-check-disk-partitions/

Thursday, 13 December 2018

Making your labtop battery last longer in Linux

So I went to Devoxx in Belgium, and I took my labtop along. Of course, it's in a Cinema, so there's no electrical sockets in the rooms.

I was looking to prolong the use of my labtop, so I was looking for extend the battery life.

There were several good articles about it (see below in the references.)

I choose to install the Xfce Desktop Environment, and I was pleasantly surprised my labtop managed to hold together for a lot longer.

Fedora has some notes on how to install it, it's basically running the package manager properly, and it's done.

It can be selected from the dropdown menu on the login screen.

I shall put the command line down here, so I do not forget:

sudo dnf install tlp tlp-rdw
sudo systemctl enable tlp

References

FOSS Post - 7 Tips to Reduce Battery Usage on Linux
https://fosspost.org/tutorials/7-tips-to-reduce-battery-usage-on-linux
Xfce Desktop Environment
https://www.xfce.org/
LXDE Desktop Environment for All
https://lxde.org/
Openbox - minimalistic window manager
http://openbox.org/wiki/Main_Page
Xfce In Fedora
https://fedoraproject.org/wiki/Xfce

Thursday, 6 December 2018

Adding MariaDB JDBC Connector to Wildfly 14

  1. install the database driver as a module
    1. create directory WILDFLY_HOME/modules/com/mariadb/main
      $ mkdir -p modules/com/mariadb/main
    2. copy database driver into that one
      $ cp ~/Downloads/mariadb-java-client-2.3.0.jar .
    3. Create the file module.xml in the same folder with the following content:
      <module xmlns="urn:jboss:module:1.3" name="com.mariadb">
          <resources>
              <resource-root path="mariadb-java-client-2.3.0.jar"/>
          </resources>
          <dependencies>
              <module name="javax.api"/>
              <module name="javax.transaction.api"/>
          </dependencies>
      </module>
  2. start Wildfly
    $ cd $WILDFLY_HOME/bin
    $ ./standalone.sh
  3. connect to http://localhost:9990/error/index.html
  4. run ./add-user.sh
    [mrbear@localhost bin]$ ./add-user.sh 

    What type of user do you wish to add? 
     a) Management User (mgmt-users.properties) 
     b) Application User (application-users.properties)
    (a): a

    Enter the details of the new user to add.
    Using realm 'ManagementRealm' as discovered from the existing property files.
    Username : mrbear
    Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.
     - The password should be different from the username
     - The password should not be one of the following restricted values {root, admin, administrator}
     - The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
    Password : 
    Re-enter Password :  
    What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]: 
    About to add user 'mrbear' for realm 'ManagementRealm'
    Is this correct yes/no? yes
    Added user 'mrbear' to file '/home/mrbear/wildfly-14.0.1.Final/standalone/configuration/mgmt-users.properties'
    Added user 'mrbear' to file '/home/mrbear/wildfly-14.0.1.Final/domain/configuration/mgmt-users.properties'
    Added user 'mrbear' with groups  to file '/home/mrbear/wildfly-14.0.1.Final/standalone/configuration/mgmt-groups.properties'
    Added user 'mrbear' with groups  to file '/home/mrbear/wildfly-14.0.1.Final/domain/configuration/mgmt-groups.properties'
    Is this new user going to be used for one AS process to connect to another AS process? 
    e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
    yes/no? no
  5. click on "Try again" on the Website
  6. log on with the new added user
  7. Configuration - Subsystems - Datasources and drivers - JDBC drivers - [+]
  8. Fill out the following information:
    Driver namemariadb
    Driver Module Namecom.mariadb
    Module Slot
    Driver Class Nameorg.mariadb.jdbc.Driver
    Drive Datasource Class Name
    Driver XA Datasource Class Name
  9. Configuration - Subsystems - Datasources and drivers - Datasources - [+]
  10. Select "Add Datasource" to add a non-XA Datasource
  11. Select "Custom" template
  12. Attributes:
    Name[name]
    JNDI Namejava:/jdbc/[name]
  13. JDBC Driver
    Driver Namemariadb
    Driver Module Name[empty]
    Driver Class Name[empty]
  14. Connection:
    Connection URLjdbc:mariadb://localhost:3306/[databasename]
    User nameroot
    Passworditsasecret
    Security Domain[empty]
  15. Test connection
  16. Reload of server required - so reload the server
  17. Test connection: Successfully tested connection for datasource [name].

References

JDBC Driver / DataSource Setup
https://hal.gitbooks.io/dev/content/recipes/jdbc-driver-setup.html
About MariaDB Connector/J
https://mariadb.com/kb/en/library/about-mariadb-connector-j/
GitHub - Use MariaDB Connector/J Driver
https://github.com/MariaDB/mariadb-connector-j/blob/master/documentation/use-mariadb-connector-j-driver.creole
IronJacamar 1.1 - Userguide - Deploying DS Descriptor
http://www.ironjacamar.org/doc/userguide/1.1/en-US/html_single/index.html#deployingds_descriptor

Thursday, 29 November 2018

Java Alternatives in Fedora Core

Installing Java 11

[root@localhost ~]# dnf install java-11-openjdk
[root@localhost ~]# dnf install java-11-openjdk-devel
Last metadata expiration check: 3:26:53 ago on Mon 12 Nov 2018 09:47:59 AM CET.
Dependencies resolved.
================================================================================
 Package                   Arch       Version                 Repository   Size
================================================================================
Installing:
 java-11-openjdk-devel     x86_64     1:11.0.1.13-1.fc28      updates     3.4 M

Transaction Summary
================================================================================
Install  1 Package

Total download size: 3.4 M
Installed size: 5.1 M
Is this ok [y/N]: y
Downloading Packages:
java-11-openjdk-devel-11.0.1.13-1.fc28.x86_64.rpm                                                                                                                                                75 kB/s | 3.4 MB     00:45
----------------------------------------------------------------------------------
Total                                                     72 kB/s | 3.4 MB     00:47
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing                                       1/1
  Installing       : java-11-openjdk-devel-1:11.0.1.13-1.fc28.x86_64                                        1/1 
  Running scriptlet: java-11-openjdk-devel-1:11.0.1.13-1.fc28.x86_64                                        1/1 
                                               1/1 
  Verifying        : java-11-openjdk-devel-1:11.0.1.13-1.fc28.x86_64                                                         1/1 

Installed:
  java-11-openjdk-devel.x86_64 1:11.0.1.13-1.fc28                                                               

Complete!

Switching to another Java version

[mrbear@localhost ~]$ sudo alternatives --config java
[mrbear@localhost ~]$ sudo alternatives --config javac
There are 2 programs which provide 'javac'.

  Selection    Command
-----------------------------------------------
*  1           java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181.b15-6.fc28.x86_64/bin/javac)
 + 2           java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.1.13-1.fc28.x86_64/bin/javac)

Enter to keep the current selection[+], or type selection number:

Of course my IntelliJ automatically detects the different Java versions installed on the system, when I tell it to add a new version of Java.

Nice.

References

Using alternative utils with JRE & JDK
https://robbinespu.github.io/eng/2018/03/21/Updating_java_with_alternative.html
Superhero Ninja - Easily switch between java versions using alternatives in Linux
https://superhero.ninja/2015/02/07/easily-switch-between-java-versions-using-alternatives-in-linux/

Saturday, 24 November 2018

Devoxx 2018 - Other talks

I'll see what I can write down and remember about the sessions I attended. Do not expect these notes to be exhaustive, they're just there for me to keep a record.

It's a follow up of the post1 Devoxx 2018 - Deep Dive Day One.

Tuesday - Deep Dive Day 2

Lambdas and Streams Masterclass Part 2
Very insightful session, especially the last part (which was quick because they were running out of time). I managed to type along on my labtop, as they gave us a few moments to try the exercises. There's a github of the Lab somewhere.
TypeScript: Complete
The session was, sadly, a bit geared towards Javascript developers, of which I am not one. An interesting toolkit I heard about was JHipster, which seems to be used for setting up a project initially, and takes care of all the dependencies, and my gods are there a lot of those.
PostgreSQL is the new NoSQL

An interesting idea was the use of UUIDs instead of a Sequence for the ID. It means it becomes much easier to merge two databases together, and no leaking of meaningful IDs to the outside in your application.

Use a Foreign Data Wrapper in PostgreSQL to attach to different data sources (other database servers, or even webservices, anything that provides data in fact.)

Micro Frontend: the microservice puzzle extended to the frontend
Very hard to follow for me, as I was a bit tired by then.

Wednesday

Java in 2018L: Change is the only Constant
Spearheading the future of programming
To JAR Hell and Back - A Live Migration To Java 11
PAAF: The passive agressive annotation framework
That was very funny! It contained annotations for indicating to other developers during writing code or code review what is wrong with the code. The framework is available at https://github.com/nvdh/paaf. Awesome annotations as @BlackBox, @Codesmell, @Backlog, @Altruistic, etc.

Project versioning like a git
Java, Today and Tomorrow
Patterns for building resilient software systems
Project Loom: Fibers and Continuations for Java
Very interesting. Fibers are part of a thread, and can help to make the thread non-blocking by having fibers yield control back to the thread. The work on it is still very much ongoing.
Java EE, Jakarta EE, MicroProfile, Or Maybe All Of Them?
Apparently the MicroProfile bit is already supported by several Application Servers, to wit Tom EE, Payara, Wildfly and OpenLiberty.

Thursday

Var with Style: Local Variable Type Inference in Java 10
Apparently there was some backlash amongst the community regarding this feature, but the speaker did an excellent job of indicating where it should be used and where it shouldn't be used and where it cannot be used. There's even a style guide for it!
GraalVM: Run Programs Faster Anywhere
Interesting if you wish to run several programming languages at the same time, and are interested in very fast startup times and very small memory footprint.
Is boilerplate code really so bad?
Yes, it's bad.
Polyglot Persistence - Which Data Model to pick for your Workload
An excellent overview of the different NoSQL/SQL/Document/KeyValueStores etc. data models and when to use them, the advantages and disadvantages, etc.
Vue.js: power and flexibility
Nice, reminds me of Angular and React, though.
From Java to Kotlin: the adventures of a smooth migration
Very easy to follow, seems easy to implement too, just add some dependencies and start replacing your java files. Most impressive was the fact that several packages of java classes could be replaced with one Kotlin file.
Bring serverless to Kubernetes with new open source tools
Down the SVG Rabbit Hole: Advanced SVG Effects & Optimized Workflow

I had no idea that the possibilities for animation and rendering of SVGs has come so far. Especially since it can all be rendered live in your browser nowadays.

Friday

How to build products people care about
How to apply AI to testing
Java Futures: Devoxx 2018 Edition

Sessions I wish I followed

Be More Productive with IntelliJ IDEA
Java Modularity :the Year after
Function Programming Patterns with Java8
The Z Garbage Collector

References

Devoxx BE (2018)
https://devoxx.be/
Devoxx BE 2018 - Playlist on Youtube
https://www.youtube.com/playlist?list=PLRsbF2sD7JVp8vBso4ysmj-X0u6uGx1rH
Devoxx 2018 - Deep Dive Day One
http://randomthoughtsonjavaprogramming.blogspot.com/2018/11/devoxx-2018-deep-dive-day-one.html

Tuesday, 13 November 2018

Devoxx 2018 - Deep Dive - Day One

Just writing down the sessions I followed, and some notes regarding the sessions.

Implementing Microservices with Jakarta EE and MicroProfile

The one point of issue that I had with the talk, is that it decided to tackle two issues. The talk was regarding JakartaEE and how to get about moving JavaEE over to Open Source, and what it takes. The talk was also about Eclipse MicroProfile. For me as a novice it is very hard afterwards to separate the characteristics of the two. I'm likely to mix it up.

It might have been better, if possible, to split the two items up into two talks.

JakartaEE

What I heard was that they are attempting to have an Eclipse Glassfish 5.1 version available on December 15th of this year, build from Open Source JavaEE specification 8.

There is already a staggering amount of building taking place of the different components in JakartaEE, see the EE4J CI/CD Progress2.

They're looking into getting JCP Standards Process replaced by "Something Else" called "Specification Process 1.0", because obviously they need some sort of process in place for JakartaEE. Hopefully without any of the problems that made JCP too slow.

The JNoSQL project is the guinea pig for the new Process.

They have TCK - test cases suites - to determine if application servers follow the specs.

Code First Mentality is what seems to work. Like Hibernate and Spring prove that something works very well, then standardize it and include it in Jakarta EE.

JakartaEE is apparently moving away from reference implementations.

It's going to be Community driven.

Eclipse MicroProfile

The project started as a way to easily move forward with JavaEE, without waiting for standards to catch up and to see what is possible. To get something quickly, the things implemented first was CDI+JAXRS+JSONP, in order to get some microservices running.

So we are already familiar with the Full Profile and the Web Profile regarding Application Servers. The MicroProfile is kind of like that, but without the whole application server behind it.

It's for quick progress and less about standards. The speed is quite impressive, 7 major releases in 2 years of existence. Features based on the "the honour system". If you say that it works, and that you've tested it, that's good enough.

This in stark contrast with Jakarta EE, a (future) standard with 1-2 major releases per year.

He did mention a cool article1 about what MicroProfile is bringing to JakartaEE.

Microservices

Now I am a novice when it comes to using microservices, how, when, where, etc.

Some interesting examples on how microservices are implemented:

Netflix
is running hundred and hundreds of microservices.
another company
could get by without with only 20 microservices that by definition might be a little more bulky.
third company

A good example of the use of microservices, is a company in Prague that computed hashes for passwords for people logging in. Apparently there were peaks in the system, for example when a new feature was announced, and people wanted to check what it did. It causes peaks, so the simple microservice for computing password hashes was deployed on every machine imaginable across all the branches of the company.

It's an excellent example of a very simple microservice that is computation intensive, without a lot of state required.

Java Streams vs. Reactive Streams: Which, When, How, and Why?

Venkat Subramaniam is a great speaker, and this was the first time I encountered him. The talk was amazing about the difference and common ground about the two. But also why you should use it, and when. Highly recommended.

Functional Exception Handling in Java with Vavr

A short talk but insightful. It basically boils down to using a Tuple to indicate success (the result value) or an error (the exception value) as a good work around of the fact that we cannot throw exceptions in lambdas.

Seems to be like the pattern used by Optional.

A Dozen Ways to Hack Your Brain to Write Fluently

It boils down to write a little bit, as soon as possible, and build it out from there.

There was a lot mroe to it than that, but I did not manage to follow the entire talk.

Exploring Java Heap Dumps

It was great. Apparently the Netbeans Java Profiler provides an API that makes it possible to drill down into the heap dumps you get to find out what the problem is. This way you can actually write a software application specifically for your problem and your application and attuned to your data model.

It can analyse the heap dump for you, but the javadoc specifically states for all functions in the API whether it can complete in normal time, or that the method you are using may require a long time (because it needs to access the entire heap dump).

It was actually not that big of an API. Apparently it is just a single package directory in the Netbeans Profiler source.

References

[1] How The MicroProfile Community Will Shape Jakarta EE
https://www.lightbend.com/blog/how-the-microprofile-community-will-shape-jakarta-ee
[2] JakartaEE CI/CD
https://ci.eclipse.org/
Getafix: How Facebook tools learn to fix bugs automatically
https://code.fb.com/developer-tools/getafix-how-facebook-tools-learn-to-fix-bugs-automatically/

Thursday, 8 November 2018

Attending Devoxx Belgium 2018

I shall be attending the Devoxx Belgium 2018 Java Conference in Antwerp, from 12th - 16th of November 2018.

My first time.

References

Devoxx Belgium 2018
https://devoxx.be/

Monday, 5 November 2018

I use Fedora

In due time, when I was little, I got started with the Redhat Linux distribution. It was a great step in the direction of getting a Linux operating system up and running with very little tweaking. Of course, I still had to compile the kernel, and configure XWindows and all sorts of other things.

Eventually, Fedora came into my life, and I have been using it ever since.

It's my Operating System of Choice both at home and at work.

References

Fedora Magazine - Say thanks during Fedora Appreciation Week (Nov. 5-11)
https://fedoramagazine.org/say-thanks-appreciation-week-2018/

Thursday, 1 November 2018

Securing Glassfish

As written in my previous blogpost, I mentioned securing Glassfish.

Here are the steps I took. I plan to add more steps, if I find them.

change the default passwords
a no-brainer, I think
do not run glassfish as root
I already did that, but I just mention it here. If you need to have it listening to port 80, there are plenty of ways to do that without running glassfish as root.
make sure the user running glassfish has /sbin/nologin as a login shell

so nobody can get shell access, unless you use another account1.

Also means if we need to access the account ourselves, we could run:

sudo -u glassfish /bin/bash
turn off admin console access from outside the server

Go to Configuration -> server-config -> Network Config -> Network Listeners -> admin-listener.

Under the General tab, in the Address: field replace 0.0.0.0 to 127.0.0.1

Restart the server

You can access the admin console using an ssh tunnel6:

[user@localhost ~]$ ssh user@mysite.com -L 4848:localhost:4848 -N

The first 4848 is the port of your homepc. The second 4848 is the remote port. And then connecting your browser to localhost:4848.

make sure only the essentials are accessible from outside the server

an application server has a very high number of open ports, many of them are only required for local access. Verifying this can be done with the following command:

[root ~]# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
tcp        0      0 0.0.0.0:7676            0.0.0.0:*               LISTEN      1002       8518781    14140/java          
tcp        0      0 0.0.0.0:42853           0.0.0.0:*               LISTEN      1002       9560152    14140/java          
tcp        0      0 0.0.0.0:44425           0.0.0.0:*               LISTEN      1002       9560153    14140/java          
tcp        0      0 0.0.0.0:45613           0.0.0.0:*               LISTEN      1002       9560151    14140/java          
tcp        0      0 0.0.0.0:8686            0.0.0.0:*               LISTEN      1002       8518047    14140/java          
tcp        0      0 0.0.0.0:4848            0.0.0.0:*               LISTEN      1002       8517513    14140/java          
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      1002       8516146    14140/java          
tcp        0      0 0.0.0.0:3700            0.0.0.0:*               LISTEN      1002       8516151    14140/java          
tcp        0      0 0.0.0.0:8181            0.0.0.0:*               LISTEN      1002       8516148    14140/java          
tcp        0      0 0.0.0.0:41593           0.0.0.0:*               LISTEN      1002       8517967    14140/javat
porttypecomments
7676Message Queue Port
42853
44425
45613
8686Pure JMX Clients Port
4848the administration consoleset it to localhost, and connect using ssh tunnel
8080the normal http listenerthis should be accessible from outside the server
3700IIOP Port ("ORB listener 1")
8181the normal https listenerthis should be accessible from outside the server
41593

This can be either done by changing the ip address in the configuration of the glassfish server to 127.0.0.1 instead of 0.0.0.0.

But it could also be done by adding firewall rules, disallowing incoming traffic to ports you do not approve.

However, why not do both?

turn off autodeployments2
asadmin set server.admin-service.das-config.autodeploy-enabled=false
dynamic-reload-enabled2 is another useful one to turn on and off in this manner
asadmin set server.admin-service.das-config.dynamic-reload-enabled=false
hide your identity
glassfish response headers contain information on what server you are running, what version, what frameworks, etc. You can turn this option off by following instructions of reference 3. Has some other excellent advice as well.
make sure any database access used by glassfish is as restricted as possible
usually it is enough to create a database user that has only access to one specific database4 5
add a second admin user account for accessing the glassfish admin console
just in case of problems
make sure the user running the glassfish has files with as restricted rights as possible
there is no reason for "other" and "group" to have any access.

References

[1] StackExchange - Unix&Linux - Does /usr/sbin/nologin as a login shell serve a security purpose?
https://unix.stackexchange.com/questions/155139/does-usr-sbin-nologin-as-a-login-shell-serve-a-security-purpose
[2] GlassFish Server Open Source Edition - Application Deployment Guide - Release 5.0
https://javaee.github.io/glassfish/doc/5.0/application-deployment-guide.pdf
[3] Securing your GlassFish. Hardening Guide
http://blog.eisele.net/2011/05/securing-your-glassfish-hardening-guide.html
[4] How to create a user in MySQL/MariaDB and grant permissions on a specific database
http://www.daniloaz.com/en/how-to-create-a-user-in-mysql-mariadb-and-grant-permissions-on-a-specific-database/
[5] MariaDB - SET PASSWORD
https://mariadb.com/kb/en/library/set-password/
[6] Frank Wiles - Quick-Tip: SSH Tunneling Made Easy
https://www.revsys.com/writings/quicktips/ssh-tunnel.html
Fine Tuning Payara Server in Production
https://blog.payara.fish/fine-tuning-payara-server-in-production
Bug 1530511 - rocksdb appears under "show databases"
https://bugzilla.redhat.com/show_bug.cgi?id=1530511

Thursday, 25 October 2018

UML Class Diagrams - Common Conventions

I just felt like writing this stuff down for once.

Java keywordUMLPlantUML syntax
public++/green circle
protected##/yellow diamond
package-private~~/blue triangle
private--/red square
abstractitalic{abstract}/italic
staticunderlined{static}/underlined
public final staticconstants are in ALL_CAPS
final definition{leaf}
final value{readOnly}

References

The Oxford Math Center - UML, Abstract Classes and Methods, and Interfaces
http://www.oxfordmathcenter.com/drupal7/node/35
UML 2.5.1. specification
https://www.omg.org/spec/UML/2.5.1/
StackOverflow - How do I add a final variable to a class diagram?
https://stackoverflow.com/questions/16252399/how-do-i-add-a-final-variable-to-class-diagram
PlantUML - Class Diagram
http://plantuml.com/class-diagram

Thursday, 18 October 2018

Sarketsdr

I am running a Glassfish server, and I recently noticed an application was deployed that I did not remember having deployed. The name of the application was completely unhelpful as being "Sarketsdr".

On closer inspection, the offending application contained a Java/JSP/JavaScript files, specifically to disclose the filesystem and grant shell access to persons unknown.

I've since removed the application and turned off the remote administration console. I plan on changing application servers, and keeping them properly updated.

I should also get some Intrusion Detection Systems going.

I've uploaded the files as gists.

File structure of Sarketsdr

File/DirectoryComments
aff.jsphttps://gist.github.com/maartenl/ddd99b927fc535a271b171a350fbe512
cj.jsphttps://gist.github.com/maartenl/dbfd8e11fb0767b06ee0f2d8c9d544bd
emu.jsphttps://gist.github.com/maartenl/549dc20a5229560e34cebf0c38e422b8
index.jsphttps://gist.github.com/maartenl/cc96faa3feb78fdeeaeff8cc12e0700b
mob.jsphttps://gist.github.com/maartenl/6deb7a1f277a6843ee34fe709b7ca5ec
META-INF
      context.xml
      MANIFEST.MF
WEB-INF
      web.xml

I am working on securing my Glassfish installation in the mean time.

References

Frage /etc/rc.d/init.d/wipefs startet das CPU-Problem
http://webirectory.com/questions/19967/etc-rc-d-init-d-wipefs-startet-das-cpu-problem
FortiGuard Labs - JSP.File.Browser
https://fortiguard.com/appcontrol/42719
vonloesch.de - Jsp File Browser
http://www.vonloesch.de/filebrowser.html

Thursday, 11 October 2018

The Browser Keeps Bugging Me

Lately the browser and/or websites seems to keep bugging me, and I am getting a little tired of it.

The questions it keeps asking for each website are the following:

  1. "We use cookies to ensure ... etc."
  2. "Would you like Firefox to save this login for [sitename]?"
  3. "Will you allow [sitename] to send notifications?"

The amount of questions a website/webbrowser offers me seems to have been proliferating lately.

I always accept cookies, but I never want the other options.

Seeing as I am using Firefox at the moment, let's see what we can do about it.

  1. The "i-don't care about cookies' addon1 2 seems to suit me just fine.
  2. Preferences - Privacy & Security - Forms & Passwords - turn off "Remember logins and passwords for websites".
  3. Go to "about:config". Search for "dom.webnotifications". Set "dom.webnotifications.enabled" to false to not see any notifications3.

UBlock addon4 5 seems to be also very good.

References

[1] I-Don't-Care-About-Cookies website
https://www.i-dont-care-about-cookies.eu/
[2] I-Don't-Care-About-Cookies addon
https://addons.mozilla.org/en-US/firefox/addon/i-dont-care-about-cookies/
[3] Web Push notifications in Firefox
https://support.mozilla.org/en-US/kb/push-notifications-firefox
[4] Firefox Addon UBlock
https://addons.mozilla.org/nl/firefox/addon/ublock-origin/
[5] Wikipedia - UBlock
https://en.wikipedia.org/wiki/UBlock_Origin

Saturday, 6 October 2018

SSH Key-Based Authentication

I'm using reference [1] almost exclusively, it is easy to follow and very well written. The reason I am writing stuff down here, is in the case the referenced article goes offline.

Generating Keys

[mrbear@localhost ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mrbear/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Passphrases do not match. Try again.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mrbear/.ssh/id_rsa.
Your public key has been saved in /home/mrbear/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:etv4wn8 4843n3v48nvan80avw2408a4vn588an04845 mrbear@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
| ..o |
| E o= . |
| o. o |
| .. |
| ..S |
| o o. |
| =o.+. |
|. =++.. |
|o=++. |
+-----------------+
[mrbear@localhost ~]$

Copying keys to the server

[mrbear@localhost ~]$ ssh-copy-id mrbear@www.mysite.org
The authenticity of host 'www.mysite.org (10.0.0.11)' can't be established.
ECDSA key fingerprint is SHA256:B&B(&BSf7bFSfb7fF&SFb7SF&tFibFuSOWWFuFBUf76.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
mrbear@www.mysite.org's password:

Number of key(s) added: 1

Now try logging into the machine, with: "ssh 'mrbear@www.mysite.org'"
and check to make sure that only the key(s) you wanted were added.

[mrbear@localhost ~]$

Logging in

[mrbear@localhost ~]$ ssh mrbear@www.mysite.org
Last login: Mon Sep 24 21:01:12 2018

Add to sudoers file

Found how to do this at [2].

[root@mysite ~]# usermod -aG wheel mrbear

Disabling Password Authentication

Edit the file /etc/ssh/sshd_config.

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication no
# systemctl restart sshd.service

Now what you get when you try is:

$ ssh -l root www.mysite.org root@www.mysite.org: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

Thank the heavens I no longer have to worry about messages as the one below:

root@mysite's password:
Last failed login: Sat Oct 6 10:12:48 CEST 2018 from 10.0.0.1 on ssh:notty
There were 56310 failed login attempts since the last successful login.
Last login: Tue Oct 2 23:23:41 2018
[root@mysite ~]#

I originally had installed fail2ban, as a way to protect against a password-based attack, but even the man page of fail2ban3 indicates that the above way is pretty much better.

References

[1] Digital Ocean - How To Configure SSH Key-Based Authentication on a Linux Server
https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server
[2] Top 20 OpenSSH Server Best Security Practices
https://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices.html
[3] Fail2ban
https://www.fail2ban.org/wiki/index.php/Main_Page
How to disable ssh password login on Linux to increase security
https://www.cyberciti.biz/faq/how-to-disable-ssh-password-login-on-linux/

Thursday, 27 September 2018

Mutable members should not be stored or returned directly

But SonarLint is complaining about it, so I refactored it into this:

It's high time this old codebase gets converted to LocalDates.

References

SonarSource - RSPEC-2384
https://rules.sonarsource.com/java/RSPEC-2384

Monday, 24 September 2018

Using a composite key in a map

Once again I stumbled upon old code, that could use some refactoring.

It took me and my colleague a few seconds to process what the software designer had in mind when he did this.

As it was up to me to add another field to the construction, making it even more terrible than it was, it was time for a refactoring.

Refactored solution

We quite quickly came up with using a Composite Key, which of course is the default way to deal with this sort of thing.

Added benefit

There was some trickery going on to properly deal with NULL keys (which are sometimes not allowed in a Map implementation1).

This disadvantage now disappears with this nice composite key.

Test setup

I tested it with a list of cars, and I do not wish to withhold the test setup:

Fuzzy matching

Of course it is quite easy to just match on some of the criteria. In this case, we could use a Map containing Lists, where the composite key used has empty fields, and would cause a list of cars to be returned and a full composite key (all search criteria) would just yield a list containing one specific car.

If we wish to use fuzzy matching, we are in a bit of a bind.

I'm pretty sure there are always other (perhaps even better) ways of doing this. If you know of some, let me know.

I'm always interested.

References

[1] Oracle JavaDoc - Map Implementation
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
Different Types Of Cars List
https://auto.ndtv.com/news/types-of-cars-1450327

Wednesday, 12 September 2018

Pop quiz answer: varargs

The answer for the VarArgs Pop Quiz.

Testcase 1 : [Ljava.lang.String;@579bb367 is not null and has length 0
Testcase 2 : args is null
Testcase 3 : [Ljava.lang.String;@1de0aca6 is not null and has length 2
     first element is null

Process finished with exit code 0

The reason for the quiz is that there's a potential NullPointerException in there, that you need to be aware of.

According to reference [1], if the argument provided is compatible with String[], it is assumed that that is what you meant. And null is always compatible with any T[].

Also interesting enough and just to drive the point home, it means that the method signatures below are identical and Java will give you a big fat warning that you defined the same method twice.

public void vars(String... args);

public void vars(String[] args);

References

[1] Oracle Java Language Spec - 15.12.4.2. Evaluate Arguments
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.4.2
Blogpost - Pop Quiz: Varargs
https://randomthoughtsonjavaprogramming.blogspot.com/2018/09/pop-quiz-varargs.html

Friday, 7 September 2018

Pop quiz : varargs

Pop quiz: what is the output of the following program:

The answer in the following blog post.

Friday, 24 August 2018

Friday, 10 August 2018

Can I use a Stream multiple times?

Just a quick question, that I answered using a small unit test.

Stream<String> stream = Arrays.asList("John""Paul""Ringo""George").stream();
assertThat(stream.filter(x -> x.equals("Matthias")).collect(Collectors.toList())).hasSize(0);
assertThat(stream.count()).isEqualTo(4);

Does this work?

Answer in my next blog.

Thursday, 2 August 2018

Dialogue

So, on route to the train station, the following conversation took place between me and my two colleagues:

Colleague 1: Another day in software design, where nothing is as it seems.
Me: If nothing is as it seems, you probably violated every naming convention known to man.
Colleague 2: Clean code!! Uncle Bob would be proud!

Thursday, 26 July 2018

Remove splash screen in Fedora Core

Just a reminder of mine on how to remove the Splash screen from Fedora Core to make it more obvious if something is going wrong.

Edit /etc/default/grub and replace

GRUB_CMDLINE_LINUX="rhgb quiet"

with

GRUB_CMDLINE_LINUX=""

After that, we need to run grub2-mkconfig:

[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfg

Yes, that's right, I'm still using BIOS instead of UEFI. One of these days (years, decades), I'm going to have to upgrade my machine.

References

Re: What is "rhgb" on the grub, kernel line?
https://www.redhat.com/archives/rhl-list/2004-May/msg07775.html
Fedora Official Docs - Working with the GRUB 2 Boot Loader
https://docs.fedoraproject.org/f28/system-administrators-guide/kernel-module-driver-configuration/Working_with_the_GRUB_2_Boot_Loader.html

Wednesday, 18 July 2018

IKEA hack: toddler learning tower stool

I occasionally do a bit of very amateurish woodworking, and my wife found a website with the following learning tower stool1.

As the website indicates, it is basically a Ikea BEKVÄM stool2, added on top is a wooden frame where the child can climb into so he/she is secure and can help me out with cooking.

I am neither a professional painter nor a professional carpenter, and for this I do not need to be. The screws to affix the pieces of wood are still clearly visible (just recessed far enough in the wood) and the painting could have been better (the website mentions spray painting for a more even nicer coat), but it sufficed for my purposes.

itemmeasurements (in cm)amount
Wood
rod31 long, 1 diameter1
vertical supports39.5 x 3.5 x 1.84
hortizontal supports, short16.4 x 6.7 x 1.84
horizontal supports, long31 x 6.7 x 1.82
Other stuff
screws, long0.4 x 710
screws, short0.35 x 414
white primer paint
white wood paint, matt
Tools
drill
screwdriver
tape measure or ruler
sandpaper
pencil

Unfortunately, our son is growing a bit big for the item, but he enjoys climbing/crawling into and out of it, when I start cooking, to help me out. But I should have made the stool a little earlier, so it was an easier fit for him. Kids grow so fast.

The screws in the picture above are clearly visible.

References

[1] Ikea Hack: Toddler Learning Tower Stool
http://happygreylucky.com/ikea-hack-toddler-learning-tower-stool/
[2] Ikea BEKVÄM Step stool, white
https://www.ikea.com/us/en/catalog/products/40178888/

Thursday, 21 June 2018

Progress!

Time for me to get dragged kicking and screaming into the Century of the Fruitbat1.

I have purchased my first SSD4.

I will spend a pleasant evening unwrapping and installing this thing. And consequently reinstalling all my operating systems.

Specifications
BrandSamsung
TypeSSD 860 EVO
InterfaceSATA 6 Gb/s Interface, compatible with SATA 3 Gb/s & SATA 1.5 Gb/s interface
Capacity500 GB (1 GB=1 Billion byte by IDEMA)
Sequential Read SpeedUp to 550 MB/s
Sequential Write SpeedUp to 520 MB/s
ControllerSamsung MJX Controller
NAND FlashSamsung V-NAND 3bit MLC
Cache MemorySamsung 512 MB Low Power DDR4 SDRAM
AES EncryptionAES 256-bit Encryption (Class 0)TCG/Opal IEEE1667 (Encrypted drive)
GC (Garbage Collection)Auto Garbage Collection Algorithm
Internal StorageYes
Form Factor2.5" SATA III
Reliability (MTBF)1.5 Million Hours Reliability (MTBF)

Of course, my colleagues wouldn't be my colleagues if they didn't mention that you can get much better deals for much less money per megabyte3. Four terabytes in one package. Sheesh.

References

[1] LSpace Wiki - Century of the Fruitbat
https://wiki.lspace.org/mediawiki/Century_of_the_Fruitbat
[2] Samsung SSD 860 EVO Specifications
https://www.samsung.com/us/computing/memory-storage/solid-state-drives/ssd-860-evo-2-5--sata-iii-500gb-mz-76e500b-am/
[3] Tweakers - Origin Storage DELL-4TBNLSA/7-F17 4TB
https://tweakers.net/pricewatch/1183219/origin-storage-dell-4tbnlsa-7-f17-4tb.html
[4] Wikipedia - Solid-state drive
https://en.wikipedia.org/wiki/Solid-state_drive

Friday, 8 June 2018

Building microservices with Vert.x and Building a self-driving RC car

On Thursday, 7th June 2018, in the evening, I was attending two talks in Den Bosch (or 's-Hertogenbosch, depending on who you talk to) at Malmberg1. Malmberg is a company that has adapted to the times and made educational materials and books and magazines, then it started to focus on educational materials exclusively, and has been working on putting said educational materials in Microservices and the Cloud for the last five years.

JPoint2, the consultancy agency has been instrumental in getting them up and going.

Building microservices with Vert.x (Bert-Jan Schrijver)

You can find the slides for the first talk at slideshare3.

They do a pretty good job of explaining what it is and how it can help you.

The examples are available at a github4 location.

Building a self-driving RC car (Tim van Eijndhoven)

This talk already was given at Devoxx UK, and there's a youtube video5 about it.

It uses the ServoBlaster6 software to drive the motors.

It uses the RPi Web Cam7.

It uses a C++ library for pattern recognition in images called OpenCV8 - open source computer vision, which already has a JNI interface with Java.

The github repo9 regarding the car can be found here.

References

[1] Malmberg
https://www.malmberg.nl/
[2] JPoint
https://www.jpoint.nl/
[3] Slideshare - Building microservices with Vert.x - Bert-jan Schrijver
https://www.slideshare.net/Codemotion/building-microservices-with-vertx-bert-jan-schrijver-codemotion-amsterdam-2016?qid=ffe2e0b9-f7fe-4897-8452-16cacc43a5ff&v=&b=&from_search=3
[4] GitHUb - vert.x 3 coding examples
https://github.com/bertjan/vertx3-examples
[5] Youtube - building a self-driving RC car
https://www.youtube.com/watch?v=yLg-LPSRjho
[6] GitHub - ServoBlaster
https://github.com/richardghirst/PiBits/tree/master/ServoBlaster
[7] GitHub - RPi Web Cam Interface
https://github.com/silvanmelchior/RPi_Cam_Web_Interface
[8] Open CV
https://opencv.org/
[9[ GitHUb - rc-dukes
github.com/rc-dukes

Monday, 4 June 2018

Can I use a builder to build many objects?

I recently questioned if it is okay to use a builder to make multiple objects. The software was designed in such a way that this is possible, but I hesitated because I did not know if it was a good idea.

I know for a fact that a lot of builders in our software, might not be suitable for this use case, as they have too many dependencies (that shouldn't be there) on using the proper sequence.

That said, the following quotes are good to take to heart when designing builders1 2:

“The Builder pattern is flexible. A single builder can be used to build multiple objects. The parameters of the builder can be tweaked between object creations to vary the objects. ”
“The builder object is responsible for constructing a valid object but the object is not constructed until you call the build() method. This means the same builder can be used multiple times to construct completely different objects.”

I especially like the last quote.

References

[1] StackOverflow - How to use a single builder to build multiple objects?
https://stackoverflow.com/questions/14429043/how-to-use-a-single-builder-to-build-multiple-objects
[2] Effective Java 2
Joshua Blog

Thursday, 24 May 2018

Hello World with Maven

Getting started with Maven is slightly complicated, so I thought I'd write down some links1 2 on how to get up and running quickly with a simple HelloWorld Java application with Maven archetypes.

That and I wanted to tell how to upgrade the Java version used for the Maven project. There seem to be different ways to do it. Some easy, some hard.

Groupidorg.apache.maven
Artifactidthe name of the jar without version, for example maven, commons-math
Version2.0
mvn archetype:generate -DgroupId=com.mrbear -DartifactId=mrbear -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false

Verify that this is the latest archetype version4.

Upgrading to Java 8

One way is to add the versions to the properties in the pom.xml, which is easiest.

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

Another way is to change the maven compiler plugin to use the new version, which is harder.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

References

[1] Apache Maven Project - Creating a simple java application
https://maven.apache.org/plugins-archives/maven-archetype-plugin-1.0-alpha-7/examples/simple.html
[2] Apache Maven Project - Maven in 5 Minutes
https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
[3] Apache Maven Project - Setting the -source and -target of the Java Compiler
https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
[4] Apache - Maven Archetype Quickstart Summary
http://maven.apache.org/archetypes/maven-archetype-quickstart/summary.html

Friday, 18 May 2018

Access control modifiers in Java

Just a small blog post.

Some time ago I came across a basic fact in the core Java programming language, that I have interpreted too narrowly for a very long time.

I always have interpreted the "protected" keyword as making the properties or methods of a class available in its subclasses.

Turns out, according to [1] this is not entirely accurate. That's not all it does.

The following table is lifted from the docs in [1]:

ModifierClassPackageSubclassWorld
publicYYYY
protectedYYYN
no modifier Y Y N N
private Y N N N

If you look at the table above, you'll notice that protected is really only one level more secure than public, which was an eye opener for me.

It turns out "protected", isn't really that protected really.

No modifier

If you omit any kind of modifier, you will automatically get the behaviour that the method/property can be accessed only by other classes in the same package.

There are several sources declaring it "no modifier" or "default modifier" or "default protected modifier", but I prefer the "package private modifier" (or just "package-private" for short). The latter is the official Java convention as described in [1].

To my mind it is the best clear short precise definition of what you can do with it.

The JLS2 strictly only mentions "package access".

Conclusion

Apparently there is no Access Modifier in Java that makes methods or fields only be inherited from subclasses3.

However we can achieve the same goal, by putting the subclasses of a class into the same package, and keep this package devoid of all others.

Sealing JARs

Of course, it means that if I create a package with the same name as a package in a JAR file included in my project, I will gain access to all the package private classes in the same package in the JAR.

This problem can apparently be solved by sealing4 the JAR file.

References

[1] Oracle - The Javatm Tutorials - Controlling Access to Members of a Class
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
[2] Oracle - Java Language Spec - JDK 8
https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf
[3] StackOverflow - Why is there no subclasses only access modifier in Java?
https://softwareengineering.stackexchange.com/questions/238581/why-is-there-no-subclasses-only-access-modifier-in-java
[4] Oracle - The Javatm Tutorials - Sealing Packages within a JAR File
https://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html

Thursday, 10 May 2018

Default method 'toString' overrides a member of 'java.lang.Object'

An interface "inherits" methods from the Object class. I wrote about this here1.

The quotes are appropriate, because Interfaces can only inherit from other Interfaces. An interface, when it does not have a super interface, declares all public non-final methods of the Object as members of the Interface (if not explicitly defined in the interface.

I recently attempted something like this TaxBracket2:

It doesn't work. In fact my IDE started complaining immediately with the following message.

Default method 'toString' overrides a member of 'java.lang.Object'

It is supposed to do that, so says the Java Language Spec3:

It is a compile-time error if a default method is override-equivalent with a non-private method of the class Object, because any class implementing the interface will inherit its own implementation of the method.

My colleague helpfully provided the alternative, which is to make an "elementString()" method in the Interface, which can be called in the toString() method of every Class that implements the Interface. (Further down in the JLS, this approach is almost word for word also given)

StackOverflow4 has a helpful link to the JDK mailinglist5 that explains it a lot more in depth.

One of the remarks that really struck a cord with me, is the fact that toString(), equals() and hashCode() are all basically related to the state of a Class, and do not belong in an Interface.

I have therefore decided to remove the offending default method.

References

[1] Do interfaces inherit from object class?
http://randomthoughtsonjavaprogramming.blogspot.nl/2017/07/do-interfaces-inherit-from-object-class.html
[2] Wikipedia - Tax bracket
https://en.wikipedia.org/wiki/Tax_bracket
[3] JLS 8 - 9.4.1.2. Requirements in Overriding
https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.4.3
[4] StackOverflow - Java8: Why is it forbidden to define a default method for a method from java.lang.Object?
https://stackoverflow.com/questions/24016962/java8-why-is-it-forbidden-to-define-a-default-method-for-a-method-from-java-lan
[5] Malinglist OpenJDK - Allow default methods to override Object's methods
http://mail.openjdk.java.net/pipermail/lambda-dev/2013-March/008435.html

Friday, 4 May 2018

Creating a method reference on a null reference does not throw NullPointerException

We ran into a problem that the Unit tests ran perfectly on my local machine, but the same Unit tests would break in the continuous delivery pipeline.

The problem occurred when creating a method reference. Like so:

When running the test included above, the test failed with:

java.lang.AssertionError: Expected exception: java.lang.NullPointerException

After some research we found out that the difference between the two is the Eclipse compiler used by the IntelliJ IDE vs. the openjdk installed in the continuous delivery pipeline.

We found out that it is illegal to use a method reference on a null reference. Quoting from [1]:

First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated. If the subexpression evaluates to null, a NullPointerException is raised, and the method reference expression completes abruptly.

At first glance, this is a bit weird. After all, we want to have a method reference, in order to call it at a later time, which in fact may never occur. So why not have the NullPointerException when an attempt is made to actually call the method?

IntelliJ

IntelliJ comes equipped automatically with the Eclipse Java Compiler (ECJ), and as such it takes some effort to find out which version is installed along with the IDE.

Jar file ecj-4.6.1.jar was include in directory .local/share/JetBrains/Toolbox/apps/IDEA-U/ch-1/181.4445.78/lib/ecj-4.6.1.jar.

In IntelliJ it is possible to provide the path to the ecj jar to use, see [2].

Setting the path to the newly downloaded jar file ~/Downloads/ecj-4.7.3a.jar solved my problem.

It's been a long time since I encountered a bug in the compiler3, but other people have noticed it too4 and then it gets fixed.

Note

Bear in mind that, if we did not use a method reference, but an ordinary lambda, that this problem would not have occurred (immediately).

This means that, if you replace a Lambda with a method reference you may be introducing a NullPointerException earlier in the code without realising it5.

Bear this in mind.

References

[1] JLS 8 - 15.13.3. Run-Time Evaluation of Method References
https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.13.3
[2] IntelliJ - Specifying compilation settings
https://www.jetbrains.com/help/idea/specifying-compilation-settings.html
[3] Eclipse - Bug Report
https://bugs.eclipse.org/bugs/show_bug.cgi?id=521182
[4] StackOverflow - Creating a method reference on a null reference does not throw an exception
https://stackoverflow.com/questions/37681625/creating-a-method-reference-on-a-null-reference-does-not-throw-an-exception
[5] StackOverflow - java.lang.NullPointerException is thrown using a method reference but not a lambda
https://stackoverflow.com/questions/37413106/java-lang-nullpointerexception-is-thrown-using-a-method-reference-but-not-a-lamb/37413546

Thursday, 26 April 2018

Java Language Futures: 2018 edition

On Monday, 23 April 2018, in the evening, I was attending two talks by Brian Goetz, Oracle Language Architect, at the Werkspoorkathedraal in Utrecht. The talk was made possible with the help of several parties, for example JPoint2 and Code Nomads3.

First talk - On Software Design

This first talk was not about technical details, but more about us software designers as a group, and how we tend to be tribal like the rest of the Human Race. Our tribes are split up upon the lines of programming languages, editors, software paradigms, layout, etc.

From an evolutionary standpoint this has always been a good idea, to protect the group, from predators and other software designers. Currently, it will limit us in our way of thinking, in trying new ideas (generated "outside the tribe") and promotes right-wrong judgmental thinking, etc.

All the energy that is spent condemning other practices of software design, can be better spent on becoming a better software designer.

Most users of software do not care about software design, they care about working programs.

Software design

When comparing Functional Programming to Object Oriented Design, what immediately stands out is that Objects are a bit more ambitious compared to Functions. Functions are derived from the Procedural way of programming.

Every programming language has a "Everything is an object|function|file|thingamabob", and that works for 5 minutes, and then it becomes impractical.

A lot of programming paradigms have always been quickly hailed as the solution to all our problems. So far this has not worked out. Every programming paradigm must be seen as another tool in the software designers toolbox.

One of the more interesting questions of course is when should you apply what. I think that is where the good software designer can stand out from the rest. Brian mentioned that, in the case of object oriented versus functional, the functional is a good fit for business logic, where the object oriented is a good fit for everything surrounding the business logic, for example databases and IO.

Second Talk - All Aboard Project Amber

The second talk went quite in-depth into the new features of project Amber4 and also the problems associated with changing an old language that everyone is using, without everyone trying to hang the Language Architect. As well as how to decide what new features to add, how easy they are to add, and how much use they would be.

What was interesting was to see the area each JDK focused on, the following list was mentioned:

JDK 5
rebooting data abstraction (by means of Generics)
JDK 8
rebooting behavioural abstraction (by means of Lambdas)
JDK 9
rebooting configuration and encapsulation (by means of Modules)

Java Language Principles

He mentioned his favorite sheet, which looked like this:

  • code should be a joy to read
  • the language should not hide what is happening
  • code should do what it seems to do
  • a clear semantic model greatly boosts reusability
  • every good feature adds more bad weight
  • sometimes it is best to leave things out

General rule: type inferences is ok in implementation not in APIs.

Naming is the single most expressive place to indicate to our audience what our program is.

Raw string literals

It will be possible to use backticks to indicate a beginning and an end of a string. Everything in between will be treated as raw information.

Product types

It is a class that only contains data, for example:

record Point(int x, int y)

You could call them Plain Old Data Objects - PODOs

Disclaimer: uh, the abbreviation PODO is mine, and not Brians.

Records are like Enums, in that you decide to give up some things, and in return you get reliable defaults.

Sum types

The possibility to limit the amount of subclasses, by means of a sealed Interface. For example:

sealed Interface Shape;

record Point(int x, int y);

record Circle (Point center, int radius) implements Shape;
record Rect (Point 11, Point ur) implements Shape;

Pattern matching and the improved switch

The switch statement has always been very limiting to Strings and primitive data types.

That is why usually you had to use the Visitor5 pattern to get anything complex done.

Im going to have to point you to documentation that explains this a lot more in depth, than I can in this blog6, 7.

Conclusion

Brian talked about a lot of things, some of which I have endeavoured to transcribe here. I enjoyed listening to him immensely as he is a captivating speaker, who seems to really know what works and what not in the realm of programming languages.

Brian is a big proponent of the new Java release cadence, and what it has to offer for us software designers.

Choice quotes

I always enjoy hearing pithy comments. Somewhere along the talk, he mentioned these gems:

“Homomorphism : the translation from real world to software applications (or vice versa), where all the relations stay intact. It does not work, because inevitably information is lost during the transformation.”
- Brian Goetz

“It's very common for software designers to have opinions on things they know nothing about.”
- Brian Goetz

“Nothing is more dangerous than an idea, if it's the only idea you have.”
- Émile Chartier

“Sorcerers Apprentice Objects.”
- Brian Goetz - on classes created when you are still learning the language

“Actually I made up the term object oriented and I can tell you that I did not have C++ in mind.”
- Alan Kay

“We write in C++ so you don't have to.”
- JVM software designers.

References

[1] Brian Goetz
https://www.linkedin.com/in/briangoetz
[2] JPoint
https://www.jpoint.nl/
[3] Code Nomads
https://www.codenomads.nl/
[4] Openjdk - Project Amber
http://openjdk.java.net/projects/amber/
[5] Wikipedia - Visitor Pattern
https://en.wikipedia.org/wiki/Visitor_pattern
[6] JEP 305 - Pattern matching
http://openjdk.java.net/jeps/305
[7] JEP 325 - Switch expressions
http://openjdk.java.net/jeps/325