[ https://issues.apache.org/jira/browse/IGNITE-10075?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Alexey Kukushkin updated IGNITE-10075: -------------------------------------- Description: Presently if there is an Ignite Java service taking parameters of complex (composite) types and returning a result of complex type then all the complex types must be explicitly specified in the binary configuration. We need to enhance Ignite not to require binary configuration assuming that we use the same type, package/namespace and field/property names on both the .NET and Java sides (or provide a custom name mapper for relaxed naming conventions). h2. Reproducer [https://github.com/kukushal/apache-ignite-issue10075.git] h3. ICalculator.java {code:java} package Sandbox.Net; public interface ICalculator { Result Calculate(Parameter p); } {code} h3. Parameter.java {code:java} package Sandbox.Net; public class Parameter { private int id; private double val; public int getId() { return id; } public Parameter setId(int id) { this.id = id; return this; } public double getValue() { return val; } public Parameter setValue(double val) { this.val = val; return this; } } {code} h3. Result .java {code:java} package Sandbox.Net; public class Result { private int id; private double value; public int getId() { return id; } public Result setId(int id) { this.id = id; return this; } public double getValue() { return value; } public Result setValue(double val) { this.value = val; return this; } } {code} h3. IgniteCalculatorService.java {code:java} package Sandbox.Net; import org.apache.ignite.services.Service; import org.apache.ignite.services.ServiceContext; public class IgniteCalculatorService implements Service, ICalculator { @Override public Result Calculate(Parameter p) { return new Result().setId(p.getId()).setValue(p.getValue() * p.getValue()); } @Override public void cancel(ServiceContext ctx) { } @Override public void init(ServiceContext ctx) { } @Override public void execute(ServiceContext ctx) { } } {code} h3. build.gradle {code:groovy} plugins { id 'java' } group 'sandbox.net' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenLocal() mavenCentral() } def igniteVer='2.8.0' dependencies { compile group: 'org.apache.ignite', name: 'ignite-core', version: igniteVer testCompile group: 'junit', name: 'junit', version: '4.12' } {code} h3. ignite-config.xml {code:xml} <?xml version="1.0" encoding="utf-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="serviceConfiguration"> <list> <bean class="org.apache.ignite.services.ServiceConfiguration"> <property name="name" value="IgniteCalculatorService"/> <property name="maxPerNodeCount" value="1"/> <property name="totalCount" value="0"/> <property name="service"> <bean class="Sandbox.Net.IgniteCalculatorService"/> </property> </bean> </list> </property> <property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> <property name="addresses"> <list> <value>127.0.0.1:47500</value> </list> </property> </bean> </property> </bean> </property> </bean> </beans> {code} h3. ICalculator.cs {code:c#} namespace Sandbox.Net { public interface ICalculator { Result Calculate(Parameter p); } } {code} h3. Parameter.cs {code:c#} namespace Sandbox.Net { public class Parameter { public int Id { get; set; } public double Value { get; set; } } } {code} h3. Result.cs {code:c#} namespace Sandbox.Net { public class Result { public int Id { get; set; } public double Value { get; set; } } } {code} h3. Reproducer.cs {code:c#} using Apache.Ignite.Core; using System; namespace Sandbox.Net { class Reproducer { static void Main(string[] args) { IgniteConfiguration CommonConfig(string name) => new IgniteConfiguration { IgniteInstanceName = name, SpringConfigUrl = "ignite-config.xml", JvmClasspath = "sandbox.net-1.0-SNAPSHOT.jar" }; var igniteServerCfg = CommonConfig("server1"); var igniteAppCfg = CommonConfig("app"); igniteAppCfg.ClientMode = true; using (var _ = Ignition.Start(igniteServerCfg)) using (var ignite = Ignition.Start(igniteAppCfg)) { var calc = ignite.GetServices().GetServiceProxy<ICalculator>("IgniteCalculatorService"); var res = calc.Calculate(new Parameter { Id = 2, Value = 2.0 }); Console.WriteLine($">>>>> {res.Value}"); } } } } {code} h2. Actual Result Exception {code:java} Apache.Ignite.Core.Services.ServiceInvocationException HResult=0x80131500 Message=Proxy method invocation failed with an exception. Examine InnerException for details. Source=Apache.Ignite.Core StackTrace: at Apache.Ignite.Core.Impl.Services.ServiceProxySerializer.ReadInvocationResult(IBinaryStream stream, Marshaller marsh, Boolean keepBinary) at Apache.Ignite.Core.Impl.PlatformJniTarget.InObjectStreamOutObjectStream[TR](Int32 type, Action`1 writeAction, Func`3 readAction, IPlatformTargetInternal arg) at Apache.Ignite.Core.Impl.Services.Services.<>c__DisplayClass22`1.<GetServiceProxy>b__21(MethodBase method, Object[] args) at Sandbox.Net.Reproducer.Main(String[] args) in C:\Dev\sandbox.net\Sandbox.Net\Reproducer.cs:line 26 Inner Exception 1: IgniteException: Java exception occurred [class=org.apache.ignite.binary.BinaryInvalidTypeException, message=Requesting mapping from grid failed for [platformId=0, typeId=1340744113]] Inner Exception 2: JavaException: class org.apache.ignite.binary.BinaryInvalidTypeException: Requesting mapping from grid failed for [platformId=0, typeId=1340744113] at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:643) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1755) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1714) at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:794) at org.apache.ignite.internal.binary.BinaryObjectImpl.deserialize(BinaryObjectImpl.java:636) at org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinary(PlatformUtils.java:912) at org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinariesInArray(PlatformUtils.java:980) at org.apache.ignite.internal.processors.platform.services.PlatformServices$ServiceProxyHolder.invoke(PlatformServices.java:579) at org.apache.ignite.internal.processors.platform.services.PlatformServices.processInObjectStreamOutObjectStream(PlatformServices.java:287) at org.apache.ignite.internal.processors.platform.PlatformTargetProxyImpl.inObjectStreamOutObjectStream(PlatformTargetProxyImpl.java:171) Caused by: java.lang.ClassNotFoundException: Requesting mapping from grid failed for [platformId=0, typeId=1340744113] at org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:409) at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:368) at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:634) ... 9 more {code} was: Presently if there is an Ignite Java service taking parameters of complex (composite) types and returning a result of complex type then all the complex types must be explicitly specified in the binary configuration. We need to enhance Ignite not to require binary configuration assuming that we use the same type, package/namespace and field/property names on both the .NET and Java sides (or provide a custom name mapper for relaxed naming conventions). h2. Reproducer h3. ICalculator.java {code:java} package Sandbox.Net; public interface ICalculator { Result Calculate(Parameter p); } {code} h3. Parameter.java {code:java} package Sandbox.Net; public class Parameter { private int id; private double val; public int getId() { return id; } public Parameter setId(int id) { this.id = id; return this; } public double getValue() { return val; } public Parameter setValue(double val) { this.val = val; return this; } } {code} h3. Result .java {code:java} package Sandbox.Net; public class Result { private int id; private double value; public int getId() { return id; } public Result setId(int id) { this.id = id; return this; } public double getValue() { return value; } public Result setValue(double val) { this.value = val; return this; } } {code} h3. IgniteCalculatorService.java {code:java} package Sandbox.Net; import org.apache.ignite.services.Service; import org.apache.ignite.services.ServiceContext; public class IgniteCalculatorService implements Service, ICalculator { @Override public Result Calculate(Parameter p) { return new Result().setId(p.getId()).setValue(p.getValue() * p.getValue()); } @Override public void cancel(ServiceContext ctx) { } @Override public void init(ServiceContext ctx) { } @Override public void execute(ServiceContext ctx) { } } {code} h3. build.gradle {code:groovy} plugins { id 'java' } group 'sandbox.net' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenLocal() mavenCentral() } def igniteVer='2.8.0' dependencies { compile group: 'org.apache.ignite', name: 'ignite-core', version: igniteVer testCompile group: 'junit', name: 'junit', version: '4.12' } {code} h3. ignite-config.xml {code:xml} <?xml version="1.0" encoding="utf-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="serviceConfiguration"> <list> <bean class="org.apache.ignite.services.ServiceConfiguration"> <property name="name" value="IgniteCalculatorService"/> <property name="maxPerNodeCount" value="1"/> <property name="totalCount" value="0"/> <property name="service"> <bean class="Sandbox.Net.IgniteCalculatorService"/> </property> </bean> </list> </property> <property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> <property name="addresses"> <list> <value>127.0.0.1:47500</value> </list> </property> </bean> </property> </bean> </property> </bean> </beans> {code} h3. ICalculator.cs {code:c#} namespace Sandbox.Net { public interface ICalculator { Result Calculate(Parameter p); } } {code} h3. Parameter.cs {code:c#} namespace Sandbox.Net { public class Parameter { public int Id { get; set; } public double Value { get; set; } } } {code} h3. Result.cs {code:c#} namespace Sandbox.Net { public class Result { public int Id { get; set; } public double Value { get; set; } } } {code} h3. Reproducer.cs {code:c#} using Apache.Ignite.Core; using System; namespace Sandbox.Net { class Reproducer { static void Main(string[] args) { IgniteConfiguration CommonConfig(string name) => new IgniteConfiguration { IgniteInstanceName = name, SpringConfigUrl = "ignite-config.xml", JvmClasspath = "sandbox.net-1.0-SNAPSHOT.jar" }; var igniteServerCfg = CommonConfig("server1"); var igniteAppCfg = CommonConfig("app"); igniteAppCfg.ClientMode = true; using (var _ = Ignition.Start(igniteServerCfg)) using (var ignite = Ignition.Start(igniteAppCfg)) { var calc = ignite.GetServices().GetServiceProxy<ICalculator>("IgniteCalculatorService"); var res = calc.Calculate(new Parameter { Id = 2, Value = 2.0 }); Console.WriteLine($">>>>> {res.Value}"); } } } } {code} h2. Actual Result Exception {code} Apache.Ignite.Core.Services.ServiceInvocationException HResult=0x80131500 Message=Proxy method invocation failed with an exception. Examine InnerException for details. Source=Apache.Ignite.Core StackTrace: at Apache.Ignite.Core.Impl.Services.ServiceProxySerializer.ReadInvocationResult(IBinaryStream stream, Marshaller marsh, Boolean keepBinary) at Apache.Ignite.Core.Impl.PlatformJniTarget.InObjectStreamOutObjectStream[TR](Int32 type, Action`1 writeAction, Func`3 readAction, IPlatformTargetInternal arg) at Apache.Ignite.Core.Impl.Services.Services.<>c__DisplayClass22`1.<GetServiceProxy>b__21(MethodBase method, Object[] args) at Sandbox.Net.Reproducer.Main(String[] args) in C:\Dev\sandbox.net\Sandbox.Net\Reproducer.cs:line 26 Inner Exception 1: IgniteException: Java exception occurred [class=org.apache.ignite.binary.BinaryInvalidTypeException, message=Requesting mapping from grid failed for [platformId=0, typeId=1340744113]] Inner Exception 2: JavaException: class org.apache.ignite.binary.BinaryInvalidTypeException: Requesting mapping from grid failed for [platformId=0, typeId=1340744113] at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:643) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1755) at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1714) at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:794) at org.apache.ignite.internal.binary.BinaryObjectImpl.deserialize(BinaryObjectImpl.java:636) at org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinary(PlatformUtils.java:912) at org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinariesInArray(PlatformUtils.java:980) at org.apache.ignite.internal.processors.platform.services.PlatformServices$ServiceProxyHolder.invoke(PlatformServices.java:579) at org.apache.ignite.internal.processors.platform.services.PlatformServices.processInObjectStreamOutObjectStream(PlatformServices.java:287) at org.apache.ignite.internal.processors.platform.PlatformTargetProxyImpl.inObjectStreamOutObjectStream(PlatformTargetProxyImpl.java:171) Caused by: java.lang.ClassNotFoundException: Requesting mapping from grid failed for [platformId=0, typeId=1340744113] at org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:409) at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:368) at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:634) ... 9 more {code} > .NET: Avoid binary configurations of Ignite Java service params and result > when calling it from Ignite.NET > ---------------------------------------------------------------------------------------------------------- > > Key: IGNITE-10075 > URL: https://issues.apache.org/jira/browse/IGNITE-10075 > Project: Ignite > Issue Type: Improvement > Components: platforms > Affects Versions: 2.9 > Reporter: Alexey Kukushkin > Assignee: Alexey Kukushkin > Priority: Major > Labels: .NET, sbcf > Attachments: MyTest.cs, ignite-10075-vs-2.8.patch > > Time Spent: 10m > Remaining Estimate: 0h > > Presently if there is an Ignite Java service taking parameters of complex > (composite) types and returning a result of complex type then all the complex > types must be explicitly specified in the binary configuration. > We need to enhance Ignite not to require binary configuration assuming that > we use the same type, package/namespace and field/property names on both the > .NET and Java sides (or provide a custom name mapper for relaxed naming > conventions). > h2. Reproducer > [https://github.com/kukushal/apache-ignite-issue10075.git] > h3. ICalculator.java > {code:java} > package Sandbox.Net; > public interface ICalculator { > Result Calculate(Parameter p); > } > {code} > h3. Parameter.java > {code:java} > package Sandbox.Net; > public class Parameter { > private int id; > private double val; > public int getId() { > return id; > } > public Parameter setId(int id) { > this.id = id; > return this; > } > public double getValue() { > return val; > } > public Parameter setValue(double val) { > this.val = val; > return this; > } > } > {code} > h3. Result .java > {code:java} > package Sandbox.Net; > public class Result { > private int id; > private double value; > public int getId() { > return id; > } > public Result setId(int id) { > this.id = id; > return this; > } > public double getValue() { > return value; > } > public Result setValue(double val) { > this.value = val; > return this; > } > } > {code} > h3. IgniteCalculatorService.java > {code:java} > package Sandbox.Net; > import org.apache.ignite.services.Service; > import org.apache.ignite.services.ServiceContext; > public class IgniteCalculatorService implements Service, ICalculator { > @Override public Result Calculate(Parameter p) { > return new Result().setId(p.getId()).setValue(p.getValue() * > p.getValue()); > } > @Override public void cancel(ServiceContext ctx) { > } > @Override public void init(ServiceContext ctx) { > } > @Override public void execute(ServiceContext ctx) { > } > } > {code} > h3. build.gradle > {code:groovy} > plugins { > id 'java' > } > group 'sandbox.net' > version '1.0-SNAPSHOT' > sourceCompatibility = 1.8 > repositories { > mavenLocal() > mavenCentral() > } > def igniteVer='2.8.0' > dependencies { > compile group: 'org.apache.ignite', name: 'ignite-core', version: > igniteVer > testCompile group: 'junit', name: 'junit', version: '4.12' > } > {code} > h3. ignite-config.xml > {code:xml} > <?xml version="1.0" encoding="utf-8" ?> > <beans xmlns="http://www.springframework.org/schema/beans" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation=" > http://www.springframework.org/schema/beans > http://www.springframework.org/schema/beans/spring-beans.xsd"> > <bean id="ignite.cfg" > class="org.apache.ignite.configuration.IgniteConfiguration"> > <property name="serviceConfiguration"> > <list> > <bean class="org.apache.ignite.services.ServiceConfiguration"> > <property name="name" value="IgniteCalculatorService"/> > <property name="maxPerNodeCount" value="1"/> > <property name="totalCount" value="0"/> > <property name="service"> > <bean class="Sandbox.Net.IgniteCalculatorService"/> > </property> > </bean> > </list> > </property> > <property name="discoverySpi"> > <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> > <property name="ipFinder"> > <bean > class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"> > <property name="addresses"> > <list> > <value>127.0.0.1:47500</value> > </list> > </property> > </bean> > </property> > </bean> > </property> > </bean> > </beans> > {code} > h3. ICalculator.cs > {code:c#} > namespace Sandbox.Net > { > public interface ICalculator > { > Result Calculate(Parameter p); > } > } > {code} > h3. Parameter.cs > {code:c#} > namespace Sandbox.Net > { > public class Parameter > { > public int Id { get; set; } > public double Value { get; set; } > } > } > {code} > h3. Result.cs > {code:c#} > namespace Sandbox.Net > { > public class Result > { > public int Id { get; set; } > public double Value { get; set; } > } > } > {code} > h3. Reproducer.cs > {code:c#} > using Apache.Ignite.Core; > using System; > namespace Sandbox.Net > { > class Reproducer > { > static void Main(string[] args) > { > IgniteConfiguration CommonConfig(string name) => new > IgniteConfiguration > { > IgniteInstanceName = name, > SpringConfigUrl = "ignite-config.xml", > JvmClasspath = "sandbox.net-1.0-SNAPSHOT.jar" > }; > var igniteServerCfg = CommonConfig("server1"); > var igniteAppCfg = CommonConfig("app"); > igniteAppCfg.ClientMode = true; > using (var _ = Ignition.Start(igniteServerCfg)) > using (var ignite = Ignition.Start(igniteAppCfg)) > { > var calc = > ignite.GetServices().GetServiceProxy<ICalculator>("IgniteCalculatorService"); > var res = calc.Calculate(new Parameter { Id = 2, Value = 2.0 > }); > Console.WriteLine($">>>>> {res.Value}"); > } > } > } > } > {code} > h2. Actual Result Exception > {code:java} > Apache.Ignite.Core.Services.ServiceInvocationException > HResult=0x80131500 > Message=Proxy method invocation failed with an exception. Examine > InnerException for details. > Source=Apache.Ignite.Core > StackTrace: > at > Apache.Ignite.Core.Impl.Services.ServiceProxySerializer.ReadInvocationResult(IBinaryStream > stream, Marshaller marsh, Boolean keepBinary) > at > Apache.Ignite.Core.Impl.PlatformJniTarget.InObjectStreamOutObjectStream[TR](Int32 > type, Action`1 writeAction, Func`3 readAction, IPlatformTargetInternal arg) > at > Apache.Ignite.Core.Impl.Services.Services.<>c__DisplayClass22`1.<GetServiceProxy>b__21(MethodBase > method, Object[] args) > at Sandbox.Net.Reproducer.Main(String[] args) in > C:\Dev\sandbox.net\Sandbox.Net\Reproducer.cs:line 26 > Inner Exception 1: > IgniteException: Java exception occurred > [class=org.apache.ignite.binary.BinaryInvalidTypeException, > message=Requesting mapping from grid failed for [platformId=0, > typeId=1340744113]] > Inner Exception 2: > JavaException: class org.apache.ignite.binary.BinaryInvalidTypeException: > Requesting mapping from grid failed for [platformId=0, typeId=1340744113] > at > org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:643) > at > org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1755) > at > org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1714) > at > org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:794) > at > org.apache.ignite.internal.binary.BinaryObjectImpl.deserialize(BinaryObjectImpl.java:636) > at > org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinary(PlatformUtils.java:912) > at > org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinariesInArray(PlatformUtils.java:980) > at > org.apache.ignite.internal.processors.platform.services.PlatformServices$ServiceProxyHolder.invoke(PlatformServices.java:579) > at > org.apache.ignite.internal.processors.platform.services.PlatformServices.processInObjectStreamOutObjectStream(PlatformServices.java:287) > at > org.apache.ignite.internal.processors.platform.PlatformTargetProxyImpl.inObjectStreamOutObjectStream(PlatformTargetProxyImpl.java:171) > Caused by: java.lang.ClassNotFoundException: Requesting mapping from grid > failed for [platformId=0, typeId=1340744113] > at > org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:409) > at > org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:368) > at > org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:634) > ... 9 more > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005)