apollo-kotlin
apollo-kotlin copied to clipboard
Linking globals named 'OBJC_CLASS_$_GatewayApiLong': symbol multiply defined!
Summary
I am testing using the Kotlin Multiplatform version of Apollo. Our schema works fine when compiling for android but we are getting the above error when building iOS library : ./gradlew clean gateway_api:iosX64MainBinaries
Version 3.3.2
Description Add context about the problem here. How it happened and how to reproduce it:
Our schema has no scalar Long
declaration but there are quite a few places that use an adhoc scalar Long definition in fields (e.g. below)
I am guessing this is the cause of the above error so I wanted to check if simply declaring a scalar Long
in the schema and using it for fields would be the correct solution? As it might quite a big change for our organization.
Or is there some compilation flag i could add that would ignore this error?
i have also tried adding codegenModels.set("responseBased")
and modifying our code to use this codegen structure - but i ended up getting the same error after the change.
{
"name": "netUnitsSold",
"description": "Net unit sold across aggregation",
"args": [],
"type": {
"kind": "SCALAR",
"name": "Long",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
This is the error stacktrace when executing ./gradlew clean gateway_api:iosX64MainBinaries
- same for pod install
in XCode.
> Task :gateway_api:linkPodDebugFrameworkIosX64 FAILED
e: Compilation failed: Linking globals named 'OBJC_CLASS_$_GatewayApiLong': symbol multiply defined!
* Source files:
* Compiler version info: Konan: 1.6.21 / Kotlin: 1.6.21
* Output kind: FRAMEWORK
e: java.lang.Error: Linking globals named 'OBJC_CLASS_$_GatewayApiLong': symbol multiply defined!
at org.jetbrains.kotlin.backend.konan.llvm.DefaultLlvmDiagnosticHandler.handle(diagnosticReport.kt:24)
at org.jetbrains.kotlin.backend.konan.llvm.LlvmDiagnosticCollector.flush(diagnostics.kt:36)
at org.jetbrains.kotlin.backend.konan.llvm.LinkModulesKt.llvmLinkModules2(linkModules.kt:36)
at org.jetbrains.kotlin.backend.konan.llvm.objc.LinkObjCKt.linkObjC(linkObjC.kt:32)
at org.jetbrains.kotlin.backend.konan.CompilerOutputKt.linkAllDependencies(CompilerOutput.kt:81)
at org.jetbrains.kotlin.backend.konan.CompilerOutputKt.linkBitcodeDependencies(CompilerOutput.kt:125)
at org.jetbrains.kotlin.backend.konan.llvm.BitcodePhasesKt$linkBitcodeDependenciesPhase$1.invoke(BitcodePhases.kt:349)
at org.jetbrains.kotlin.backend.konan.llvm.BitcodePhasesKt$linkBitcodeDependenciesPhase$1.invoke(BitcodePhases.kt:346)
at org.jetbrains.kotlin.backend.konan.KonanLoweringPhasesKt$makeKonanModuleOpPhase$1.invoke(KonanLoweringPhases.kt:65)
at org.jetbrains.kotlin.backend.konan.KonanLoweringPhasesKt$makeKonanModuleOpPhase$1.invoke(KonanLoweringPhases.kt:63)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:22)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:43)
at org.jetbrains.kotlin.backend.konan.KonanDriverKt.runTopLevelPhases(KonanDriver.kt:34)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:88)
at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:37)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:91)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:43)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:93)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:71)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:40)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:168)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithGradleRenderer$1.invoke(K2Native.kt:412)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion$mainNoExitWithGradleRenderer$1.invoke(K2Native.kt:411)
at org.jetbrains.kotlin.util.UtilKt.profileIf(Util.kt:22)
at org.jetbrains.kotlin.util.UtilKt.profile(Util.kt:16)
at org.jetbrains.kotlin.cli.bc.K2Native$Companion.mainNoExitWithGradleRenderer(K2Native.kt:411)
at org.jetbrains.kotlin.cli.bc.K2NativeKt.mainNoExitWithGradleRenderer(K2Native.kt:666)
at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMain$1.invoke(main.kt:62)
at org.jetbrains.kotlin.cli.utilities.MainKt$daemonMain$1.invoke(main.kt:62)
at org.jetbrains.kotlin.cli.utilities.MainKt.mainImpl(main.kt:17)
at org.jetbrains.kotlin.cli.utilities.MainKt.daemonMain(main.kt:62)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.runInProcess(KotlinToolRunner.kt:136)
at org.jetbrains.kotlin.compilerRunner.KotlinToolRunner.run(KotlinToolRunner.kt:81)
at org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink.compile(KotlinNativeTasks.kt:657)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:242)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:227)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:210)
at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:193)
at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:171)
at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:89)
at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:40)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:53)
at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:50)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:40)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:61)
at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:42)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:60)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:27)
at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:180)
at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:75)
at org.gradle.internal.Either$Right.fold(Either.java:175)
at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:73)
at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:48)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:110)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:56)
at java.base/java.util.Optional.orElseGet(Optional.java:362)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:56)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:73)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:44)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:89)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:50)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:114)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:57)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:76)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:249)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:204)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:83)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:54)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43)
at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:287)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:144)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:133)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:333)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:320)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:313)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:299)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:143)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:227)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:218)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:140)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:830)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':gateway_api:linkPodDebugFrameworkIosX64'.
> Compilation finished with errors
Hi! Thanks for reporting this!
This doesn't immediately ring a bell 🤔
However I'm not sure I understand what you mean by "Our schema has no scalar Long" - if the netUnitsSold
field shown above is of type Long
then it must be declared in the schema?
On the other hand, if that wasn't the case, Apollo Kotlin should have emitted something like "Unknown type Long
".
In any case if possible, it would help a lot if you could share a project so that we can reproduce and investigate this (if this can't be shared publicly feel free to send it to [email protected]) 🙏
hi, yes sorry it is actually declared i missed it before.
In the header file generated i can see that interface (GatewayApiLong) is actually generated twice - just have to check with the org what i can share. so i'll get back soon.
thanks for the quick response.
Thanks! Are you in a multi-module setup by any chance (wondering if it could be a type clash).
Each schema is in it's own kmp module. The other module is very simple - it compiles fine and I can use it in the ios app. This gateway_api module has the bulk of the operations though.
in the generated GatewayApi.h the conflicting interfaces are:
__attribute__((swift_name("KotlinLong")))
@interface GatewayApiLong : GatewayApiNumber
- (instancetype)initWithLongLong:(long long)value;
+ (instancetype)numberWithLongLong:(long long)value;
@end;
and
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("Long")))
@interface GatewayApiLong : GatewayApiBase
- (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer));
+ (instancetype)new __attribute__((availability(swift, unavailable, message="use object initializers instead")));
@property (class, readonly, getter=companion) GatewayApiLongCompanion *companion __attribute__((swift_name("companion")));
@end;
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("Long.Companion")))
@interface GatewayApiLongCompanion : GatewayApiBase
+ (instancetype)alloc __attribute__((unavailable));
+ (instancetype)allocWithZone:(struct _NSZone *)zone __attribute__((unavailable));
+ (instancetype)companion __attribute__((swift_name("init()")));
@property (class, readonly, getter=shared) GatewayApiLongCompanion *shared __attribute__((swift_name("shared")));
@property (readonly) GatewayApiApollo_apiCustomScalarType *type __attribute__((swift_name("type")));
@end;
So possibly the declared scalar Long
in our schema is conflicting with the KotlinLong
from the default KotlinNumber
interfaces?
__attribute__((swift_name("KotlinNumber")))
@interface GatewayApiNumber : NSNumber
- (instancetype)initWithChar:(char)value __attribute__((unavailable));
- (instancetype)initWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
- (instancetype)initWithShort:(short)value __attribute__((unavailable));
- (instancetype)initWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
- (instancetype)initWithInt:(int)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
- (instancetype)initWithLong:(long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
- (instancetype)initWithLongLong:(long long)value __attribute__((unavailable));
- (instancetype)initWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
- (instancetype)initWithFloat:(float)value __attribute__((unavailable));
- (instancetype)initWithDouble:(double)value __attribute__((unavailable));
- (instancetype)initWithBool:(BOOL)value __attribute__((unavailable));
- (instancetype)initWithInteger:(NSInteger)value __attribute__((unavailable));
- (instancetype)initWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
+ (instancetype)numberWithChar:(char)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedChar:(unsigned char)value __attribute__((unavailable));
+ (instancetype)numberWithShort:(short)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedShort:(unsigned short)value __attribute__((unavailable));
+ (instancetype)numberWithInt:(int)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInt:(unsigned int)value __attribute__((unavailable));
+ (instancetype)numberWithLong:(long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLong:(unsigned long)value __attribute__((unavailable));
+ (instancetype)numberWithLongLong:(long long)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedLongLong:(unsigned long long)value __attribute__((unavailable));
+ (instancetype)numberWithFloat:(float)value __attribute__((unavailable));
+ (instancetype)numberWithDouble:(double)value __attribute__((unavailable));
+ (instancetype)numberWithBool:(BOOL)value __attribute__((unavailable));
+ (instancetype)numberWithInteger:(NSInteger)value __attribute__((unavailable));
+ (instancetype)numberWithUnsignedInteger:(NSUInteger)value __attribute__((unavailable));
@end;
i don't know if that helps - still checking about the schema but it might take a few days .. sorry
Ooh good catch, yes this is probably the culprit. Can you try to rename the Long
scalar definition and usage to, for instance, MyLong
in your schema, to see if that resolves the issue?
By the way, I noticed above you showed part of your schema in json, but you can convert it to SDL instead, which is more user-friendly:
./gradlew convertApolloSchema --from=src/main/graphql/schema.json --to=src/main/graphql/schema.graphqls
It a corporate schema. So company wide. Probably you might need to change the namespaciing a bit? It's not urgent tho.
Possibly the numerical interfaces could be Klong
etc? Just an idea..
Eg
__attribute__((swift_name("KotlinLong")))
@interface GatewayApiKotlinLong : GatewayApiNumber
In this PR, we're adding an (experimental) @targetName
directive that you can set on your scalar declaration (by extending it), which will be used to chose the corresponding generated Kotlin type name. You will be able to use it like this:
# In a new file named extra.graphqls, next to your schema.graphqls
extend scalar Long @targetName(name: "GatewayApiLong")
In the meantime, you can still rename the Long
scalar in your schema, locally on your project, and that should probably work.
yes looks like that should work. I'm not sure how common it is for users to declare a scalar type with a name the same as a kotlin type (Integer, Long, Char, etc). I guess this would work for all those cases though.
when do you think it would be released? it not really urgent atm though. as we are just testing things out.
The @targetName
directive has just been merged, so this will be in the next release, in the meantime it can be tried out with the snapshots.
on nice ... i'll give it a whirl
So i am trying this out. I have got the 3.4.1-SNAPSHOT
in the project - i can see it loaded
I have extra.graphqls
:
# In a new file named extra.graphqls, next to your schema.graphqls
extend scalar Long @targetName(name: "GatewayApiMyLong")
but it shows errors:
The extension 'Long' type is missing its base underlying type
'Long' tried to use an undeclared directive 'targetName'
Wondering if you have any suggestions for checking it?
Thanks for trying it out! Just making sure, are these messages you're seeing in the IDE? It's possible the directive is not known to the GraphQL plugin, so it highlights it as an error, but it will still compile OK. You can have a look at the generated code which should be in the build/generated/source/apollo/
folder of your module.
it still the same error - so looks like it not getting picked up for some reason
./gradlew clean gateway_api:iosX64MainBinaries
e: Compilation failed: Linking globals named 'OBJC_CLASS_$_GatewayApiLong': symbol multiply defined!
* Source files:
* Compiler version info: Konan: 1.6.21 / Kotlin: 1.6.21
* Output kind: FRAMEWORK
e: java.lang.Error: Linking globals named 'OBJC_CLASS_$_GatewayApiLong': symbol multiply defined!
the generated Long
class is
package com.wayfair.partners.gateway.api.type
import com.apollographql.apollo3.api.CustomScalarType
public class Long {
public companion object {
public val type: CustomScalarType = CustomScalarType("Long", "kotlin.Any")
}
}
Hmm this is odd indeed. The class should be named GatewayApiMyLong
. Could this be a cache issue (have you tried to clean/rebuild?). I also pushed a mini project here that generates the correct class name, maybe you can catch any difference with your setup?
@sentinelweb anything else we can help with here?
sorry i missed you message - i couldn't get this to work for our use case, i cleaned and rebuilt, etc - but luckily for us the offending Long scalar declaration was move to another module so the conflict disappeared.
@BoD @martinbonnin I am seeing this issue in my Multiplatform project on the latest version of Apollo, even with the extra.graphqls
solution above. Any suggestions on a way to handle this without forcing the upstream API to make changes?
Hi @allenwhite. If you added the @targetName
directive, can you check in the generated files (<yourmodule>/build/generated/source/apollo/service/com/example/type
), if you see one named Long.kt
? You should not see it but see MyLong.kt
(or the name you picked).
@BoD Thanks for getting back to me. Yeah I checked, I see Long.kt
and the default implementation there, despite having added the @targetName
directive.
@allenwhite Just to be sure: which version of Apollo are you on? Is the extra.graphqls
file next to the schema.graphqls
one (like in this sample)?
@BoD I initially saw on an earlier version of Apollo, and updated to the latest (3.8.0) but still saw the issue. And yupp, I have that file right next to the schema file.
@allenwhite Would it be possible for you to provide a minimal barebones version of your project so we can have a look? (If this can't be public, you can share it to my email: [email protected])
Just shot something over to you @BoD . Thanks!
Thanks a lot! This helped identify the issue.
For the posterity in case other people have the same issue: Apollo was explicitly configured with schemaFile.set(...)
which excludes the extra.graphqls
file from being considered. Removing the option solved the issue (all schema files in src/commonMain/graphql
are included by default).