Starting with gradle, creating a simple build.gradle

(note: proof edits pending)

Gradle a very well known building tool, originating in JVM world, but spreading to wider and wider use. A building tool is designed to automate workflows, particularly for building programs but in fact can automate any workflow iincluding building, linting, testing, pushing and much more to make your life easier. Sometimes it could be hard to grasp the concept even after reading the official documentation. This guide focuses on the basics and can enable having gradle up and running within a few minutes.

1. Gradle Introduction
2. A practical workflow for working with gradle
3. Add plugins
4. Configure the plugin
5. Add the dependencies of your project
6. Configure the project information
7. End

Continue reading “Starting with gradle, creating a simple build.gradle”


Gradle with Intellij: Using build.gradle

When first opening a kotlin project that has a gradle configuration, the following two messages should appear:

  1.  Configure gradle in project – DO NOT DO THIS!!!
  2. Import gradle project – ONLY DO THIS ONE ONLY

The trap is that the first suggestion modifies the file, and in fact our trials, this will normally break the build.gradle file.  If you have selected this, the only solution is to then undo those modifications made by IntelliJ and try again.

The import gradle may require setting the gradle home directory.  Set this to the location where you installed gradle. On a Mac, this is typically /usr/local/opt/gradle/libexec.


Gradle window (view/tool windows/gradle or gradle from right sidebar)


Note if the import gradle option action does not appear, check if the gradle window is already available, in which case import gradle has already taken place.  If not, try closing and reopening the project after checking that the build.gradle file is in the project root.

Once the import gradle is complete (it takes a while),  open the gradle window (view/tool windows/gradle or gradle in the right sidebar) and expand tasks/build and activate the ‘build‘ option under tasks/build.

It might be useful to then select the gradle build in the run debug toolbar (as shown below):


by clicking the dropdown, and selecting an option with the green gradle icon (as shown to the left of Unnamed above) before using the build build/build project or the run or debug symbols from the bar shown above.  Do not use either of these options before running.

How to publish artifacts to Maven Central via Gradle

Publishing artifacts on Maven Central is a close equivalent to publishing Python packages on PyPI (aka the cheese shop). If you have published packages on PyPI before, you will find these steps a bit more advanced than those you tackled in Python.

0. First things first
1. Sign up
2. Apply for your namespace
3. Get the GPG key
4. Save your secrets
5. Set up your project to upload
6. Upload
7. Publish on Maven Central
8. Use it

0. First things first

No one can publish to Maven Central directly. You have to publish your artifacts to an approved repository, then release them to Maven Central.
Sonatype OSS Nexus​ is an approved repository hosting service run by Sonatype (the company that runs Maven Central) which provides hosting free of charge specifically for open-source projects.


1. Sign up

Hopefully, you know about namespaces, packages and groupIds, right? To upload an artifact into a Sonatype repo, your artifact should be created using a specific namespace in order to prevent naming collisions. The package and groupId are also required. You must apply for a namespace from Sonatype. To apply for a namespace, you will need to raise an issue (see below) on the Sonatype Jira instance. In order to do that, you will first need to sign up for a Sonatype Jira account.


  • Sign up with your company email if you are going to apply for a groupId which will be the domain name of your company.
  • Remember your user name and password. It is not only used for raising issues. It is used for uploading your artifacts as well.


2. Apply for your namespace

Create an issue here to apply for your namespace (it should be a reversed domain name). Your issue will be manually reviewed by a Sonatype employee. It should be fast, within 2 hours.


After your application is approved, you will gain permission to the following URLs:


3. Get the GPG key

If you use Mac, you should download and install GPG Suite. Then open the app. The generate new key pair dialogue box should automatically open, otherwise press New on the tope menu in the app to create your key pair.

  • Name is the user name that you used when you registered on Sonatype.
  • Email is the email address that you used when you registered on Sonatype.
  • Enter a unique password twice to confirm it. Remember this password too, you are going need it.
  • Advanced options can be left as they are.

Needs confirmation: I don’t know whether the user name and email need to match, but I matched them both just in case.

After successfully creating your key, either accept the option to Upload Public Key in the dialogue box displayed or right-click your key in the key list in the app and select Send Public Key to Key Server to publish your public key.
To find your Key ID double-click your key in the key list in the app, select the Key tab if not already selected, note it down.
In Terminal on your Mac, use this command to get the secret key ring file:
gpg --export-secret-keys YOUR-KEY-ID > secret-keys.gpg

Enter the passphrase you used when you created the key in the Pinentry Mac dialogue box when it is displayed. The secret-keys.gpg file will be located in the folder where you ran GPG export command above. Take note of the path to this file, it will be needed later.
If you use Windows or other systems, you just need to get the following 3 things in order to push any further:

  • Key ID of your newly generated key pair.
  • The key password for this key pair.
  • The secret key ring file called secret-keys.gpg.

4. Save your secrets

Create your ​ file or open it if you already have one and add the following code:




  • Add the to your project root folder rather than in the .gradle  or gradle folders. Why? I am using Intellij IDEA and my IDEA gradle settings file could not be found if I put it either of those two folders. I had to put it in the project root.
  • ADD THE FILE TO YOUR PROJECT’S .gitignore. You never want to release this to the repo (it has your key password).


5. Set up your project to upload

There is an official guide here using the Maven gradle plugin, but I choose to use ​ because I found it easier to understand and use.
Below is the full code listing of the build.gradle ​ plugin. Add it to your current gradle code:

buildscript {
  repositories {
  dependencies {
     classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'

apply plugin: ''

archivesBaseName = 'teachUpload-jvm'
group = "com.yourCompany.package"
version = "0.1"

modifyPom {
 project {
   name 'teachUpload'
   description 'Teaching how to use gradle.'
   url ''
   inceptionYear '2018'

   scm {
     url ''
     connection 'scm:'
     developerConnection 'scm:git://'

   licenses {
     license {
       name 'The Apache Software License, Version 2.0'
       url ''
       distribution 'repo'

   developers {
     developer {
       id 'albertgao'
       name 'Albert Gao'
       email ''

extraArchive {
 sources = true
 tests = true
 javadoc = true

nexus {
 sign = true
 repositoryUrl = ''
 snapshotRepositoryUrl = ''


  • You don’t need to create the sourceJar in the build.gradle settings file above. The ​ plugin will add it for you.

6. Upload

The above code should add an uploadArchives task to your gradle (it might reside in the upload category (if you can’t find it in your IntelliJ IDEA gradle side-panel)).

Double click it to execute the uploadArchives task.
You might see the following error when you first upload:
Could not find metadata com.yourCompany.package:teachUpload-jvm/maven-metadata.xml in remote (

  • This is not an error, just information – this is your first time, so no meta file previously existed on the server.
  • Your package will have already been uploaded if this is the only information displayed.

Congratulations! After completing all of these steps, your package should finally have been uploaded onto Sonatype OSS Nexus.


7. Publish on Maven Central

There are two ways to get your artifacts onto Maven Central:

  1. Auto-publish via gradle
  2. Manually publish via Nexus website

7.1 Auto-publish via gradle

We are going to need to use another gradle plugin called Gradle Nexus Staging plugin.

Just add the following gradle code:

plugins {
    id '' version '0.11.0'
nexusStaging {
    // optional if packageGroup == project.getGroup()
    packageGroup = "org.mycompany" 

    // when not defined will be got from server using "packageGroup"
    stagingProfileId = "yourStagingProfileId"

Now several gradle tasks will exist:

  • closeRepository – closes an open repository with the uploaded artifacts. There should be just one open repository available in the staging profile (possible old/broken repositories can be dropped with Nexus GUI)
  • releaseRepository – releases a closed repository (required to put artifacts to Maven Central aka The Central Repository)
  • closeAndReleaseRepository – closes and releases a repository (an equivalent to closeRepository and then releaseRepository)
  • getStagingProfile – gets and displays a staging profile id for a given package group. This is a diagnostic task to get the value and put it into the configuration closure as stagingProfileId.

Now you should already have uploaded your artifacts to the Nexus repo. All you need to do now is to run the closeAndReleaseRepository, and your artifacts will be added to Maven Central (within 10 min ~ 2 hours).


  • If you have a multiple project gradle setup. You just need to add this plugin at the root level.

7.2 Manually publish via Nexus website

The reason we still need this publishing option is that sometimes there are some errors during the auto-publishing phase. After publishing, check the status on the website. Follow the steps below to publish manually if the auto option is unsuccessful.

  1. Open the Nexus Repository Manager.
  2. Click the Log In button in the upper right corner of the screen.
  3. On the right-hand side, click Staging Repositories.
  4. Search your project by following this search pattern: if for example, your groupId is, then enter comgoogle.
  5. Select the correct item and click the Close button to close it – this action finalizes the upload.
  6. Click the Refresh button to get the latest updates (remember this trick, no ajax yet).
  7. If see any errors:
    • You can inspect them at the Activity panel.
    • You will need to:
      •  Drop this upload
      • Find and fix the errors in your local folder
      • Run the uploadArchives task again
      • Then finalize the upload by pressing the Close button again and then continue
  8. If you see NO errors:
    • Click the Release button to publish

Congratulations! Your artifact should have finally been uploaded to Maven Central.

8. Use it

In the build.gradle file in your project, add the following if you want to use this package:

repositories {

dependencies {
    compile "com.yourCompany.package:teachUpload-jvm:0.1"

The pattern in our example is: groupId:archiveBaseName:versionNumber

          groupId = com.yourCompany.package
          archiveBaseName = teachUpload-jvm
          versionNumber = 0.1



Hopefully now you get it and everything is set up! Enjoy. 🙂


Stack Memory and Local Variables

In todays languages, every call to a function adds new data to ‘the stack’ in the form of the local data for the function, and the value of where to return to in the program when the function completes.  To understand the stack, it can be useful to understand the problem the stack solves.

  • Subroutines
  • The problem:  PDP-8
  • The stack solves the problem
  • Parameters on the Stack
  • Local Variables on the Stack
  • Stack Overflow
  • Tracing the stack
  • conclusion


Before functions, there were subroutines.  A program was considered as a ‘routines’ and subroutines were effectively sub-programs.  Blocks of code that could be considered logically as a single instruction by the overall program.  Subroutines quickly evolved by the addition of parameters, local variables and then return values to be what we today generally call functions.  Some languages still have both subroutines (functions with no return value) and functions (with a return value), but many languages now simply think of all as functions.

The problem: PDP-8

The PDP-8 computer was designed with an instruction set that enabled ‘subroutines’ without using a stack.  The memory location immediately prior to the first instruction of the subroutine holds the return address, which means there can only be one return address.  The problem with only being able to hold one return address is, what if the subroutine has been call from two or more different places?  The second call will overwrite the return address for the first call.  Consider a routine such as factorial when implemented recursively.  For recursion to be possible, each call of the function must have its own return address.  Factorial 3 requires three calls, each with its own return address.

The stack Solves the problem.

So the stack was introduced as a concept to provide a new set of data for each call.  With a stack, three call allows three return addresses stacked on top of each other on a stack.

The PDP-8 call instruction does the following:

  • calculate return address as  the instruction following the current instruction
  • save the return address at the location called
  • set the program counter to the location following the location called (the location after where the return address was stored)
  • To return, the code jumps to value stored at the call location

A new stack based call would be as follows:

  • calculate return address as  the instruction following the current instruction
  • save the return address at the location of the stack pointer and subtract one from the stack pointer
  • set the program counter to the location called
  • to return, add one to the stack pointer and jump to the location stored at the location pointed to by the stack pointer.

The stack approach, requires the following:

  • An area of memory allocated as ‘the stack’
  • A different ‘call subroutine’ instruction performing the call steps above
  • A stack pointer (which is normally a register of the CPU), set to the base of the stack before any subroutine calls
  • A return instruction performing as described above


Parameters on the Stack

In the real world of modern programs, subroutines also accept parameters.  Consider the factorial equation, and the call requires the number for the factorial as a parameter. Again, it should be considered that there may be more than one call to the subroutine active, so separate storage is required for each call.   The stack again provides the solution. Simply push the parameter onto the stack prior to calling the routine, and within the routine the parameter can be accessed using an offset from the stack pointer.

Local Variables on the Stack.

The next concept was to add ‘local variables’.  From the beginning a subroutine could have a variable in global storage that only that subroutine made use of as a type of ‘local’ variable,  but again the problem of multiple copies of the subroutine would occur with several calls to the function all using the same memory locations for local variables. The solution it to allocate a block of ‘local variable storage’ when the subroutine is called.  At the start of the subroutine, the stack pointer is adjusted by the number of bytes required to reserve memory for local variables, and a reverse adjustment is required at the end of the subroutine.  The diagram here on Wikipedia illustrates a stack where there has been a subroutines call, and then that subroutines has also made a call.

Stack Overflow.

The amount of information on the stack has grown from the original return address.  With the return address, parameters and space for local variables, the amount of stack space used by any given routine can be significant.  Nesting, or the process of one routine calling another, grows the space required for the stack.  Too many levels of nesting, particularly with routines making use of a lot of local storage, and the stack can run out of room or ‘overflow’.  In reality most stack overflows occur as a result of infinite recursion.

Tracing the stack.

During debugging, tracing back through the stack can be the only way to understand complex problems, and a ‘stack trace’ or listing of the stack contents the only way to determine the exact state of a program.


The stack or ‘call stack’, has become an integral part of how functions and subroutines actually operate.  Understanding the call stack is critical to fully understanding how programs work.


Kotlin Limitations vs Python

social-media-failThis page will serve as repository of limitations found when attempting to move kotlin code to python code. Some limitations are a natural consequence of moving to static types, others are effectively inherited from Java.

The list here is based on placing those I find most significant at the top, and the further down the list the less significant.

base class parameter pass through


Kotlin, like python, allows for optional parameters, a feature not found in Java.  A consequence of this feature is that libraries with heavily used classes can over time evolve to have a large number of optional parameters in the most heavily used methods.  A larger number of parameters should only occur in code in a language that has optional parameters, as without the parameters being optional, every extra parameter  would introduce overhead on every call.  These methods with a large number of parameters are often frequently used methods, and the goal is that well chosen defaults will mean that most of these optional parameters are only provided in exceptional cases.  While a typical instance of the class may require only 2 or 3 parameters, while there may be as many as 20 to chose from.

To find examples, I simply thought: “what are the most widely used python packages I can think of?”.  The first three that occurred to me to check were sqlalchemy,  attr, and Django, and for each of these I looked for the most basic usage cases I could find. The first examples I found are:

  • sqlalchemy:   Table Class  20 optional parameters (see ‘parameters’)
  • attr: atrr.s() function – 9 optional parameters (see attr.s function)
  • Django: Field class – 22 optional parameters (see __init__)

While such a large number of parameters should not normally occur in Java due to lack of optional parameters, I think these example establish that the pattern is common in well regarded python packages.

The Problem.

Consider the Django Fieldclass . This class serves as a base class for several other classes, such as  TextField, TimeField, BinaryField etc.  To code examples like these cleanly, some type of language mechanism is needed which effectively achieves:  “include all fields from the base class constructor (or other method from the base class) as also parameters to this class unless specifically declared in this class“.

Python uses the *args,**kwargs system, which for several reasons is not an appropriate solution for kotlin, but is at least a solution.  There are some more elegant solutions possible for kotlin, and perhaps one will be added at a later time.

In Python the code for defining the BinaryField Class is as follows (not exact code for simplicity):

class BinaryField(Field):

    def __init__(self, *args, **kwargs):
        kwargs['editable'] = False
        super().__init__(*args, **kwargs)
        // other init code goes here

while in kotlin (slightly changed for name conventions and simplicity) the code becomes:

class BinaryField(
        verboseName:String?=null, name:String?=null, primaryKey:Boolean=false,
        maxLength:Int?=null, unique:Boolean=false, blank:Boolean=false,
        nulled:Boolean=false, dbIndex:Boolean=false, rel:String?=null,
        default:Any?=null, //editable:Boolean=true, - force 'false' for editable
        uniqueForYear:Int?=null, choices:String?=null, helpText:String="",
        dbColumn:Int?=null, dbTablespace:Int?=null, autoCreated:Boolean=false,
        validators:List<Any>?=null, errorMessages:String?=null
 ):Field(verboseName=verboseName, name=name, primaryKey=primaryKey,
        maxLength=maxLength, unique=unique, blank=blank, nulled=nulled,
        dbIndex=dbIndex, rel=rel, default=default, editable=false,
        serialize=serialize, uniqueForYear=uniqueForYear, choices=choices,
        helpText=helpText, dbColumn=dbColumn,
        dbTablespace=dbTablespace, autoCreated=autoCreated,
        validators=validators, errorMessages=errorMessages) {
  // class code here

Clearly, the call to the base constructor will be much shorter if not using named parameters, which is a choice, but in a list this long I would use named parameters.

The code (or almost identical code) will be repeated TextField, TimeField and the over 12 other fields that inherit from Field. Any update to the parameter list for the base Field class is tedious to say the least.

This is a case where kotlin requires boilerplate that is not required in python. What is needed is some way to say “accept all parameters to the base default constructor not specifically named in the base call, and pass these parameters through“. Given this problem will not occur in Java libraries which have no default parameters, it may be some time before kotlin designers consider this, if ever.  In the mean time, messy.

Constructor Calls

(to be added: by Nov 13)

Intricate, preset order, class data initialisation

Kotlin has what can appear a rather strange way of implementing the overriding of properties when extending classes.  The result is that when extending classes, the behaviour of initcode can be unexpected.  The way to avoid this is to use lazy properties in place of initialising during init.

open class Base{
    val simple = 3
    open val open = 3
    open val openGet = 3
    open val getter get()= 3
    open val getOpen get()= 3
    open val getDelg by GetDelg(3)
    init {
        println("base simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")
    //open fun add(a:Int,b:Int) = a + b

class SubClass:Base(){
    override val open = 4
    override val openGet get()= 4
    override val getter get() = 4
    override val getOpen = 4
    //override val getDelg by GetDelg(4)  //uncomment for null pointer
    init {
        println("sub simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")

class GetDelg(val value:Int){
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return value

The print from instancing a SubClass object is:

base simple 3 open 0 openG 4 getOpen 0 getter 4 getDelg 3
sub simple 3 open 4 openG 4 getOpen 4 getter 4 getDelg 3


Open is 0 in the base class init because the code to set the value has not yet been run, but not it is not 3 as you would expect.

openG, a value overridden by a get() method, perhaps unexpected returns the override value in both init() methods

getOpen, a get() method in the base overridden by a simple initialisation, behaves as a simple initialised value overridden by a new initialise, which is to be unitialised in the base init() method

getter() , a get() method overidden by another get() method returns the override value as does openG

getDelg() actually generates a null pointer exception if called during  the base init() method, as the overridden value has not been calculated

Note: part of this behaviour is base on the fact that overridden properties are actually new distinct properties, so the do not inherit values from base class property which is still accessible via super.<name>.  This means, counterintuitively, that open in the base init() method, returns 0while in the subclass init()will return 3

I will update with more on the use of lazy to avoid this issue, but the main point is to think carefully before initialising values in a base class that are open.

*args, **kwargs (to be added)

A specific use of *args and **kwargs has already been covered in base class parameter pass through.

Outside of that specific use, kotlin does have effective equivalents to most use cases, but may depend on the reflections library, which is not available on all platforms at this time.

vararg parameters capture the equivalent to a *args list, and allows for using the list for calling in a manner very similar to python.

callBy provide most of the functionality of **kwargs when used for calling functions, but some code is needed to map parameter names to KParameters.  A link to such code may be added to this page is someone asks 🙂

For cases where it is desired to capture parameters in map for, using a map actually makes better sense in every case I have found, but I will update this further if I find a case where this is not true.