-
Notifications
You must be signed in to change notification settings - Fork 220
Native Image Friendly #231
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
Native Image Friendly #231
Conversation
…r-test # Conflicts: # spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/TestController.java
@psycho-ir thanks! Change looks nice, I'll test it and merge if possible, even today :) |
@psycho-ir I've tested and it works like a harm. I've added integration test to the example so we can be sure that application is starting and at least it's possible to create CRD and CR. |
Thanks for the feedback @kirek007, if we decide that we want to go in this direction I'll make the code simpler and test a few cases that I think fails with the current implementation. |
This code will be removed as soon as kubernetes-client v5 will reach stable release (There is already MR with implementation #229) , at least for Doneable class. I still don't know if we should generate List class or leave it to the developer. I will check that. Personally I like that with this code we can start building native operators right now! I believe that it's worth investing to make it happen. I'd like to hear from @adam-sandor and @csviri what they thinks about it. |
Yup, sounds reasonable to use them. |
@kirek007 @psycho-ir We don't have to generate the list class, we can use the base class as it is now. |
Makes sense because then it's up to developer if he want's to cast List results to custom object or implement List class to have clear API. Ok, so this code will be removed when stable kubernetes-client 5.0 for quarkus will be available. |
Note that we're planning more improvements on the Custom Resource handling in the k8s client. See fabric8io/kubernetes-client#2611, ideas are welcome. |
The PR is ready for review. |
operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java
Outdated
Show resolved
Hide resolved
} catch (CannotCompileException | NotFoundException e) { | ||
throw new IllegalStateException(e); | ||
final Class<T> customResourceClass = getCustomResourceClass(controller); | ||
return (Class<? extends CustomResourceDoneable<T>>) Class.forName(customResourceClass.getCanonicalName() + "Doneable"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this work if the CR class is an inner class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it does work, haven't tested that with native-images yet though.
@kirek007 do you think we can have an integration test in example repository where has the CustomResource as inner class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll add this test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After while, I believe that we should test it here, not in example. We would like to introduce native build as a main feature of the SDK.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could add native build as a test step in next PR.
WDYT: @adam-sandor @csviri ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After while, I believe that we should test it here, not in example. We would like to introduce native build as a main feature of the SDK.
True, would be great to have it as one of the examples in this repository, will be easier to find for the users and also can be used as regression tests for future changes in the framework.
Code looks good to me, If @csviri and @adam-sandor doesn't have anything to add I would suggest merging it. |
@@ -37,7 +36,8 @@ static boolean getGenerationEventProcessing(ResourceController controller) { | |||
} | |||
|
|||
static <R extends CustomResource> Class<R> getCustomResourceClass(ResourceController<R> controller) { | |||
return (Class<R>) getAnnotation(controller).customResourceClass(); | |||
final Class<R> type = Arrays.stream(controller.getClass().getGenericInterfaces()).filter(i -> i instanceof ParameterizedType).map(i -> (ParameterizedTypeImpl) i).findFirst().map(i -> (Class<R>) i.getActualTypeArguments()[0]).get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the future we plan to have a hierarchy of controllers, so extend from an abstract controller. Thus this should be aware of inheritance. I think its not trivial to cover all possible scenarios, that was the reason it was explicit in the annotation. Are you sure this will handle all the cases?
@psycho-ir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very good point, the simplest solution would be searching for the interface we are interested in recursively, but that won't work with native-images as it's impossible to guarantee that reflection is enabled for the entire hierarchy.
I changed the annotation processor implementation to generate a file with a mapping of controller class names to custom resource names and used it here to get the class in one shot.
Changes are already committed, would be great if you could review it. Needs a little bit refactoring & cleanup though that I'll do tomorrow.
operator-framework/src/main/java/io/javaoperatorsdk/operator/ControllerUtils.java
Show resolved
Hide resolved
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@RegisterForReflection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only reason we have quarkus on classpath? Would be cleaner if we could do it without it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if somebody wan't to use quarkus, it can be added to the project. But if not its an unnecessary dependency on classpath.
However if there is no other way to do this, then we can let it here, since quarkus is a priority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, good point.
We can create project that will act like "springboot-starter" for quarkus. It will take of usign supported quarkus version and configuration of reflections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'm planning on doing that with #228.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my suggestion is to:
- Remove quarkus from this PR
- Because WIP: feat: make it possible to externally configure the operator #228 is getting quite big let's open new PR dedicated only for implementing quarkus starter
If @metacosm don't mind I can take care of this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, I'm not sure that native compilation will work properly without using RegisterForReflection
… I also think we should merge #229 as soon as possible because that will simplify a lot of things by removing the need to deal with Doneable
classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kirek007 another aspect is also that #228 tries to extract the configuration parts from the Spring Boot starter so that it could be reused in a Quarkus extension instead of duplicating the code so I really think that it should get done sooner rather than later. That said, I'm not quite satisfied with how it currently is, in terms of configuration I mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove the Quarkus dependency from here, the other way to achieve the same is generating a ReflectionConfigurationFile in compile time (just like what Quarkus is doing with the annotations). Can be done in the new module that will be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be great @psycho-ir
…annotation-processor-test
operator-framework/pom.xml
Outdated
</plugin> | ||
</plugins> | ||
</build> | ||
<profiles> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't that be removed now that we only target Java 11+?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psycho-ir, this should be removed, because we support only 11+ (it's already in master)
Any idea of when this will be merged, @psycho-ir @csviri ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove all quarkus dependencies and then I'll be able to test it and merge finally.
operator-framework/pom.xml
Outdated
</plugin> | ||
</plugins> | ||
</build> | ||
<profiles> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psycho-ir, this should be removed, because we support only 11+ (it's already in master)
operator-framework/pom.xml
Outdated
<groupId>org.javassist</groupId> | ||
<artifactId>javassist</artifactId> | ||
<version>3.27.0-GA</version> | ||
<groupId>io.quarkus</groupId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove quarkus dependency, we'll add it in dedicated module
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@RegisterForReflection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to quarkus dependency and should be removed
|
||
|
||
final TypeSpec typeSpec = TypeSpec.classBuilder(doneableClassName) | ||
.addAnnotation(RegisterForReflection.class) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This annotation won't compile after removing quarkus-core
import io.fabric8.kubernetes.client.CustomResourceDoneable; | ||
import io.quarkus.runtime.annotations.RegisterForReflection; | ||
|
||
@RegisterForReflection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't compile after removing quarkus-core
As soon as all request changes will be resolved :) |
I removed quarks dependency, practically means this changeset wouldn't be adequate to support Quarkus native builds. |
@psycho-ir You mean, there will be new maven module within this PR? Or you intend to do that a separate PR? |
If you don't mind I would like to merge this one, and move quarkus work to separate branch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@psycho-ir You mean, there will be new maven module within this PR? Or you intend to do that a separate PR?
If you don't mind I would like to merge this one, and move quarkus work to separate branch
Sure I'm fine with that.
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@RegisterForReflection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if somebody wan't to use quarkus, it can be added to the project. But if not its an unnecessary dependency on classpath.
However if there is no other way to do this, then we can let it here, since quarkus is a priority.
operator-framework/pom.xml
Outdated
<profile> | ||
<id>java8</id> | ||
<activation> | ||
<jdk>1.8</jdk> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still valid? I guess this needs to be java 11
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@RegisterForReflection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be great @psycho-ir
@csviri @kirek007 Sorry I wasn't clear, yes I meant a new module will be needed but not in the scope of this PR. |
Keeping the annotation for sure makes the integration with Quarkus way simpler. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@kirek007 Here is the PoC.
You should be able to run the https://github.com/java-operator-sdk/basic-native-operator-example/tree/init with this version of the SDK with no need to define neither the donable class nor the custom resource class in @controller annotation.
closes #224