Some time ago I went to a Meetup session “Death To Null” by Ties van de Ven from JDriven.
During the presentation it became clear that it wasn‘t so much about null checks and NullPointerExceptions but more about Immutability and how it can help keep your software free of bugs and NullPointerExceptions.
One of the statements that got me thinking was (something along the lines of): “Java chose the wrong default.
Instead of making everything explicitly final when we want an immutable variable, everything should be implicitly final unless the developer makes it explicitly mutable”.
Not knowing that much about the implementation of annotations I thought it would be fun to try to write an annotation which would do exactly that.
The first bump I encountered is that annotations cannot modify the programmers source code, or the classes generated from this source code; they can generate new sources or validate code.
This quickly turned my attention to project Lombok which does that already.
If you use project Lombok for the generation of getters and setters these never show up in your source code.
How can your IDE still hint at the existence of the getters and setters?
Continue reading →
We use the model task to see which objects are available in the Gradle model space. The model spaced is managed by Rule based model configuration. Objects can be defined as hidden by the object author(s). By default a hidden object is not shown in the model report. We must use the task option --showHidden to show also the hidden objects in the model report.
$ gradle -q model --showHidden
------------------------------------------------------------
Root project
------------------------------------------------------------
+ buildDir
| Type: java.io.File
| Value: /Users/mrhaki/Projects/sample/build
| Creator: Project..buildDir()
+ extensionContainer
| Type: org.gradle.api.plugins.ExtensionContainer
| Creator: Project..extensionContainer()
+ fileOperations
| Type: org.gradle.api.internal.file.FileOperations
| Creator: DefaultProject.BasicServicesRules#fileOperations(ServiceRegistry)
+ instantiator
| Type: org.gradle.internal.reflect.Instantiator
| Creator: DefaultProject.BasicServicesRules#instantiator(ServiceRegistry)
+ nodeInitializerRegistry
| Type: org.gradle.model.internal.core.NodeInitializerRegistry
| Creator: DefaultProject.BasicServicesRules#nodeInitializerRegistry(ModelSchemaStore, StructBindingsStore)
+ projectIdentifier
| Type: org.gradle.api.internal.project.ProjectIdentifier
| Value: root project 'versionrule'
| Creator: Project..projectIdentifier()
+ proxyFactory
| Type: org.gradle.model.internal.manage.instance.ManagedProxyFactory
| Creator: DefaultProject.BasicServicesRules#proxyFactory(ServiceRegistry)
+ schemaStore
| Type: org.gradle.model.internal.manage.schema.ModelSchemaStore
| Creator: DefaultProject.BasicServicesRules#schemaStore(ServiceRegistry)
+ serviceRegistry
| Type: org.gradle.internal.service.ServiceRegistry
| Value: ProjectScopeServices
| Creator: Project..serviceRegistry()
+ sourceDirectorySetFactory
| Type: org.gradle.api.internal.file.SourceDirectorySetFactory
| Creator: DefaultProject.BasicServicesRules#sourceDirectorySetFactory(ServiceRegistry)
+ structBindingsStore
| Type: org.gradle.model.internal.manage.binding.StructBindingsStore
| Creator: DefaultProject.BasicServicesRules#structBindingsStore(ServiceRegistry)
+ taskFactory
| Type: org.gradle.api.internal.project.taskfactory.ITaskFactory
| Creator: DefaultProject.BasicServicesRules#taskFactory(ServiceRegistry)
+ tasks
| Type: org.gradle.model.ModelMap | Creator: Project..tasks()
| Rules:
⤷ VersionFileTaskRules#createVersionFileTask(ModelMap, VersionFile)
+ buildEnvironment
| Type: org.gradle.api.tasks.diagnostics.BuildEnvironmentReportTask
| Value: task ':buildEnvironment'
| Creator: tasks.addPlaceholderAction(buildEnvironment)
| Rules:
⤷ copyToTaskContainer
+ components
| Type: org.gradle.api.reporting.components.ComponentReport
| Value: task ':components'
| Creator: tasks.addPlaceholderAction(components)
| Rules:
⤷ copyToTaskContainer
+ dependencies
| Type: org.gradle.api.tasks.diagnostics.DependencyReportTask
| Value: task ':dependencies'
| Creator: tasks.addPlaceholderAction(dependencies)
| Rules:
⤷ copyToTaskContainer
+ dependencyInsight
| Type: org.gradle.api.tasks.diagnostics.DependencyInsightReportTask
| Value: task ':dependencyInsight'
| Creator: tasks.addPlaceholderAction(dependencyInsight)
| Rules:
⤷ HelpTasksPlugin.Rules#addDefaultDependenciesReportConfiguration(DependencyInsightReportTask, ServiceRegistry)
⤷ copyToTaskContainer
+ dependentComponents
| Type: org.gradle.api.reporting.dependents.DependentComponentsReport
| Value: task ':dependentComponents'
| Creator: tasks.addPlaceholderAction(dependentComponents)
| Rules:
⤷ copyToTaskContainer
+ generateVersionFile
| Type: mrhaki.gradle.VersionFileTask
| Value: task ':generateVersionFile'
| Creator: VersionFileTaskRules#createVersionFileTask(ModelMap, VersionFile) > create(generateVersionFile)
| Rules:
⤷ copyToTaskContainer
+ help
| Type: org.gradle.configuration.Help
| Value: task ':help'
| Creator: tasks.addPlaceholderAction(help)
| Rules:
⤷ copyToTaskContainer
+ init
| Type: org.gradle.buildinit.tasks.InitBuild
| Value: task ':init'
| Creator: tasks.addPlaceholderAction(init)
| Rules:
⤷ copyToTaskContainer
+ model
| Type: org.gradle.api.reporting.model.ModelReport
| Value: task ':model'
| Creator: tasks.addPlaceholderAction(model)
| Rules:
⤷ copyToTaskContainer
+ projects
| Type: org.gradle.api.tasks.diagnostics.ProjectReportTask
| Value: task ':projects'
| Creator: tasks.addPlaceholderAction(projects)
| Rules:
⤷ copyToTaskContainer
+ properties
| Type: org.gradle.api.tasks.diagnostics.PropertyReportTask
| Value: task ':properties'
| Creator: tasks.addPlaceholderAction(properties)
| Rules:
⤷ copyToTaskContainer
+ tasks
| Type: org.gradle.api.tasks.diagnostics.TaskReportTask
| Value: task ':tasks'
| Creator: tasks.addPlaceholderAction(tasks)
| Rules:
⤷ copyToTaskContainer
+ wrapper
| Type: org.gradle.api.tasks.wrapper.Wrapper
| Value: task ':wrapper'
| Creator: tasks.addPlaceholderAction(wrapper)
| Rules:
⤷ copyToTaskContainer
+ typeConverter
| Type: org.gradle.internal.typeconversion.TypeConverter
| Creator: DefaultProject.BasicServicesRules#typeConverter(ServiceRegistry)
+ versionFile
| Type: mrhaki.gradle.VersionFile
| Creator: VersionFileTaskRules#versionFile(VersionFile)
| Rules:
⤷ versionFile { ... } @ build.gradle line 8, column 5
+ outputFile
| Type: java.io.File
| Value: /Users/mrhaki/Projects/sample/build/version.txt
| Creator: VersionFileTaskRules#versionFile(VersionFile)
+ version
| Type: java.lang.String
| Value: 1.0.1.RELEASE
| Creator: VersionFileTaskRules#versionFile(VersionFile)
$
Continue reading →
The Gradle model task shows the objects in the model space of Gradle. The output shows the object hierarchy. By default a full report is shown, with a lot of information. We can customize the output format with the --format task argument. The default value is full, but we can also use the value short. With the value short a lot less information is shown.
Let's see the output of the model task for a sample project:
Continue reading →
When playing around in Polymer, we encounter iron signals. Besides normal javascript events, this gives us a lot of options for dealing with events. Lets try it all out! We can catch events using the on-event attribute:
1
Continue reading →
In general a REST service serves JSON document formats.
In Spring Boot it is even the standard without having to configure anything.
Over HTTP we have the ability to send a Content-Type as header to instruct the server to return a certain document format (Mime type).
Besides handling JSON, XML is another common document format.
But what if we want to serve or read a YAML document format? This tutorial provides the required steps to be able to handle objects in YAML format.
To be able to send a YAML Content-Type with the header, and to be able to serialize and deserialize with the existing ObjectMappers of Jackson.
This tutorial will use Spring Boot, Jackson and a YAML dataformat extension library for Jackson.
First we need to add the YAML Jackson extension to our Gradle build file.
Continue reading →
Gradle has an incubating feature Rule based model configuration.
This is a new way to configure Gradle projects where Gradle has more control of the configuration and the dependencies between configuration objects.
This allows Gradle to resolve configuration values before they are used, because Gradle knows there is a dependency.
With this new model we don't need any lazy evaluation "tricks" we had to use.
For example there was an internal convention mapping mechanism for tasks to assign values to a task configuration after the task was already created.
Also the project.afterEvalute is a mechanism to have late binding for task properties.
With the new rule based model Gradle can do without these options, we can rely on Gradle resolving all dependent configuration values when we create a task.
In Gradle we already know about the "project space" where the Project object is the root of the object graph.
For example repositories are part of the project space. Gradle can get some useful information from the project space, but it is mostly a graph of objects that Gradle only partially can reason about.
Then we have the "model space".
This is part of a project and we can use it in our build script with the model configuration block.
The model space is separate from the project space and contains objects that are managed by Gradle.
Gradle knows dependencies between the objects and how to create and change them.
This helps Gradle to optimise build logic.
To help Gradle we must define rules to work with objects in the model space.
Each rule is like a recipe for Gradle on how to work with the model.
Gradle can build a graph of models and know about dependencies between models.
This way Gradle guarantees that model objects are completely configured before being used.
For example if a rule needs a VersionFile model configuration object then Gradle makes sure that the VersionFile is created and all properties are set.
So we don't need any lazy or late binding anymore, because the properties will be set (Gradle makes sure) when we want to use them.
The rules are defined a class that extends RuleSource.
Such a class is stateless and only contains methods to work with the model objects.
Gradle has some specific annotations that can be used on methods to indicate what a method should do.
Continue reading →
Asciidoctor is a Ruby tool, but luckily we can use AsciidoctorJ to use Asciidoctor in Java code.
The Asciidoctor Gradle plugin relies on AsciidoctorJ to run.
AsciidoctorJ allows us to write custom extensions in Java (or Groovy), but we can still use Asciidoctor extensions written in Ruby with the Gradle plugin.
In the following example we use the emoji-inline-macro from Asciidoctor extensions lab.
This is an extension written in Ruby. We create a new directory for our sample and create a lib folder.
Inside the lib directory we copy the file emoji-inline-macro.rb and the supporting directory emoji-inline-macro.
These files are all in the Asciidoctor extensions lab repository.
After we have copied the files we should have the following structure:
Continue reading →
To apply a plugin in our Gradle build script we can use the plugins DSL.
The plugins DSL is very concise and allows Gradle to be more efficient and more in control when loading the plugin.
Normally the plugin we define is fetched from the Gradle plugin portal.
If we have our own repository, for example on the intranet of our company, we have to define that extra repository with a pluginRepositories configuration block in the settings.gradle file of our project.
In the following sample we have a plugin mrhaki.gradle.version-file that is stored in the company intranet repository with the URL http://intranet/artifactory/libs-release/.
Continue reading →
This is the first of a series of posts.
Where we will use machine learning to rate movies.
For this task we're not going to watch all the movies.
I assume it's good enough to just read the plot.
We'll use Markov chains to rate the movies and as an added bonus we can also generate new movie plots for awesome (or terrible) movies.
In this first part we'll get the data and change it into a more usable format.
We can use the data from IMDB, which is published on ftp://ftp.fu-berlin.de/pub/misc/movies/database/.
Of interest are the plots and the ratings.
Plots look like this:
Continue reading →
The Pair class in Ratpack is an easy way to create a growing data structure, passed on via Promise methods.
A Pair object has a left and right part containing data.
These parts can even be other Pair objects.
Since Ratpack 1.4.0 the Promise class has methods to set the right or left part of a Pair: left, flatLeft, right and flatRight.
The result of these methods is a Promise<Pair> object.
The input can be Promise type or a Function that can use a previous Promise.
In the following example specification we use the different new methods to create a Pair.
We also create a simple Ratpack server with a asynchronous HTTP client implementation to simulate remote calls returning a Promise:
Continue reading →