multiline icon indicating copy to clipboard operation
multiline copied to clipboard

Error interacting with meanbean for unit tests...

Open InfoSec812 opened this issue 9 years ago • 2 comments

When I use the multiline library in conjunction with meanbean for unit testing beans, I get an error. The error goes away when I remove the @Multiline annotation:

Cannot test bean [com.sungardas.cc.vsphere.docs.VCenterConfig]. Failed to instantiate an instance of the bean.
org.meanbean.test.BeanTestException
    at org.meanbean.test.BeanTester.testBean(BeanTester.java:406)
    at org.meanbean.test.BeanTester.testBean(BeanTester.java:350)
    at com.sungardas.cc.vsphere.docs.BeanTester.testBeans(BeanTester.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:242)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:137)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.meanbean.factories.ObjectCreationException: Failed to instantiate object of type [com.sungardas.cc.vsphere.docs.VCenterConfig] due to InvocationTargetException.
    at org.meanbean.factories.BasicNewObjectInstanceFactory.wrapAndRethrowException(BasicNewObjectInstanceFactory.java:94)
    at org.meanbean.factories.BasicNewObjectInstanceFactory.create(BasicNewObjectInstanceFactory.java:74)
    at org.meanbean.test.BeanTester.testBean(BeanTester.java:400)
    ... 31 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.meanbean.factories.BasicNewObjectInstanceFactory.create(BasicNewObjectInstanceFactory.java:62)
    ... 32 more
Caused by: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 24 column 6
    at com.google.gson.Gson.fromJson(Gson.java:818)
    at com.google.gson.Gson.fromJson(Gson.java:768)
    at com.google.gson.Gson.fromJson(Gson.java:717)
    at com.google.gson.Gson.fromJson(Gson.java:689)
    at com.sungardas.cc.vsphere.docs.VCenterConfig.<init>(VCenterConfig.java:70)
    ... 37 more
Caused by: com.google.gson.stream.MalformedJsonException: Expected name at line 24 column 6
    at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1505)
    at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:494)
    at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:403)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:184)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
    at com.google.gson.Gson.fromJson(Gson.java:803)
    ... 41 more

The exception being caused by Gson is interesting and confusing to me... Can Multiline automatically map JSON strings to a nested Map? Is that why it uses Gson?

The class looks like:

package com.sungardas.cc.vsphere.docs;

import com.google.gson.annotations.Expose;
import com.sungardas.cc.documents.AbstractDocument;
import java.util.HashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.adrianwalker.multilinestring.Multiline;

/**
 *
 * @author <a href="https://github.com/InfoSec812">Deven Phillips</a>
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VCenterConfig extends AbstractDocument {

    // Defines a multi-line String literal in a more readable fashion
    /**
    {
        "VirtualMachine": [
            "name", "summary.config.uuid", "summary.config.memorySizeMB", "summary.config.numCpu",
            "runtime.powerState", "runtime.host", "summary.config.template", "guestHeartbeatStatus",
            "guest.disk", "guest.net", "guest.hostName", "guest.guestFamily", "guest.guestFullName", 
            "guest.guestId", "config.hardware.device", "config.hardware.numCoresPerSocket"
        ],
        "ClusterComputeResource": [
          "name", "summary.numHosts", "summary.totalMemory", "summary.numCpuCores", "host"
        ],
        "Datastore": [
          "name", "summary.freeSpace", "summary.capacity", "summary.uncommitted",
             "summary.accessible", "summary.type", "host"
        ],
        "HostSystem": [
          "name", "vm"
        ],
        "DistributedVirtualSwitch": [
          "capability", "config", "networkResourcePool", "portgroup", "summary", "uuid"
        ],
        "DistributedVirtualPortgroup": [
          "config", "key", "portKeys"
        ],
    }
     */
    @Multiline
    static String DEFAULT_PROPERTIES;

    @Expose
    private String host;

    @Expose
    private Integer port = 9443;

    @Expose
    private String username;

    @Expose
    private String password;

    @Expose
    private String site;

    @Expose
    private String location;

    @Expose
    private Map<String, String[]> properties = AbstractDocument.getGson().fromJson(DEFAULT_PROPERTIES, HashMap.class);

    @Expose
    private Integer maxObjects = 1000;

    @Override
    public String documentType() {
        return "vcenter-config";
    }
}

InfoSec812 avatar Jun 18 '15 13:06 InfoSec812

@InfoSec812 Multiline do nothing special to JSON. As I guess, charactors for new line or spaces affects validation of the JSON string.

I recommend to test as following

  1. Print the json string on the console System.out.println(DEFAULT_PROPERTIES)
  2. Copy the result of 1 to a file ( ex) test.json )
  3. Read the content of 2, and try to parse it

benelog avatar Mar 08 '16 21:03 benelog

This is definitely user error. The actual problem is the trailing comma after the "DistributedVirtualPortgroup" key's value, which JSON doesn't allow. (The JSON would work fine as a Javascript literal, however, because Javascript has looser parsing rules.)

allanon avatar Aug 17 '16 23:08 allanon