RFR: 7903778: JOL: Add utility for creating objects via factory method when unable to create via constructor

Aleksey Shipilev shade at openjdk.org
Mon Jul 22 10:57:43 UTC 2024


On Thu, 7 Mar 2024 17:27:38 GMT, Kyle J Stiemann <duke at openjdk.org> wrote:

> Adds CLI option to provide a factory FQCN which can create objects that you want to analyze. This is useful in situations where you have dependency classes or JDK classes that require non-null objects or have other validation in the constructor. These kinds of classes can't easily be modified, so it's nice to provide an alternative option for creating them.
> 
> For example:
> 
> 
>     public static final class RequiresFactory {
>        public RequiresFactory(final String string) {
>            Objects.requireNonNull(string);
>            if (string.isEmpty()) {
>                throw new IllegalArgumentException("string must not be empty");
>            }
>        }
>     }
> 
> 
> Usage:
> 
> 
> java -jar jol-cli.jar internals --classpath my-classes.jar --factory my.Factory my.RequiresFactory
> 
> 
> Where `my.Factory` is:
> 
> 
> public class Factory {
>     public static <T> T newInstance(Class<T> aClass) {
> 
>         if (aClass.equals(RequiresFactory.class)) {
>             return aClass.cast(new RequiresFactory("test"));
>         }
> 
>         throw new UnsupportedOperationException(aClass.getTypeName());
>     }
> }

I have only the cosmetics, really. 

Please go to https://github.com/stiemannkj1/jol/actions and enable workflow. It would trigger on the next commit to this PR branch. (No need to force push, the commits would be squashed on integration)

jol-cli/src/main/java/org/openjdk/jol/operations/ClasspathedOperation.java line 57:

> 55:         OptionSpec<String> optFactory = parser.accepts("factory",
> 56:                 "Fully-qualified factory class name. Factory must implement a factory method with the signature: public static <T> T newInstance(java.lang.Class<T>)")
> 57:             .withRequiredArg().ofType(String.class).describedAs("factoryClass");

Suggestion:

            .withRequiredArg().ofType(String.class).describedAs("factory class");

jol-cli/src/main/java/org/openjdk/jol/operations/ClasspathedOperation.java line 78:

> 76: 
> 77:             if (set.has(optFactory)) {
> 78:                 factoryClass = ClassUtils.loadClass(optFactory.value(set));

Can you check what happens if class cannot be loaded? I think it should also fall through to `printHelpOn` with some useful message?

jol-cli/src/main/java/org/openjdk/jol/operations/ClasspathedOperation.java line 105:

> 103:                     factoryClass
> 104:                         .getMethod("newInstance", Class.class)
> 105:                         .invoke(null, klass);

The line breaks here and later are odd. We have enough column space to do:


Object o = factoryClass.getMethod("newInstance", Class.class).invoke(null, klass);

jol-cli/src/test/java/org/openjdk/jol/operations/ClasspathedOperationTest.java line 17:

> 15:     public void testTryInstantiate() throws Exception {
> 16: 
> 17:         final ClasspathedOperation classpathedOperation = new ClasspathedOperation() {

Suggestion:

        final ClasspathedOperation op = new ClasspathedOperation() {


...and the rest of the renames.

jol-cli/src/test/java/org/openjdk/jol/operations/ClasspathedOperationTest.java line 63:

> 61:            Objects.requireNonNull(object);
> 62:        }
> 63:     }

I think it would be less confusing to clearly say this is not a factory. Current use seems to mean "requires factory", but the class name suggests this is an actual `Factory`? I think something like `NeedsFactoryObject` or something like that?

jol-cli/src/test/java/org/openjdk/jol/operations/ClasspathedOperationTest.java line 71:

> 69:             }
> 70: 
> 71:             return null;

Suggestion:

            }
            return null;

jol-cli/src/test/java/org/openjdk/jol/operations/ClasspathedOperationTest.java line 77:

> 75:     public static final class InvalidFactory {
> 76: 
> 77:         public static <T> T newInstance(final Class<T> klass) {

Suggestion:

    public static final class InvalidFactory {
        public static <T> T newInstance(final Class<T> klass) {

-------------

PR Review: https://git.openjdk.org/jol/pull/58#pullrequestreview-2191226793
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686340239
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686348229
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686354459
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686356961
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686360842
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686357777
PR Review Comment: https://git.openjdk.org/jol/pull/58#discussion_r1686355300


More information about the jol-dev mailing list