Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle plugin has no default propertyWordDelimiters #162

Closed
asker123 opened this issue Mar 20, 2014 · 23 comments
Closed

Gradle plugin has no default propertyWordDelimiters #162

asker123 opened this issue Mar 20, 2014 · 23 comments
Milestone

Comments

@asker123
Copy link

Hi All,

I have been using this library for converting my jsonschema2pojo and I use both maven and gradle for my project.

My JsonSchema looks like below:

{
    "javaType" : "user.Tool",
    "type":"object",
    "$schema": "http://json-schema.org/draft-03/schema",
    "id": "http://jsonschema.net",
    "required":false,
    "properties":{
        "tool_key": {
            "type":"number",
            "id": "http://jsonschema.net/tool_key",
            "required":false
        },
        "tool_password": {
            "type":"string",
            "id": "http://jsonschema.net/tool_password",
            "required":false
        }
    }
}

For maven, it generates java class like: ToolKey and ToolPassword
For gradle, it generates java class like: Tool_key and Tool_password

Is this a problem with using this library? Is there any solution to have the pojo's created with same names?

Please let me know. Appreciate any help.

Thanks.

@asker123
Copy link
Author

Just for more info:

Maven pojo:

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "tool_key",
    "tool_password"
})
public class Tool {

    /**
     * 
     */
    @JsonProperty("tool_key")
    private Double toolKey;
    /**
     * 
     */
    @JsonProperty("tool_password")
    private String toolPassword;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     */
    @JsonProperty("tool_key")
    public Double getToolKey() {
        return toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_key")
    public void setToolKey(Double toolKey) {
        this.toolKey = toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public String getToolPassword() {
        return toolPassword;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public void setToolPassword(String toolPassword) {
        this.toolPassword = toolPassword;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

Gradle Pojo:

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "tool_key",
    "tool_password"
})
public class Tool {

    /**
     * 
     */
    @JsonProperty("tool_key")
    private Double tool_key;
    /**
     * 
     */
    @JsonProperty("tool_password")
    private String tool_password;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     */
    @JsonProperty("tool_key")
    public Double getTool_key() {
        return tool_key;
    }

    /**
     * 
     */
    @JsonProperty("tool_key")
    public void setTool_key(Double tool_key) {
        this.tool_key = tool_key;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public String getTool_password() {
        return tool_password;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public void setTool_password(String tool_password) {
        this.tool_password = tool_password;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

@joelittlejohn joelittlejohn changed the title maven plugin creates pojos different than gradle plugin, for the same jsonschema Gradle plugin has no default propertyWordDelimiters Mar 21, 2014
@joelittlejohn
Copy link
Owner

Looks like this is a bug in the Gradle plugin caused by #109. You can fix this by setting the propertyWordDelimiters config option to ['_'] when using the groovy plugin.

@asker123
Copy link
Author

Thanks. I used the solution you provided, but then when I do serialization/deserialization the property name is converted to toolKey and toolName. I want to have them as tool_key and tool_name. The java classes prob gets solved but the json property name changes. Is there a way to get the names as I mentioned? Also, is there a way to get rid of additionalproperties?

Thanks.

@joelittlejohn
Copy link
Owner

You can set "additionalProperties": false in your schema.

What library are you using to serialize/deserialize the types? I don't know why you would see these names change since the @JsonProperty annotation should stop this. Can you show me the new Tool class?

@asker123
Copy link
Author

additionalProperties works. Thanks for the solution.

I am using jackson.

Here's the Java class:

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "tool_key",
    "tool_password"
})
public class Tool {

    /**
     * 
     */
    @JsonProperty("tool_key")
    private Double toolKey;
    /**
     * 
     */
    @JsonProperty("tool_password")
    private String toolPassword;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     */
    @JsonProperty("tool_key")
    public Double getToolKey() {
        return toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_key")
    public void setToolKey(Double toolKey) {
        this.toolKey = toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public String getToolPassword() {
        return toolPassword;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public void setToolPassword(String toolPassword) {
        this.toolPassword = toolPassword;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

Thanks.

@joelittlejohn
Copy link
Owner

Hmmm, I think you might have your Jackson versions mixed up. You can see the @JsonProperty annotations that should ensure that your JSON properties are named as tool_key and tool_password.

You don't show the imports (you should check these), but by default the plugin will generate Jackson 2 compatible types. Are you using an ObjectMapper from Jackson 2 to serialize your objects? If you need Jackson 1, you can set annotationStyle to jackson1.

@asker123
Copy link
Author

Hi, I am not using ObjectMapper. Versions for both maven and gradle are similar. I am using jackson 2.2.2.

Thanks

@joelittlejohn
Copy link
Owner

Sorry, maybe I'm misunderstanding what you mean by this:

I used the solution you provided, but then when I do serialization/deserialization the property name is converted to toolKey and toolName. I want to have them as tool_key and tool_name. The java classes prob gets solved but the json property name changes. Is there a way to get the names as I mentioned?

What exactly do you see in the JSON? Is the JSON wrong or do you mean you want the Java field and method names to be different?

@asker123
Copy link
Author

The JSON has the property names as toolKey and toolPassword. I want them as tool_key and tool_password. I also want the functions generated to have same names (for both maven and gradle) so that when I build with either of them, I don't have compilation issues.

@joelittlejohn
Copy link
Owner

Okay, so could you paste the result of running the Gradle plugin after you have set the propertyWordDelimiters? Including all imports.

We know why the Java output is different between Gradle and Maven, it's because there is a problem with the Gradle plugin and no default propertyWordDelimiters are set (so you have to set them manually).

The only reason that tool_key would become toolKey in the JSON output is if Jackson is ignoring the @JsonProperty annotations. The most likely cause for this is that the wrong version of Jackson is being used to serialize (so the annotations aren't found). You say you are not using ObjectMapper, so what are you using to serialize?

@asker123
Copy link
Author

The issue is with maven generated pojo.

This is maven pojo:

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "tool_key",
    "tool_password"
})
public class Tool {

    /**
     * 
     */
    @JsonProperty("tool_key")
    private Double toolKey;
    /**
     * 
     */
    @JsonProperty("tool_password")
    private String toolPassword;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     */
    @JsonProperty("tool_key")
    public Double getToolKey() {
        return toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_key")
    public void setToolKey(Double toolKey) {
        this.toolKey = toolKey;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public String getToolPassword() {
        return toolPassword;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public void setToolPassword(String toolPassword) {
        this.toolPassword = toolPassword;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

This is maven config:

<groupId>org.jsonschema2pojo</groupId>
                <artifactId>jsonschema2pojo-maven-plugin</artifactId>
                <version>0.4.0</version>
                <configuration>
                    <sourceDirectory>./src/main/resources/JsonSchema</sourceDirectory>
                    <targetPackage>com.myproject.entities</targetPackage>
                    <propertyWordDelimiters>_</propertyWordDelimiters>
                </configuration>

This is gradle pojo:

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "tool_key",
    "tool_password"
})
public class Tool {

    /**
     * 
     */
    @JsonProperty("tool_key")
    private Double tool_key;
    /**
     * 
     */
    @JsonProperty("tool_password")
    private String tool_password;
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     */
    @JsonProperty("tool_key")
    public Double getTool_key() {
        return tool_key;
    }

    /**
     * 
     */
    @JsonProperty("tool_key")
    public void setTool_key(Double tool_key) {
        this.tool_key = tool_key;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public String getTool_password() {
        return tool_password;
    }

    /**
     * 
     */
    @JsonProperty("tool_password")
    public void setTool_password(String tool_password) {
        this.tool_password = tool_password;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

Also, the groovy has this:

  propertyWordDelimiters = [] as char[]

So, maven is not annotating as per my jsonschema. Gradle works perfect. I am using jackson 2, and I am sending java object 'Tool' as asyncResponse on the vertx handler.

Thanks.

@joelittlejohn
Copy link
Owner

Okay, so which do you want in the Java? Do you want getTool_key or getToolKey?

@asker123
Copy link
Author

I want getTool_key.

@joelittlejohn
Copy link
Owner

If you want getToolKey, then set propertyWordDelimiters = ['_'] as char[] in Gradle config. If you want getTool_key then set <propertyWordDelimiters></propertyWordDelimiters> (empty value) in the Maven config. The Maven plugin has some default propertyWordDelimiters, the Gradle plugin does not. I described this problem above, and you mentioned that you had already applied this solution - are we going backwards here?

Now, you should never see toolKey in any JSON output, it will always be tool_key. You can see this from the @JsonProperty annotations shown in the code you have pasted. If you ever see toolKey then it means there is something wrong with the way you are serializing these types - if you use Jackson 2 to serialize them, then it will not create toolKey (because of the @JsonProperty value).

@asker123
Copy link
Author

I tried the solution. I see that the @JsonProperty is set as tool_key in maven pojo, but the class name is somehow coming as toolKey. I don't understand why.

This is my jackson dependency in maven:

com.fasterxml.jackson.core jackson-databind 2.2.2

I am not able to see what I am missing. I changed the propertyWordDelimiters as well.

Thanks.

@joelittlejohn
Copy link
Owner

I tried the solution. I see that the @JsonProperty is set as tool_key in maven pojo, but the class name is somehow coming as toolKey.

I don't think you mean class name, do you? What is coming as toolKey? the method/field name or the JSON data?

Could you try the following:

<propertyWordDelimiters> </propertyWordDelimiters>

(Note the value is a space)

@asker123
Copy link
Author

The method/field name is coming as toolKey. I want it to be getTool_key for both maven and gradle, so that I can compile using both. I tried with space, the same results. :(
Thanks.

@joelittlejohn
Copy link
Owner

It looks like this is caused by the way that Maven treats empty and blank strings as null values:

http://mail-archives.apache.org/mod_mbox/maven-users/200708.mbox/%[email protected]%3E

The following should work for you:

<propertyWordDelimiters>-</propertyWordDelimiters>

You can set any character in there, as long as your property names will not use this character (e.g. -, *, $, etc).

@asker123
Copy link
Author

Hey it worked. It now generates same method names for both maven and gradle. Thanks a lot. :)

@joelittlejohn
Copy link
Owner

@asker123 probably best if we leave this open for now. The propertyWordDelimiters should have a default value in Gradle (to match the Maven plugin) and I plan to add this into the next release.

@joelittlejohn joelittlejohn reopened this Mar 31, 2014
@joelittlejohn joelittlejohn modified the milestones: 0.4.2, 0.5.0 Apr 17, 2014
@ben-manes
Copy link
Collaborator

Probably the Gradle plugin's JsonSchemaExtension should initialize the values by creating a DefaultGenerationConfig and querying it for each field. The fields are currently set to manually after inspecting DefaultGenerationConfig. As the default config was changed, the Gradle plugin's defaults were out of sync. Using DefaultGenerationConfig directly would ensure that it is the canonical truth.

@joelittlejohn
Copy link
Owner

Very good point. This is similar to what the website does (
jsonschema2pojo.org) to maintain defaults for anything that's not
explicitly specified.

On 14 June 2015 at 16:02, Ben Manes [email protected] wrote:

Probably the Gradle plugin's JsonSchemaExtension should initialize the
values by creating a DefaultGenerationConfig and querying it for each
field. The fields are currently set to manually after inspecting
DefaultGenerationConfig. As the default config was changed, the Gradle
plugin's defaults were out of sync. Using DefaultGenerationConfig
directly would ensure that it is the canonical truth.


Reply to this email directly or view it on GitHub
#162 (comment)
.

@joelittlejohn
Copy link
Owner

Fixed by #625.

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

No branches or pull requests

4 participants