Fork me on GitHub
#polylith
<
2023-01-15
>
emccue05:01:00

For static methods, same approach is valid

emccue05:01:23

package dev.mccue.polylith.math;

import dev.mccue.polylith.math.spi.MathUtilsOps;

import java.util.ServiceLoader;

public final class MathUtils {
    private static final MathUtilsOps OPS = ServiceLoader.load(MathUtilsOps.class)
            .findFirst()
            .orElseThrow();

    private MathUtils() {}

    public static int add(int a, int b) {
        return OPS.add(a, b);
    }
}
Make an interface to delegate to

emccue05:01:30

package dev.mccue.polylith.math.spi;

public interface MathUtilsOps {
    int add(int a, int b);
}

emccue05:01:02

module jolly.math {
    exports dev.mccue.polylith.math;
    exports dev.mccue.polylith.math.spi to jolly.math.impl;

    requires transitive java.sql;

    uses dev.mccue.polylith.math.spi.MathUtilsOps;
}
Don't expose the interface - keep it in its own package and expose it to implementations

emccue05:01:37

package dev.mccue.polylith.math.impl;

import dev.mccue.polylith.math.spi.MathUtilsOps;

public final class MathUtilsOpsImpl implements MathUtilsOps {
    @Override
    public int add(int a, int b) {
        return a + b;
    }
}
module jolly.math.impl {
    requires jolly.math;

    provides dev.mccue.polylith.math.spi.MathUtilsOps
            with dev.mccue.polylith.math.impl.MathUtilsOpsImpl;
}
Provide implementation of interface, which is then exported as static methods to the consumer

emccue05:01:08

And all of these structural components can probably be asserted statically by a tool

emccue05:01:54

i.e that the component modules provide a service, that interface modules require the same services that the component module provides, and that every interface module has a matching component module, and every project requires both the interface and implementation

tengstrand22:01:46

Hi @U3JH98J4R! This looks interesting, thanks for sharing it with us! Have you considered any approaches that would let you build projects at compile-time (rather than run-time), as that would more closely match the approach we take with the Clojure version? I created this https://github.com/polyfy/polylith/issues/278 and my plan is to implement a short example in Java that shows what I mean.

emccue22:01:06

I have - i'm not sure where I land on that tbh

tengstrand23:01:31

Okay. I will come back to you when I have something to show.

tengstrand17:01:18

Hi @U3JH98J4R. I found the old example that I posted in the https://github.com/polyfy/polylith/issues/278.

emccue18:01:47

@U1G0HH87L left a question