Using XStream with a modular application?

28 views
Skip to first unread message

Lee Carver

unread,
Jun 22, 2023, 3:40:53 PM6/22/23
to XStream User
I've happily used XStream with some Java 8 applications, and was looking forward to including it as a component of new Java 17 application.  The new application has all of it's components baked into named modules.

With Gradle, I can add the XStream class path dependency in an implementation clause.

But how do I get the modularized application code to create and manipulate XStream objects?  If I understand the JPMS definitions, these types are entirely inaccessible to modular components.  Previously, each application type (now modularized) would configure XStream with the relevant details.  I'm missing how to use that code organization with the existing XStream structures.

It would be very sad if the new program had to give up using modules.

Jörg Schaible

unread,
Jun 23, 2023, 1:38:34 PM6/23/23
to XStream User
Hi Lee,
If you put XStream on the module path, you have to open all modules to it that
contain class types XStream processes with reflection. You can open your own
modules to module xstream in the module-info. However, XStream also accesses
some stuff in the modules of the java runtime. Those will have to be opened too
when you start your application using options for the JVM.

Look at common apps like Tomcat or Eclipse, that will open also some modules
at start time.

Regards,
Jörg


Lee Carver

unread,
Jul 20, 2023, 5:09:51 PM7/20/23
to XStream User
I’m still trying to figure out how to use XStream with Java modules.  As soon as I start using the JPMS’s module features for a project, the XStream data types become unavailable to the project.  What magic spell am I missing?

I think I understand the --add-opens trick that allows XStream to use reflection for serializing data in a running JVM, but how do I get XStream dependent code to compile in the first place?

For very simple test code

package demo.xstream;

import com.thoughtworks.xstream.XStream;

public class Test {

  private XStream xstream;

  public Test(XStream xstream) {
    this.xstream = xstream;
  }
}


This compiles fine (./gradlew build) with the necessary Gradle instructions.

plugins {
  id 'java'
}

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.thoughtworks.xstream:xstream:1.4.20'
}



If I attempt to package the demo as a module, and add a module definition file (module-info.java), the Test class no longer compiles.

module demo.xstream {
  requires xstream;
}



There are multiple compilation errors:

Test.java: the imported package com.thoughtworks.xstream.XStream is not accessible (but is visible in the IDE).
Module-info.java:  the named component xstream cannot be resolved to a module.

If I eliminate the requires xstream; but retain the module-info.java, the imported package remain inaccessible.

Perhaps I just don’t understand the JPMS rules, but I thought the xstream-1.4.20.java Jar would lead to an implicit module named xstream.  Perhaps that has tightened with Java 17.

The target application is expected to have dozens of modules, many with their own persisted data type.  It is very desirable to have the extension modules provide customized serializers for their data types.  Efficient implementation of customized serializers requires that the modules have access to XStream data types.

In some of the extension modules, it is desirable to open a package of serialized data types to XStream, with a line in the module definition.  Hand adding a variable set of extension modules to an -add-opens JVM directive does not seem scalable or extensible.

The GitHub repository leeca/XStreamExample has the sample code in place.

The short sequence of commands should replicate the challenges in a small repository.

$ git clone g...@github.com:leeca/XStreamExample.git
$ cd XStreamExample/AutomaticModule/
$ ./gradlew build  # This succeeds
$ cd ../ExplicitModule/
$ ./gradlew build  # This fails




Lee Carver

unread,
Oct 6, 2023, 1:49:44 PM10/6/23
to XStream User
For resolution, the clean and tidy approach is for the application to use "module-aware" components to connect the XStream behaviors to a system's modular components.

On a practical basis, this means isolating the serialization layer into its own component with a module name specified in the MANIFEST.MF file as the Automatic-Module-Name property.

Reply all
Reply to author
Forward
0 new messages