Skip to content
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

Expose ArchetypeGenerator and ArchetypeManager #922

Closed

Conversation

kwin
Copy link
Member

@kwin kwin commented Sep 21, 2022

This closes #921

@kwin kwin force-pushed the feature/expose-archetype-generator branch 2 times, most recently from 34a5d55 to c0ab7c4 Compare September 21, 2022 17:25
@kwin
Copy link
Member Author

kwin commented Sep 22, 2022

@laeubi The compilation inside Eclipse works fine and org.eclipse.m2e.core.ui list sorg.osgi.annotation.versioning_1.1.2.202109301733.jar as plug-dependency. Still Tycho cannot compile and fails with

Error:  Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:2.7.4:compile (default-compile) on project org.eclipse.m2e.core.ui: Compilation failure: Compilation failure: 
Error:  /home/runner/work/m2e-core/m2e-core/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenDependenciesWizardPage.java: 
Error:  	/*******************************************************************************
Error:  	^
Error:  The type org.osgi.annotation.versioning.Version cannot be resolved. It is indirectly referenced from required .class files
Error: [ERROR] 1 problem (1 error)
Error:  -> [Help 1]

The target file though contains the bundle org.osgi.annotation.versioning so I am puzzled why Tycho does not pick up that dependency....

@laeubi
Copy link
Member

laeubi commented Sep 22, 2022

The target file though contains the bundle org.osgi.annotation.versioning so I am puzzled why Tycho does not pick up that dependency....

I think the problem is that Tycho 2.4 is used here.

Copy link
Contributor

@mickaelistria mickaelistria left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just moving this is IMO not enough. We need to audit what are the real operations necessary to be exposed for clients to efficiently use the Archetype API here. Many operations in the promoted APIs can probably remain implementation-internal and should then be so.

@kwin
Copy link
Member Author

kwin commented Sep 22, 2022

Just moving this is IMO not enough. We need to audit what are the real operations necessary to be exposed for clients to efficiently use the Archetype API here.

The reasoning is in #921. This PR obviously just contains the code changes.

@kwin kwin changed the title Expose ArchetypeGenerator Expose ArchetypeGenerator and ArchetypeManager Sep 22, 2022
@mickaelistria
Copy link
Contributor

The reasoning is in #921.

The reasoning "it was this way before" is not viable. The API was removed in this major version because it wasn't appearing as useful to anyone involved regularly in the development of m2e. That is already a sign that the API state should be challenged and not cloned for the future of m2e. If we're to reopen an API, it can and should be a minimal one, just like if we were starting it from scratch.
What is the particular methods you're using in your code? We should just start by exposing as API and keep everything else internal until we have a good story to promote them.

@kwin
Copy link
Member Author

kwin commented Sep 22, 2022

@mickaelistria
Copy link
Contributor

So you would only need a way to run something like archetypeGenerator.createProject(Archetype, ...) ?

@laeubi
Copy link
Member

laeubi commented Sep 22, 2022

@kwin I think Tycho support requires version 3.0.0 what will be released end of month for those annotations.

public interface ArchetypeGenerator {

/**
* Creates project structure using the given archetype and then imports created project(s)
Copy link
Member Author

@kwin kwin Sep 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This javadoc (although just copied from ArchetypeGeneratorImpl) seems to require an update, as Eclipse projects are no longer created by this method.

@HannesWell
Copy link
Contributor

@kwin if you rebase on top of the current master, some (maybe all) of the CI failures should vanish.

@kwin
Copy link
Member Author

kwin commented Sep 29, 2022

Before I rebase and adjust the tests I would like to know if you are fine with the proposed API exposure.

@laeubi
Copy link
Member

laeubi commented Oct 5, 2022

@mickaelistria any more comments regarding API? I think this would be good to make a release after this so @kwin can adapt to the changes...

Copy link
Contributor

@mickaelistria mickaelistria left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fresher and a well focused API! I just have a couple of questions/comments inline.

Also expose necessary MavenArchetype (as the only implementation of
IArchetype)

This closes eclipse-m2e#921
@kwin kwin force-pushed the feature/expose-archetype-generator branch from ca61f5a to d39e00f Compare October 5, 2022 15:36
@@ -74,8 +77,8 @@
*
* @author Eugene Kuleshov
*/
@Component(service = ArchetypePlugin.class)
public class ArchetypePlugin {
@Component(service = {ArchetypeManager.class, ArchetypePlugin.class})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ArchetypePlugin should not be exposed as a service here

Copy link
Member Author

@kwin kwin Oct 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not possible, as the ArchetypePlugin is the internal API which is used. If you would only register as ArchetypeManager (public API) you would need to cast in M2EUIPluginActivator. How do you want to get hold of this without casting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal code can cast to internal Implementations but this should not be used as declared services (wich are exposed to everyone in the OSGi framework!)

Copy link
Member Author

@kwin kwin Oct 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are exporting internal packages and by that exposing them to everyone in the framework anyways, but I am open to other suggestions. In case you prefer casting, what should happen if the implementation does not implement ArchetypePlugin? DS allows to replace one service implementation with another one!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also remember that you previously registered only to the internal API ArchetypePlugin via DS, so that pattern is not something I introduced.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DS allows to replace one service implementation with another one!
This has nothing to do with DS, anyways you would be most likely wrecked then anyways. If you want be extra you can assert the type with instanceof and throw an exception otherwise...

Also remember that you previously registered only to the internal API ArchetypePlugin via DS, so that pattern is not something I introduced.

Many thing in m2e need improvements and some are just for migrating thing so we should not take this as good examples when refactoring/rework things.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn’t make this a prerequisite. It can be improved by someone else in a follow up

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Softwaredevelopment "later" often means "never" :-)

I would prefer to have a cast on the cases where it is required (that is we use no API method) as this is already done elsewhere in m2e and shows where we have an API gap...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, fixed in 0306f85.

* @since 2.1.0 (package version 1.0.0)
*/
@ProviderType
public interface ArchetypeManager {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is ArchetypeManager public? Should ArchetypeGenerator not be enough?

@laeubi
Copy link
Member

laeubi commented Oct 6, 2022

Looks good so far, just wondering if we really need to make ArchetypeManager public?

@laeubi
Copy link
Member

laeubi commented Oct 6, 2022

ArchetypeManager is used e.g.

But all these should be m2e internal, so can we not make ArchetypeManager internal as well?

@kwin
Copy link
Member Author

kwin commented Oct 6, 2022

I use it outside of m2e, so I prefer using it with an API. I don't want to depend on internal API for my use case which was the original driver for this PR.

@laeubi
Copy link
Member

laeubi commented Oct 6, 2022

I use it outside of m2e, so I prefer using it with an API. I don't want to depend on internal API for my use case which was the original driver for this PR.

Can you explain how you use this? Do you provide own UI wizard? The main problem with this (and why it was decided to make this "non API") is that the Archetype is a separate plugin, so exposing its classes directly has two problems:

  1. We need to make people depend on a specific ArcheType version (that is the one embedded in m2e) and we only support it partially, e.g. some classes will throw CNF because we only embedd the bar minimum of stuff.
  2. If we update the ArcheType version and that API changes, this is actually an API break for m2e even though nothing was changed here.

This has lead to the situation that previously m2e a very long time relied on outdated Archetype 2.x. and it was quite hard to upgrade to 3.x. The result is/was the IArcheType facade interface that exposed the bare minimum required.

Can you check if for your use-case something similar would be possible to have (read only) facade types with a reduced signature for RequiredProperty and ArchetypeCatalog?

@kwin
Copy link
Member Author

kwin commented Oct 6, 2022

We are going in circles here, I cannot explain better than above: #922 (comment). Have you checked the code?

@laeubi
Copy link
Member

laeubi commented Oct 6, 2022

@kwin sorry I mixed that up with a previous comment from usages inside m2e.

About ChooseArchetypeWizardPage what do you think of instead Map<String, ArchetypeCatalog> getActiveArchetypeCatalogs() throws CoreException; having a method Stream<IArcheType> getArchetypes() throws CoreException? Would this be sufficient? It seems thats what actually is computed in that code there?

@laeubi
Copy link
Member

laeubi commented Oct 6, 2022

About ArchetypeParametersWizardPage do you think you probably would reuse the m2e page? It also supports parameter validation through regexp now, otherwhise I think we can have an IRequiredProperty facade that wraps the maven RequiredPropertywith just the getters required here.

@TIBCOeddie
Copy link
Contributor

Our product uses the ArchetypeGenerator and friends. Is there still time to look at something and provide comments?

@laeubi
Copy link
Member

laeubi commented Oct 12, 2022

I think best would be too finish this PR and then if there are still things missing start with a new PR.

@HannesWell
Copy link
Contributor

I think best would be too finish this PR and then if there are still things missing start with a new PR.

If it directly about what is changed in this PR I think comments should be made now. Of course it can be started again afterwards, but if possible why not consider them now but later?
If it is more an extension I agree that doing it step by step is better. :)

@HannesWell
Copy link
Contributor

@kwin can you please rebase this change on top of the current master?


/**
* Creates a project structure using the given archetype in non-interactive mode.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please have javadoc for params, or you'll get all the javadoc warnings especially since j17+ have turned it up, and for sure it's always a pity to not have these! esp handy is what can be null, what is optional, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember our integration had to dive into source to understand what "interactive mode" was

* Gets the required properties of an {@link IArchetype}.
*
* @param archetype the archetype possibly declaring required properties
* @param remoteArchetypeRepository the remote archetype repository, can be null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

param is not in sync with actual

* @param archetype the archetype possibly declaring required properties
* @param remoteArchetypeRepository the remote archetype repository, can be null
* @param monitor the progress monitor, can be null
* @return the required properties of the archetypes, null if none is found
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when your signature has a list, isn't it eclipse code guidelines to not return null and return an empty list instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, it's generally a good practice to not return null for Arrays or Collections but empty ones; not only for Eclipse but for Java in general.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better return an Optional<...> instead then. There is a difference between an Archetype not found and having no required properties... one might even throw a CoreException if not found here ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better return an Optional<...> instead then.

I don't think so.

There is a difference between an Archetype not found and having no required properties..

Maybe, but that's not the goal of this method to detect that an Archetype is not found. But your comment here emphasize that documentation is ambiguous and that there are different ways to interpret none.

one might even throw a CoreException if not found here ...

CoreException is just an abstract exception in Eclipse world; creating a custom exception type would be better for an API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better return an Optional<...> instead then.

I don't think so.

Why? Either is is optional (because it is fine / could happen) but then it is not valid to just return an empty list if nothing is found as a user of that method then falsely assumes everything is fine and one could potentially call this archetype (what will just fail because it is not found)...

Maybe, but that's not the goal of this method to detect that an Archetype is not found. But your comment here emphasize that documentation is ambiguous and that there are different ways to interpret none.

Obviously there is a way to detect this, so either it is an error (= exception must be thrown) or a user has to be able to distinguish the cases.

@mickaelistria
Copy link
Contributor

Why? Either is is optional (because it is fine / could happen) but then it is not valid to just return an empty list if nothing is found as a user of that method then falsely assumes everything is fine and one could potentially call this archetype (what will just fail because it is not found)...

There is a lot of literature against null collections, the most "reference" one being the "Effective Java" book, Your comment is based IMO on a dogmatic vision of API development; but experience of the whole Java (and other languages as well) community has concluded that returning null collections is more an anti-pattern than a benefit.

Obviously there is a way to detect this, so either it is an error (= exception must be thrown) or a user has to be able to distinguish the cases.

Or maybe we just don't care about distinguishing, do we? Or maybe since we have an Archetype object as parameter, then we can assume that this Archetype exists and is found already.

@laeubi
Copy link
Member

laeubi commented Oct 21, 2022

There is a lot of literature against null collections,

And how does it relates to returning an empty Optional in case nothing could be computed here?

Or maybe we just don't care about distinguishing, do we? Or maybe since we have an Archetype object as parameter, then we can assume that this Archetype exists and is found already.

The parameter is just a simple container object and obviously the creator of that method has taken into account that the archetype is not present.

@mickaelistria
Copy link
Contributor

Given the comments, it seems like the overall design of those APIs is then questionable as they come with very poor guarantee about validity and lifecycle of instances.

So the current IArchetype is not an IArchetype then, it's just a GAV which is more used as an ArchetypeRequest. If I have an IArchetype, in a good API, I expect the archetype exists. The issue is then not what to do with a non existing IArchetype, it's that the API should ensure an IArchetype maps to something existing.
In the current state, I'd suggest removing the IArchetype.of method which is just a GAV, and even deprecating the IArchetype interface; or to make the IArchetype interface host the method to query parameters and other stuff and let only the ArchetypeManager create the IArchetype instance if this one does exists.

@HannesWell
Copy link
Contributor

What's the status here?

@laeubi
Copy link
Member

laeubi commented Dec 3, 2022

@kwin please rebase and resolve conflicts.

@laeubi
Copy link
Member

laeubi commented Mar 6, 2023

Closing this for now as no progress and no response, but feel fre to just reopen or provide a new PR on the top of the master branch.

@laeubi laeubi closed this Mar 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API missing for creating archetype projects and to refresh archetype catalog
5 participants