Skip to content

SPI 3 Refactoring#2382

Draft
chrisdutz wants to merge 76 commits intodevelopfrom
refactor/spi3
Draft

SPI 3 Refactoring#2382
chrisdutz wants to merge 76 commits intodevelopfrom
refactor/spi3

Conversation

@chrisdutz
Copy link
Copy Markdown
Contributor

In this refactoring, we are replacing the existing Netty-based core into a set of lightweight sub-modules without requiring Netty at all and with as little third party dependencies as possible.

This will allow using our code-generation framework independently from building PLC4J drivers and allow porting PLC4X to other languages as we no longer rely on external libraries for which counterparts need to be integrated for new languages.

@chrisdutz chrisdutz marked this pull request as draft December 8, 2025 08:47
default:
return boxSideBySide(boxes.get(0), mergeHorizontal(new ArrayList<>(boxes).subList(1, boxes.size())));
}
return switch (boxes.size()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really like the new syntax... :)

dependabot bot and others added 21 commits January 12, 2026 12:22
…2381)

Bumps [org.sonarsource.scanner.maven:sonar-maven-plugin](https://github.com/SonarSource/sonar-scanner-maven) from 5.4.0.6343 to 5.5.0.6356.
- [Release notes](https://github.com/SonarSource/sonar-scanner-maven/releases)
- [Commits](SonarSource/sonar-scanner-maven@5.4.0.6343...5.5.0.6356)

---
updated-dependencies:
- dependency-name: org.sonarsource.scanner.maven:sonar-maven-plugin
  dependency-version: 5.5.0.6356
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
….0 (#2380)

Bumps [org.apache.commons:commons-text](https://github.com/apache/commons-text) from 1.14.0 to 1.15.0.
- [Changelog](https://github.com/apache/commons-text/blob/master/RELEASE-NOTES.txt)
- [Commits](apache/commons-text@rel/commons-text-1.14.0...rel/commons-text-1.15.0)

---
updated-dependencies:
- dependency-name: org.apache.commons:commons-text
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.google.googlejavaformat:google-java-format](https://github.com/google/google-java-format) from 1.32.0 to 1.33.0.
- [Release notes](https://github.com/google/google-java-format/releases)
- [Commits](google/google-java-format@v1.32.0...v1.33.0)

---
updated-dependencies:
- dependency-name: com.google.googlejavaformat:google-java-format
  dependency-version: 1.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…2386)

Bumps [golang.org/x/net](https://github.com/golang/net) from 0.47.0 to 0.48.0.
- [Commits](golang/net@v0.47.0...v0.48.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.48.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#2385)

Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.39.0 to 0.40.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](golang/tools@v0.39.0...v0.40.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-version: 0.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.igormaznitsa:gosdk-wrapper-maven-plugin](https://github.com/raydac/gosdk-wrapper-maven-plugin) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/raydac/gosdk-wrapper-maven-plugin/releases)
- [Changelog](https://github.com/raydac/gosdk-wrapper-maven-plugin/blob/main/CHANGELOG.md)
- [Commits](raydac/gosdk-wrapper-maven-plugin@1.1.1...1.1.2)

---
updated-dependencies:
- dependency-name: com.igormaznitsa:gosdk-wrapper-maven-plugin
  dependency-version: 1.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `mockito.version` from 5.20.0 to 5.21.0.

Updates `org.mockito:mockito-core` from 5.20.0 to 5.21.0
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](mockito/mockito@v5.20.0...v5.21.0)

Updates `org.mockito:mockito-junit-jupiter` from 5.20.0 to 5.21.0
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](mockito/mockito@v5.20.0...v5.21.0)

---
updated-dependencies:
- dependency-name: org.mockito:mockito-core
  dependency-version: 5.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.mockito:mockito-junit-jupiter
  dependency-version: 5.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps com.gradle:develocity-maven-extension from 2.2.1 to 2.3.

---
updated-dependencies:
- dependency-name: com.gradle:develocity-maven-extension
  dependency-version: '2.3'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/apache/maven-release/releases)
- [Commits](apache/maven-release@maven-release-3.3.0...maven-release-3.3.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-release-plugin
  dependency-version: 3.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [io.vavr:vavr](https://github.com/vavr-io/vavr) from 0.10.7 to 0.11.0.
- [Release notes](https://github.com/vavr-io/vavr/releases)
- [Commits](vavr-io/vavr@v0.10.7...v0.11.0)

---
updated-dependencies:
- dependency-name: io.vavr:vavr
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](actions/cache@v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps `logback.version` from 1.5.21 to 1.5.22.

Updates `ch.qos.logback:logback-classic` from 1.5.21 to 1.5.22
- [Release notes](https://github.com/qos-ch/logback/releases)
- [Commits](qos-ch/logback@v_1.5.21...v_1.5.22)

Updates `ch.qos.logback:logback-core` from 1.5.21 to 1.5.22
- [Release notes](https://github.com/qos-ch/logback/releases)
- [Commits](qos-ch/logback@v_1.5.21...v_1.5.22)

---
updated-dependencies:
- dependency-name: ch.qos.logback:logback-classic
  dependency-version: 1.5.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: ch.qos.logback:logback-core
  dependency-version: 1.5.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.testcontainers:testcontainers](https://github.com/testcontainers/testcontainers-java) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](testcontainers/testcontainers-java@2.0.2...2.0.3)

---
updated-dependencies:
- dependency-name: org.testcontainers:testcontainers
  dependency-version: 2.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.21.3 to 1.21.4.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](testcontainers/testcontainers-java@1.21.3...1.21.4)

---
updated-dependencies:
- dependency-name: org.testcontainers:junit-jupiter
  dependency-version: 1.21.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps org.apache.karaf.tooling:karaf-maven-plugin from 4.4.8 to 4.4.9.

---
updated-dependencies:
- dependency-name: org.apache.karaf.tooling:karaf-maven-plugin
  dependency-version: 4.4.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.jetbrains.kotlin:kotlin-stdlib](https://github.com/JetBrains/kotlin) from 2.2.21 to 2.3.0.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](JetBrains/kotlin@v2.2.21...v2.3.0)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…12 (#2401)

Bumps org.apache.maven:maven-artifact from 3.9.11 to 3.9.12.

---
updated-dependencies:
- dependency-name: org.apache.maven:maven-artifact
  dependency-version: 3.9.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…tor/spi3

# Conflicts:
#	.mvn/extensions.xml
#	plc4go/go.mod
#	plc4go/go.sum
#	plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultNettyPlcConnection.java
#	plc4j/spi/src/test/java/org/apache/plc4x/java/spi/connection/SingleProtocolStackConfigurerTest.java
#	pom.xml
@splatch
Copy link
Copy Markdown
Contributor

splatch commented Feb 22, 2026

@chrisdutz I see a change in generated code, but I can't see any changes around transports SPI. If I understand correctly main point of this pull request is to update plc4j-spi to not rely on netty to initialize client. Do you have a separate branch for that work? Frame representations we generated before and with above changes interact only with (Reader/Writer)Buffer, thus this PR does not touch netty part yet. I believe we still need other half of the changes.

@chrisdutz
Copy link
Copy Markdown
Contributor Author

Hmmm ... that's odd ... I think this PR has become so big GitHub can't show it anymore ... if you have a look at https://github.com/apache/plc4x/tree/refactor/spi3/plc4j/transports ... it's there.

@chrisdutz
Copy link
Copy Markdown
Contributor Author

image

@splatch
Copy link
Copy Markdown
Contributor

splatch commented Feb 22, 2026

Yeah, github UI couldn't get more than 3000 files, transports fall apart from diff. Will have a look on them!

@sruehl
Copy link
Copy Markdown
Contributor

sruehl commented Mar 20, 2026

Changes look good, awesome work, keep them coming :)

@chrisdutz
Copy link
Copy Markdown
Contributor Author

I've just pushed a first port of the Modbus driver to the new SPI3 ... please have a look and leave some feedback here. I'm now going to pause for a few days so you all have time to review and reply.

@sruehl sruehl requested a review from Copilot April 14, 2026 07:11
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 4911 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<groupId>org.apache.plc4x</groupId>
<artifactId>plc4x-code-generation-language-java</artifactId>
<version>0.14.0-SNAPSHOT</version>
<artifactId>plc4x-code-generation-language-java-jp</artifactId> <version>0.14.0-SNAPSHOT</version>
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is not valid XML because <artifactId> and <version> are on the same line as two separate elements, which will break Maven parsing. Split this into separate properly-indented <artifactId> and <version> lines.

Suggested change
<artifactId>plc4x-code-generation-language-java-jp</artifactId> <version>0.14.0-SNAPSHOT</version>
<artifactId>plc4x-code-generation-language-java-jp</artifactId>
<version>0.14.0-SNAPSHOT</version>

Copilot uses AI. Check for mistakes.
Comment on lines +661 to +688
case "List": {
if (typeReference.isArrayTypeReference() && typeReference.asArrayTypeReference().orElseThrow().getElementTypeReference().isByteBased()) {
return CodeBlock.of("_value.getRaw()");
} else if (typeReference.isArrayTypeReference()) {
ArrayTypeReference arrayTypeReference = typeReference.asArrayTypeReference().orElseThrow();
TypeReference elementTypeReference = arrayTypeReference.getElementTypeReference();
TypeName languageTypeNameForTypeReference = getLanguageTypeNameForTypeReference(elementTypeReference, true);
String typeName = StaticHelper.CAPITALIZE(languageTypeNameForTypeReference.toString());
if (languageTypeNameForTypeReference.equals(TypeName.get(BigInteger.class))) {
typeName = "BigInteger";
} else if (languageTypeNameForTypeReference.equals(TypeName.get(String.class))) {
typeName = "String";
}
//_value.getList().stream().map(PlcValue::getBoolean).collect(Collectors.toList())
return CodeBlock.of("_value.getList().stream().map($T::get$L).collect($T.toList())", PlcValue.class, typeName, Collectors.class);
}
}
case "Struct": {
// _value.getStruct().get("control").getBoolean()
CodeBlock typeName = CodeBlock.of("Struct");
if ((typeReference != null) && typeReference.isArrayTypeReference() && typeReference.asArrayTypeReference().orElseThrow().getElementTypeReference().isByteBased()) {
typeName = CodeBlock.of("Raw");
} else if ((typeReference != null) && typeReference.isSimpleTypeReference()) {
TypeName languageTypeNameForTypeReference = getLanguageTypeNameForTypeReference(typeReference.asSimpleTypeReference().orElseThrow(), true);
typeName = CodeBlock.of("$L", StaticHelper.CAPITALIZE(languageTypeNameForTypeReference.toString()));
}
return CodeBlock.of("_value.getStruct().get($S).get$L()", fieldName, typeName);
}
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In getGetValueBlockForCase, the case \"List\" block can fall through into case \"Struct\" when typeReference is not an array type (no return/break at the end of the List case). This will generate incorrect accessors for list values. Additionally, building typeName via languageTypeNameForTypeReference.toString() can produce fully-qualified names (e.g., java.lang.Integer) which would generate invalid getter calls like PlcValue::getJava.lang.Integer. Add an explicit return/fallback for non-array lists, and derive the getter suffix from a controlled mapping (e.g., based on PlcValueType or ClassName.simpleName() with special-cases for primitives/wrappers) instead of TypeName.toString().

Copilot uses AI. Check for mistakes.
Comment on lines +369 to +376
CodeBlock getValueBlock = CodeBlock.of("$L", field.asNamedField().orElse(() -> "unnamed").getName());
switch (field.getTypeName()) {
case "array": {
generateArrayField(complexTypeDefinition, field, fieldIndex, allParserArguments.orElse(Collections.emptyList()), getValueBlock, getValueBlock, codeBlocksParse, codeBlocksSerialize, codeBlocksGetLengthInBits);
if (field.asArrayField().orElseThrow().getType().asArrayTypeReference().orElseThrow().getElementTypeReference().isByteBased()) {
constructorArgs.put(field.asNamedField().orElse(() -> "unnamed").getName(), ArrayTypeName.of(TypeName.BYTE));
} else {
constructorArgs.put(field.asNamedField().orElse(() -> "unnamed").getName(), getFieldTypeClassName(field));
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional.orElse(...) expects a NamedField value, but this passes a lambda () -> \"unnamed\", which won’t compile (and then calls .getName() on the lambda). Use field.asNamedField().map(NamedField::getName).orElse(\"unnamed\") (or similar) to safely obtain the name string.

Suggested change
CodeBlock getValueBlock = CodeBlock.of("$L", field.asNamedField().orElse(() -> "unnamed").getName());
switch (field.getTypeName()) {
case "array": {
generateArrayField(complexTypeDefinition, field, fieldIndex, allParserArguments.orElse(Collections.emptyList()), getValueBlock, getValueBlock, codeBlocksParse, codeBlocksSerialize, codeBlocksGetLengthInBits);
if (field.asArrayField().orElseThrow().getType().asArrayTypeReference().orElseThrow().getElementTypeReference().isByteBased()) {
constructorArgs.put(field.asNamedField().orElse(() -> "unnamed").getName(), ArrayTypeName.of(TypeName.BYTE));
} else {
constructorArgs.put(field.asNamedField().orElse(() -> "unnamed").getName(), getFieldTypeClassName(field));
String fieldName = field.asNamedField().map(NamedField::getName).orElse("unnamed");
CodeBlock getValueBlock = CodeBlock.of("$L", fieldName);
switch (field.getTypeName()) {
case "array": {
generateArrayField(complexTypeDefinition, field, fieldIndex, allParserArguments.orElse(Collections.emptyList()), getValueBlock, getValueBlock, codeBlocksParse, codeBlocksSerialize, codeBlocksGetLengthInBits);
if (field.asArrayField().orElseThrow().getType().asArrayTypeReference().orElseThrow().getElementTypeReference().isByteBased()) {
constructorArgs.put(fieldName, ArrayTypeName.of(TypeName.BYTE));
} else {
constructorArgs.put(fieldName, getFieldTypeClassName(field));

Copilot uses AI. Check for mistakes.
String parentTypeName = complexTypeDefinition.getParentType().orElseThrow().getName();
// Add the builder implementation
TypeSpec.Builder builderImplementationBuilder = TypeSpec.classBuilder(parentTypeName + "BuilderImpl")
.addSuperinterface(ClassName.get(targetPackage, parentTypeName + "." + parentTypeName + "Builder"))
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attempts to create a ClassName using a dotted name in the 'simple name' position (\"Parent.ParentBuilder\"). JavaPoet ClassName.get(package, className) is for top-level types and generally does not accept dots in the class name; it can produce invalid output or throw at runtime. Use ClassName.get(targetPackage, parentTypeName).nestedClass(parentTypeName + \"Builder\") (or ClassName.get(targetPackage, parentTypeName, parentTypeName + \"Builder\")) to reference the nested builder interface correctly.

Suggested change
.addSuperinterface(ClassName.get(targetPackage, parentTypeName + "." + parentTypeName + "Builder"))
.addSuperinterface(ClassName.get(targetPackage, parentTypeName).nestedClass(parentTypeName + "Builder"))

Copilot uses AI. Check for mistakes.
# specific language governing permissions and limitations
# under the License.
#
org.apache.plc4x.codegeneration.language.java.JavaLanguageOutput
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The java-jp module registers org.apache.plc4x.codegeneration.language.java.JavaLanguageOutput, which strongly suggests it shares the same fully-qualified class name as the existing code-generation/language/java implementation. If both artifacts end up on the classpath, this becomes a classpath collision (one class shadows the other) and can make ServiceLoader behavior non-deterministic. Consider renaming the package and/or the implementation class for the JavaPoet variant (e.g., ...language.java.jp.JavaPoetLanguageOutput) and updating this service entry accordingly to ensure both variants can coexist safely during the migration.

Copilot uses AI. Check for mistakes.
.addModifiers(Modifier.PUBLIC)
.addJavadoc("Code generated by code-generation. DO NOT EDIT.\n");

// Generate some java constants for holing their values
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'holing' to 'holding'.

Suggested change
// Generate some java constants for holing their values
// Generate some java constants for holding their values

Copilot uses AI. Check for mistakes.
// Write to the configured output root directory; JavaPoet will create package folders.
javaFile.writeTo(outputRootDir);
} catch (IOException e) {
LOGGER.error("Error generating enum {}", dataIoTypeDefinition.getName(), e);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log message says "Error generating enum" but this generator is producing a DataIo type. Update the message to reflect the actual generated artifact (e.g., "data-io"/"DataIo type") to make failures diagnosable.

Suggested change
LOGGER.error("Error generating enum {}", dataIoTypeDefinition.getName(), e);
LOGGER.error("Error generating DataIo type {}", dataIoTypeDefinition.getName(), e);

Copilot uses AI. Check for mistakes.
// Write to the configured output root directory; JavaPoet will create package folders.
javaFile.writeTo(outputRootDir);
} catch (IOException e) {
LOGGER.error("Error generating enum {}", complexTypeDefinition.getName(), e);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log message says "Error generating enum" but this generator is producing a complex type. Adjust the message to "Error generating complex type" (or similar) for accurate diagnostics.

Suggested change
LOGGER.error("Error generating enum {}", complexTypeDefinition.getName(), e);
LOGGER.error("Error generating complex type {}", complexTypeDefinition.getName(), e);

Copilot uses AI. Check for mistakes.
// Write to the configured output root directory; JavaPoet will create package folders.
javaFile.writeTo(outputRootDir);
} catch (IOException e) {
LOGGER.error("Error generating enum {}", constantsTypeDefinition.getName(), e);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log message says "Error generating enum" but this generator is producing a constants type. Update the message to match what’s being generated to avoid confusion during troubleshooting.

Suggested change
LOGGER.error("Error generating enum {}", constantsTypeDefinition.getName(), e);
LOGGER.error("Error generating constants type {}", constantsTypeDefinition.getName(), e);

Copilot uses AI. Check for mistakes.
@sruehl
Copy link
Copy Markdown
Contributor

sruehl commented Apr 14, 2026

wow awesome work @chrisdutz. Going through the changes, CoPilot also found some interessting things, but one thing that jumped to my eye was the use of the package name functions. I would propose to name it operations to not confuse it with functions used in programming.

@chrisdutz
Copy link
Copy Markdown
Contributor Author

I just took the liberty to run the manual test benchmark in both the old and the new driver:

Old driver:

=== Test Summary ===
Single Item:
  Average Read Time:  13,80 ms (15 requests, 207 ms total)
  Average Write Time: 12,00 ms (15 requests, 180 ms total)
  Average Time:       12,90 ms
Multi Item (each 15 items):
  Average Read Time:  11,81 ms (100 requests, 1181 ms total)
  Average Write Time: 175,98 ms (100 requests, 17598 ms total)
  Average Time:       93,90 ms
======================
Test executed in 21570ms

New driver:

=== Test Summary ===
Protocol:  Modbus TCP (modbus-tcp)
Transport: TCP (tcp)
Single Item:
  Average Read Time:  14,60 ms (15 requests, 219 ms total)
  Average Write Time: 11,53 ms (15 requests, 173 ms total)
  Average Time:       13,07 ms
#Multi Item (each 15 items):
  Average Read Time:  16,47 ms (100 requests, 1647 ms total)
  Average Write Time: 174,59 ms (100 requests, 17459 ms total)
  Average Time:       95,53 ms
======================
Test executed in 19863ms

The new connection handling is quite a bit faster than the old Netty version. However, I see the new driver is in average 1ms/request slower ... will look into what I could do in order to improve that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants