10

I have been searching the internet for a reason why JAXB generated classes have protected members (all of them, regardless of inheritance).

I would like the members to be private instead.

My search has come up empty.

I have normal xsd files which are converted into Java classes using Maven and JAXB. Ideally the generated members should be private but I cannot find a way to achieve this.

Is there a way to modify this default behaviour?

Adam Michalik
  • 9,678
  • 13
  • 71
  • 102
tom
  • 2,735
  • 21
  • 35
  • JAXB generated classes have protected members and possibly have them generated as private, and you say that Ideally the generated members should be private but I cannot find a way to achieve this.. You want ALL the members to be private? As you are saying, they are already private, but some of them are protected, then check if classes having protected fields are inherited by other classes, that may be the reason? – d1e Feb 21 '12 at 12:55
  • @JMelnik: I guess this is a spelling mistake in the first sentence. Just checked my sources and JAXB generates all member attributes with `protected` modifier (regardless of inheritence). Maybe the OP can provide some clarification on the first sentenence? – home Feb 21 '12 at 13:04
  • Modified the first sentence. All members are `protected` (regardless of inheritance) but I want them to be `private`. – tom Feb 21 '12 at 13:18

2 Answers2

11

Well, I am going to respond to my own question. Creating a plugin was the right way to go.

I wrote the following plugin and it seems to work.

public class PrivateMemberPlugin
    extends Plugin
{

    @Override
    public String getOptionName()
    {
        return "Xpm";
    }

    @Override
    public String getUsage()
    {
        return "  -Xpm    : Change members visibility to private";
    }

    @Override
    public boolean run(Outline model, Options opt, ErrorHandler errorHandler)
        throws SAXException
    {
        for (ClassOutline co : model.getClasses())
        {

            JDefinedClass jdc = co.implClass;
            // avoid concurrent modification by copying the fields in a new list
            List<JFieldVar> fields = new ArrayList<JFieldVar>(jdc.fields().values());
            for (JFieldVar field : fields)
            {
                // never do something with serialVersionUID if it exists.
                if (!field.name().equalsIgnoreCase("serialVersionuid"))
                {
                    // only try to change members that are not private
                    if (field.mods().getValue() != JMod.PRIVATE)
                    {
                        // since there is no way to change the visibilty, remove the field an recreate it
                        jdc.removeField(field);
                        jdc.field(JMod.PRIVATE, field.type(), field.name());

                    }
                }
            }

        }
        return true;
    }

}

Feel free to use this if you want.

tom
  • 2,735
  • 21
  • 35
  • You should edit my answer with your defined plugin, this way it would be easier for people to find a solution. Good job! – d1e Feb 22 '12 at 11:04
  • @Matthew, I do appreciate your edit to my answer but I do not think it is relevant. This plugin is to be used when going from a WSDL/XSD to Java code. As far as I know there is no such notion of annotations on any of those hence I remove your note. – tom Apr 19 '13 at 18:42
  • Newer version of the Codemodel library let you update the state of JMods object. In this case, you could invoke `JMods#setPrivate()`. – user1808924 Apr 05 '15 at 19:34
  • Could you please guide me a bit on how to use a plugin? Now I'm using maven plugin, which I run with a `mvn jaxb2:xjc` command. – Frankie Drake Sep 01 '20 at 08:25
6

I think the only way to achieve this is to develop a JXC plugin yourself, search google for samples.

What Can A Plugin Do?

An XJC plugin participates in the code generation from a schema. It can define its own customizations that users can use to control it, it can access the code that the JAXB RI generates, it can generate additional classes/methods/fields/annotations/comments, and it can also replace some of the pluggability points in the compilation process, such as XML name -> Java name conversion.

Luckily, question owner has developed and shared the plugin.

Community
  • 1
  • 1
d1e
  • 6,372
  • 2
  • 28
  • 41