Skip to content

Commit

Permalink
Enh 35200808 - [35160572->23.09] Provide a Gradle alternative for Coh…
Browse files Browse the repository at this point in the history
…erence POF Maven plugin

This commit includes the following changes:

99264 - COH-25991 - Fix Gradle POF plugin to build on Windows
99206 - Fix 905-key-association example Coherence Maven POF Plugin dependency
99202 - COH-25991 - Polish Gradle build, tests and Maven integration
99176 - COH-25991 - Provide a Gradle alternative for Coherence POF Maven plugin

[git-p4: depot-paths = "//dev/coherence-ce/main/": change = 99369]
  • Loading branch information
ghillert committed Mar 21, 2023
1 parent bf18617 commit 965ea2c
Show file tree
Hide file tree
Showing 37 changed files with 2,664 additions and 13 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
target
dist
_package
build/

#ignore these specific files
dependency-reduced-pom.xml
Expand All @@ -30,5 +31,3 @@ dependency-reduced-pom.xml
!.gitignore
!prj/.mvn
!prj/.mvn/**


8 changes: 8 additions & 0 deletions prj/coherence-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
<maven.assembly.plugin.version>3.0.0</maven.assembly.plugin.version>
<maven.build.helper.plugin.version>1.8</maven.build.helper.plugin.version>
<maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
<maven.clean.plugin.version>3.2.0</maven.clean.plugin.version>
<maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
<maven.dependency.plugin.version>2.8</maven.dependency.plugin.version>
<maven.dependency-check.plugin.version>8.1.1</maven.dependency-check.plugin.version>
Expand Down Expand Up @@ -1240,6 +1241,13 @@
</executions>
</plugin>

<!-- maven-clean-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven.clean.plugin.version}</version>
</plugin>

<!-- maven-compiler-plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
8 changes: 5 additions & 3 deletions prj/examples/guides/905-key-association/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/*
* Copyright (c) 2000, 2022 Oracle and/or its affiliates.
* Copyright (c) 2023 Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/

plugins {
id 'java'
id 'com.oracle.coherence' version "${coherenceVersion}"
id 'com.github.vlsi.jandex' version "${jandexPluginVersion}"
}

group = 'com.oracle.coherence.guides'
Expand All @@ -27,9 +29,9 @@ dependencies {
testImplementation "org.hamcrest:hamcrest:${hamcrestVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
testImplementation "org.junit.jupiter:junit-jupiter-params:${junitVersion}"
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}

test {
useJUnitPlatform()
}
}
3 changes: 2 additions & 1 deletion prj/examples/guides/905-key-association/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2000, 2022, Oracle and/or its affiliates.
# Copyright (c) 2000, 2023, Oracle and/or its affiliates.
#
# Licensed under the Universal Permissive License v 1.0 as shown at
# https://oss.oracle.com/licenses/upl.
Expand All @@ -11,5 +11,6 @@ coherenceVersion=23.09-SNAPSHOT
# or com.oracle.coherence for the Commercial Edition
coherenceGroupId=com.oracle.coherence.ce

jandexPluginVersion=1.86
junitVersion=5.8.2
hamcrestVersion=2.2
6 changes: 3 additions & 3 deletions prj/examples/guides/905-key-association/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Licensed under the Universal Permissive License v 1.0 as shown at
https://oss.oracle.com/licenses/upl.
Expand Down Expand Up @@ -85,9 +85,9 @@
<build>
<plugins>
<plugin>
<groupId>com.oracle.coherence.ce</groupId>
<groupId>${coherence.group.id}</groupId>
<artifactId>pof-maven-plugin</artifactId>
<version>22.06</version>
<version>${project.version}</version>
<executions>
<execution>
<id>instrument</id>
Expand Down
12 changes: 10 additions & 2 deletions prj/examples/guides/905-key-association/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/

rootProject.name = 'key-association'
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}

rootProject.name = 'key-association'

269 changes: 269 additions & 0 deletions prj/plugins/gradle/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
:coherence-gradle-plugin-version: 23.09-SNAPSHOT
:com-github-vlsi-jandexm-version: 1.86
:org-kordamp-gradle-jandex-version: 0.13.2

= POF Gradle Plugin

The POF Gradle Plugin provides automated instrumentation of classes with the `@PortableType` annotation to generate
consistent (and correct) implementations of Evolvable POF serialization methods.

It is a far from a trivial exercise to manually write serialization methods that support serializing inheritance
hierarchies that support the Evolvable concept. However, with static type analysis these methods can be deterministically
generated.

This allows developers to focus on business logic rather than implementing boilerplate code for the above-mentioned
methods.

NOTE: Please see
https://docs.oracle.com/en/middleware/standalone/coherence/14.1.1.2206/develop-applications/using-portable-object-format.html#GUID-25206CEF-3271-494C-B43A-066A84E6B1BD[Portable Types documentation]
for more information and detailed instructions on Portable Types creation and usage.

== Usage

In order to use the POF Gradle Plugin, you need to declare it as a plugin dependency in your `build.gradle` file:

[source,groovy]
----
plugins {
id 'java'
id 'com.oracle.coherence.ce'
}
----

Without any further configuration, the plugin will add a task named `coherencePof` to your project. The `coherencePof`
task will be executed at the end of the `compileJava` task. At the same time, `coherencePof` also depends on the `compileJava` task.

Therefore, calling:

[source,bash]
----
gradle compileJava
----

will execute the `coherencePof` task. And similarly:

[source,bash]
----
gradle coherencePof
----

will execute the `compileJava` task first. By *default*, the `coherencePof` task will take the *build output directory* as
input for classes to be instrumented excluding any test classes.

By just adding the plugin using the configuration above, the Coherence Gradle Plugin will discover and instrument all
project classes annotated with the `@PortableType` annotation, excluding test classes. If you do need to instrument test
classes, you can add the `coherencePof` closure and provide additional configuration properties.

=== Custom Configuration

The default behavior of the Coherence Gradle Plugin, can be customized using several optional properties. Simply provide
a `coherencePof` closure to your `build.gradle` script containing any additional configuration properties, e.g.:

.Build.gradle
[source,groovy]
----
coherencePof {
debug=true // <1>
}
----
<1> This will instruct Coherence to provide more logging output in regard to the instrumented classes

=== Available Configuration Properties

==== Enable Debugging

Set the boolean `debug` property to `true` in order to instruct the underlying `PortableTypeGenerator` to generate debug
code in regards the instrumented classes.

If not specified, this property _defaults_ to `false`.


==== Instrumentation of Test Classes

Set the boolean `instrumentTestClasses` property to `true` in order to instrument test classes.
If not specified, this property _defaults_ to `false`.

==== Set a Custom TestClassesDirectory

Provide a path to a custom test classes directory using property `testClassesDirectory`. If not set, it will default
to the default test output directory.

==== Set a Custom MainClassesDirectory

Provide a path to a custom classes directory using property `mainClassesDirectory`. If not set, it will default
to the default output directory.

=== What about classes without the @PortableType annotation?

In some cases, it may be necessary to expand the type system with the types that are not annotated with the
`@PortableType` annotation, and are not discovered automatically. This is typically the case when some of your portable
types have `enum` values, or existing classes that implement the `PortableObject` interface explicitly as attributes.

You can add those types to the schema by creating a `META-INF/schema.xml` file and specifying them explicitly. For example,
if you assume that the `Color` class from the earlier code examples:

.META-INF/schema.xml
[source,xml]
----
<?xml version="1.0"?>
<schema xmlns="http://xmlns.oracle.com/coherence/schema"
xmlns:java="http://xmlns.oracle.com/coherence/schema/java" external="true">
<type name="Color">
<java:type name="petstore.Color"/>
</type>
</schema>
----

== Jandex Index

The portable type discovery feature of Coherence depends on the availability of a
https://github.com/smallrye/jandex[Jandex] index within the modules that provide portable types that need to be registered.

Therefore, in order to use POF instrumented classes at compile-time in your Gradle project, you should also add a
Jandex Gradle plugin. As Oracle Coherence uses Jandex 2 under the covers, there are 2 options available:

- https://github.com/vlsi/vlsi-release-plugins
- https://github.com/kordamp/jandex-gradle-plugin (Only versions `< 1.0.0` as recent versions use Jandex 3)

.Build.gradle
[source,groovy,subs="normal"]
----
plugins {
id 'java'
id 'com.oracle.coherence.ce' version '{coherence-gradle-plugin-version}'
id 'com.github.vlsi.jandex' version '{com-github-vlsi-jandex-version}'
}
----

.Build.gradle
[source,groovy,subs="normal"]
----
plugins {
id 'java'
id 'com.oracle.coherence.ce' version '{coherence-gradle-plugin-version}'
id 'org.kordamp.gradle.jandex' version '{org-kordamp-gradle-jandex-version}'
}
----

== Example

An example `Person` class (below) when processed with the plugin, results in the bytecode shown below.

.Person.java
[source,java]
----
@PortableType(id=1000)
public class Person
{
public Person()
{
}
public Person(int id, String name, Address address)
{
super();
this.id = id;
this.name = name;
this.address = address;
}
int id;
String name;
Address address;
// getters and setters omitted for brevity
}
----

Let's inspect the generated bytecode:

[source,bash]
----
javap Person.class
----

This should yield the following output:

[source,java]
----
public class demo.Person implements com.tangosol.io.pof.PortableObject,com.tangosol.io.pof.EvolvableObject {
int id;
java.lang.String name;
demo.Address address;
public demo.Person();
public demo.Person(int, java.lang.String, demo.Address);
public int getId();
public void setId(int);
public java.lang.String getName();
public void setName(java.lang.String);
public demo.Address getAddress();
public void setAddress(demo.Address);
public java.lang.String toString();
public int hashCode();
public boolean equals(java.lang.Object);
public void readExternal(com.tangosol.io.pof.PofReader) throws java.io.IOException; // <1>
public void writeExternal(com.tangosol.io.pof.PofWriter) throws java.io.IOException;
public com.tangosol.io.Evolvable getEvolvable(int);
public com.tangosol.io.pof.EvolvableHolder getEvolvableHolder();
}
----
<1> Additional methods generated by Coherence POF plugin.

=== Skip Execution

You can skip the execution of the `coherencePof` task by running the Gradle build using the `-x` flag, e.g.:

[source,bash]
----
gradle clean build -x coherencePof
----

== Development

During development, it is extremely useful to rapidly test the plugin code against separate example projects. For this,
we can use Gradle's https://docs.gradle.org/current/userguide/composite_builds.html[composite build] feature. Therefore,
the Coherence POF Gradle Plugin module itself provides a separate `sample` module. From within
the sample directory you can execute:

[source,bash]
----
gradle clean compileJava --include-build ../plugin
----

This will not only build the sample but will also build the plugin and developers can make plugin code changes and see
changes rapidly reflected in the execution of the sample module.

Alternatively, you can build and install the Coherence Gradle plugin to your local Maven repository using:

[source,bash]
----
gradle publishToMavenLocal
----

For projects to pick up the local changes ensure the following configuration:

.Build.gradle
[source,groovy,subs="normal"]
----
plugins {
id 'java'
id 'com.oracle.coherence.ce' version '{coherence-gradle-plugin-version}'
id 'com.github.vlsi.jandex' version '{com-github-vlsi-jandex-version}'
}
----

.Settings.gradle
[source,groovy,subs="normal"]
----
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
----

Loading

0 comments on commit 965ea2c

Please sign in to comment.