[
https://issues.apache.org/jira/browse/IGNITE-10075?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17240358#comment-17240358
]
Alexey Kukushkin commented on IGNITE-10075:
-------------------------------------------
[~nizhikov],
TypeID->TypeName mappings are automatically registered at the time of calling a
service. The mapping is saved as a <workDirectory>/db/marshaller/<Type
ID>.classname<Platform ID> file, where Platform ID is 0 when the call
originates in .NET and 1 when the call originates from Java. Thus, a .NET->Java
call with a type of argument having type ID, say, 123, creates a file
<workDirectory>/db/marshaller/123.classname1.
The Java service receiving the call tries to unmarshal the argument type
(instantiate Java class from Ignite binary type).
The problem is that currently (without the patch I attached) the Java service
looks only for Java types (with Platform ID 0). In our example, it would look
for file 123.classname0 and such a lookup would fail since the .NET caller
created only file 123.classname1.
What the patch suggests is: during the execution of the java service from .Net
we lookup parameter ID not only for Java but also for .NET (if Java
registration not found). In our example we would first look for 123.classname0,
and, the it was not found then we would look for 123.classname1. The last
lookup would succeed and we would proceed with the service call.
I believe what you suggested was to register every type for both platforms - in
our example create both 123.classname0 and 123.classname1. Such a solution
would also work but I like it less due to duplication of the mapping files and
more changes in the 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: Nikolay Izhikov
> Priority: Major
> Labels: .NET, sbcf
> Attachments: IGNITE-10075-from-2.9.0.patch, MyTest.cs
>
> Time Spent: 20m
> 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 Apache.Ignite.Issue10075;
> public interface ICalculator {
> Result Calculate(Parameter p);
> }
> {code}
> h3. Parameter.java
> {code:java}
> package Apache.Ignite.Issue10075;
> public final 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 Apache.Ignite.Issue10075;
> public final 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 Apache.Ignite.Issue10075;
> import org.apache.ignite.services.Service;
> import org.apache.ignite.services.ServiceContext;
> public final 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 'apache.ignite.issue10075'
> version '1.0.0-SNAPSHOT'
> sourceCompatibility = 1.8
> repositories {
> mavenLocal()
> mavenCentral()
> }
> def igniteVer='2.9.0'
> dependencies {
> compile group: 'org.apache.ignite', name: 'ignite-core', version:
> igniteVer
> testCompile group: 'junit', name: 'junit', version: '4.12'
> }
> {code}
> h3. Apache.Ignite.Issue10075/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="Apache.Ignite.Issue10075.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. Apache.Ignite.Issue10075/ICalculator.cs
> {code:c#}
> namespace Apache.Ignite.Issue10075
> {
> public interface ICalculator
> {
> Result Calculate(Parameter p);
> }
> }
> {code}
> h3. Apache.Ignite.Issue10075/Parameter.cs
> {code:c#}
> namespace Apache.Ignite.Issue10075
> {
> public class Parameter
> {
> public int Id { get; set; }
> public double Value { get; set; }
> }
> }
> {code}
> h3. Apache.Ignite.Issue10075/Result.cs
> {code:c#}
> namespace Apache.Ignite.Issue10075
> {
> public class Result
> {
> public int Id { get; set; }
> public double Value { get; set; }
> }
> }
> {code}
> h3. Apache.Ignite.Issue10075/Program.cs
> {code:c#}
> using Apache.Ignite.Core;
> using System;
> namespace Apache.Ignite.Issue10075
> {
> class Program
> {
> static void Main(string[] args)
> {
> IgniteConfiguration CommonConfig(string name) => new
> IgniteConfiguration
> {
> IgniteInstanceName = name,
> SpringConfigUrl = "ignite-config.xml",
> JvmClasspath = "apache-ignite-issue10075-1.0.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}
> h3. Apache.Ignite.Issue10075/Apache.Ignite.Issue10075.csproj
> {code:java}
> <Project Sdk="Microsoft.NET.Sdk">
> <PropertyGroup>
> <OutputType>Exe</OutputType>
> <TargetFramework>netcoreapp3.1</TargetFramework>
> </PropertyGroup>
> <ItemGroup>
> <None Include="apache-ignite-issue10075-1.0.0-SNAPSHOT.jar">
> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
> </None>
> </ItemGroup>
> <ItemGroup>
> <PackageReference Include="Apache.Ignite" Version="2.9.0" />
> </ItemGroup>
> <ItemGroup>
> <None Update="ignite-config.xml">
> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
> </None>
> </ItemGroup>
> </Project> {code}
> h2. Actual Result Exception
> {code:java}
> Unhandled exception. Apache.Ignite.Core.Services.ServiceInvocationException:
> Proxy method invocation failed with an exception. Examine InnerException for
> details.
> ---> Apache.Ignite.Core.Common.IgniteException: Java exception occurred
> [class=org.apache.ignite.binary.BinaryInvalidTypeException,
> message=Requesting mapping from grid failed for [platformId=0,
> typeId=-960631211]]
> ---> Apache.Ignite.Core.Common.JavaException: class
> org.apache.ignite.binary.BinaryInvalidTypeException: Requesting mapping from
> grid failed for [platformId=0, typeId=-960631211]
> at
> org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:689)
> at
> org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1757)
> at
> org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1716)
> at
> org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:796)
> at
> org.apache.ignite.internal.binary.BinaryObjectImpl.deserialize(BinaryObjectImpl.java:637)
> at
> org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinary(PlatformUtils.java:927)
> at
> org.apache.ignite.internal.processors.platform.utils.PlatformUtils.unwrapBinariesInArray(PlatformUtils.java:995)
> at
> org.apache.ignite.internal.processors.platform.services.PlatformServices$ServiceProxyHolder.invoke(PlatformServices.java:593)
> at
> org.apache.ignite.internal.processors.platform.services.PlatformServices.processInObjectStreamOutObjectStream(PlatformServices.java:288)
> at
> org.apache.ignite.internal.processors.platform.PlatformTargetProxyImpl.inObjectStreamOutObjectStream(PlatformTargetProxyImpl.java:172)
> Caused by: java.lang.ClassNotFoundException: Requesting mapping from grid
> failed for [platformId=0, typeId=-960631211]
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:429)
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:384)
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:371)
> at
> org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:680)
> ... 9 more --- End of inner exception stack trace ---
> --- End of inner exception stack trace ---
> at
> Apache.Ignite.Core.Impl.Services.ServiceProxySerializer.ReadInvocationResult(IBinaryStream
> stream, Marshaller marsh, Boolean keepBinary)
> at
> Apache.Ignite.Core.Impl.Services.Services.<InvokeProxyMethod>b__2a(IBinaryStream
> stream, IPlatformTargetInternal res)
> at
> Apache.Ignite.Core.Impl.PlatformJniTarget.InObjectStreamOutObjectStream[TR](Int32
> type, Action`1 writeAction, Func`3 readAction, IPlatformTargetInternal arg)
> at Apache.Ignite.Core.Impl.PlatformTargetAdapter.DoOutInOp[TR](Int32 type,
> Action`1 outAction, Func`3 inAction, IPlatformTargetInternal arg)
> at
> Apache.Ignite.Core.Impl.Services.Services.InvokeProxyMethod(IPlatformTargetInternal
> proxy, String methodName, MethodBase method, Object[] args, PlatformType
> platformType)
> at
> Apache.Ignite.Core.Impl.Services.Services.<>c__DisplayClass22`1.<GetServiceProxy>b__21(MethodBase
> method, Object[] args)
> at Apache.Ignite.Issue10075.Program.Main(String[] args) in
> C:\Dev\github.com\kukushal\apache-ignite-issue10075\Apache.Ignite.Issue10075\Program.cs:line
> 25
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)