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

Remove OSGi annotations from the API #716

Closed
radcortez opened this issue Sep 17, 2021 · 15 comments · Fixed by #732
Closed

Remove OSGi annotations from the API #716

radcortez opened this issue Sep 17, 2021 · 15 comments · Fixed by #732
Labels
bug 🪲 An error in the implementation code or documentation

Comments

@radcortez
Copy link
Contributor

The OSGi annotations added in #381, cause annoying compiler warnings.

The issue is that we mark the OSGi dependencies as provided and a reference to org.osgi.annotation.bundle.Requirement.Resolution#OPTIONAL is missing from the dependencies when compiling a project that uses @ConfigProperty.

Adding the OSGi dependency as compile does fix the issue, but I believe an MP API should not transitively push this kind of dependency to their consumers (especially if they are not using OSGi).

This can be reproduced just by using the MP Config API JAR, use the @ConfigProperty annotation and compile code with warnings on: -Dmaven.compiler.showWarnings=true. It generates the following warning:

[WARNING] unknown enum constant org.osgi.annotation.bundle.Requirement.Resolution.OPTIONAL
  reason: class file for org.osgi.annotation.bundle.Requirement$Resolution not found

This causes confusion to users, and we should remove this warning.

@Emily-Jiang
Copy link
Member

@rotty3000 this is the annotation you added for OSGi CDI. If I remembered correctly, this annotation should not cause any issues for non-OSGi environament. Apparently it caused problems for Quarkus. We might have to remove these annotations if this can't be resolved.

@radcortez
Copy link
Contributor Author

Just a clarification, this has nothing to do with Quarkus. You can reproduce the warning just with the MP Config API jar and with compiler warnings turned on.

@rotty3000
Copy link
Contributor

Though this is not a runtime limitation in any way, I don't think I know a way to prevent the compiler warning based on how the annotation is designed (to use a enum as property value).

I would ask @bjhargrave for advice on this.

@bjhargrave
Copy link
Member

This is because the the osgi annotations jar is not a compile scope dependency of the eclipse microprofile config jar. Generally tools need to see annotation definitions to see if they may be meta-annotated with annotations the tool needs to process. Javadoc wants to look for Documented meta-annotations, Bnd wants to look for meta-annotations it must process. Javac is likely also wanting to do the same. Thus the warning to indicate there is an annotation whose definition cannot be examined.

The solution is for the eclipse microprofile config jar to have a compile scope dependency on the osgi.annotation jar which would provide javac, javadoc, etc. which visibility to the annotation definitions.

Based upon this feedback, we are making updates to the OSGi api jars about to be published for the Compendium Release 8 to make sure the maven pom metadata properly indicates the compile scope dependency on osgi.annotation.

@Emily-Jiang I can prepare a PR for eclipse microprofile config for this change (compile scope dependency on osgi.annotation) if you want.

@radcortez
Copy link
Contributor Author

Yes, I know that adding the OSGi dependency would fix the issue.

On the other hand, I think that we need to be very careful about this decision. Yes, I know it should be harmless, but by principle, I believe that the MP APIs shouldn't push any additional dependencies. This creates a blurred boundary on what it is acceptable to add as metadata from external APIs and what is not.

If other APIs would like to add their own metadata, should we add it as well and include their dependencies?

@bjhargrave
Copy link
Member

This is not pushing any runtime dependencies. This is about preventing compiler warnings (which are harmless but we should support clean builds) via compile time dependencies.

The OSGi annotations allow the artifacts to be OSGi-ready. A number of Microprofile stakeholders and users use OSGi as a module system and need the artifacts to be OSGi-ready. Without the OSGi annotations in the source code, the OSGi metadata would need to be manually maintained in the pom file (or external bnd file) and this would become out of date as developers forget or don't know to update the information. This is the value of annotations: the information is in the source code where the developers are working.

If other APIs would like to add their own metadata, should we add it as well and include their dependencies?

This is a slippery-slope argument and not very compelling. We have an actual need now for OSGi metadata in the artifacts. If other module systems (e.g. JPMS) need source code (e.g. module-info.java), I am sure Microprofile will do what is needed for the stakeholders and users of Microprofile. This sort of decision is best made when there are actual expressed needs rather than attempting to wave them away up front.

@famod
Copy link

famod commented Sep 28, 2021

I'm not at all familiar with the internals of MP Config, but have you ever considered shipping two flavours? One with and one without OSGi?

@jorsol
Copy link

jorsol commented Jan 27, 2022

Yes, please remove the OSGi annotations, any annotation that makes use of an enum creates an unnecessary dependency.

While using annotations improves the maintenance of OSGi metadata, there is an issue when those annotations use enums, I honestly think that until those annotations remove the enum coupling, the OSGi metadata should be maintained in the pom file or externally.

@Emily-Jiang
Copy link
Member

Emily-Jiang commented Jan 27, 2022

@rotty3000 please see the above comments. The use case is for OSGi specification to use MicroProfile Config. @jorsol I think it can be changed to compile dependency. I don't think moving to pom.xml is something OSGi specification can benefit from using the APIs at all. It depends on whether MicroProfile wants others to use this technology.

@renegrob
Copy link

renegrob commented Feb 6, 2022

I added the following snipped to my code to get rid of this annoying warning:

package org.osgi.annotation.bundle;

/**
 * Workaround for "warning: unknown enum constant Resolution.OPTIONAL" during compilation. This class is not used at runtime.
 * See also https://github.com/eclipse/microprofile-config/issues/716
 */
@SuppressWarnings("unused")
public class Requirement {
    public enum Resolution {
        OPTIONAL
    }
}

While this works it is an ugly hack. My question is, if this dependency is not required then why is it referenced. Somewhere seems to be a false dependency scope or a class in the wrong dependency. Or the package that depends on org.osgi.annotation.bundle should be moved to a separate artifact that then depends on it. Having warnings in the build that you just need to ignore and can't even switch off easily is just super annoying.

@jorsol
Copy link

jorsol commented Feb 6, 2022

The problem is those optional (or compile-only) annotations should NEVER use enums, so until the OSGi annotations are fixed and remove the enum dependency this will be a problem.

Enums make the code more type-safe, but if the annotations are intended to be used optionally or just at compile-time (for generation of metadata or source code), then using enums is definitely a bad practice.

@Emily-Jiang
Copy link
Member

@jorsol the dependency should be marked compiled instead of provided. Can make that change to get rid of the warning.

@jorsol
Copy link

jorsol commented Feb 7, 2022

The problem is that the dependency should not be of scope compiled, it's an optional dependency, the dependency should not end up in the final artifacts just by transitivity... yes, that will get rid of the warning, but the proper fix should be that the annotations get rid of the enums, in other words, the fix should be done in the annotations of the OSGi project.

I can just add the dependency (or if it's declared as compile this is pulled transitively):

<dependency>
    <groupId>org.osgi</groupId>
    <artifactId>osgi.annotation</artifactId>
    <version>8.0.1</version>
</dependency>

The result will be that a dependency ends up in the final application directory for no good reason. This is especially true for an annotation that the main purpose is to generate a bundle's manifest, there is no use of the dependency beyond that.

@famod
Copy link

famod commented Feb 7, 2022

FTR, I'm using following workaround in my Quarkus project (in root parent pom.xml):

        <!-- workaround for https://github.com/quarkusio/quarkus/issues/19970 -->
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>osgi.annotation</artifactId>
            <version>7.0.0</version>
            <scope>provided</scope>
        </dependency>

This way it at least doesn't end up in the production jar.

bjhargrave added a commit to bjhargrave/osgi that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

To address this, we replace the enum classes with simple classes holding
string constants and change the annotation elements returning the enum
values to return string values. This is generally source compatible
with usage of the OSGi annotations. Since these are CLASS retention
annotations, they are not visible at runtime and so only tools, like
Bnd, which process the annotations at tool time are affected.

Bnd 6.2 is being taught to seamlessly handle old and new annotations
using the old enum values or the new string values. So moving to using
the updated OSGi annotations will also require moving to use Bnd 6.2 or
later.

Signed-off-by: BJ Hargrave <[email protected]>
@bjhargrave
Copy link
Member

FYI, I am working a fix to the OSGi annotations to replace use of enum types with String along with a corresponding fix to Bnd to support this change.

bjhargrave added a commit to bjhargrave/osgi that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

To address this, we replace the enum classes with simple classes holding
string constants and change the annotation elements returning the enum
values to return string values. This is generally source compatible
with usage of the OSGi annotations. Since these are CLASS retention
annotations, they are not visible at runtime and so only tools, like
Bnd, which process the annotations at tool time are affected.

Bnd will seamlessly handle old and new annotations using the old enum
values or the new string values. So moving to using the updated OSGi
annotations will not require updating to use a newer version of Bnd.
Bnd 6.2 is being updated to better handle these changes including
validation of the string values since a string return type is open
ended while an enum return type is not.

Signed-off-by: BJ Hargrave <[email protected]>
bjhargrave added a commit to bjhargrave/bnd that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

To address this, we support the use of enum values or string values
as the annotation element value. This will support the OSGi change in
osgi/osgi#404

We seamlessly handle old and new annotations
using the old enum values or the new string values. So moving to using
the updated OSGi annotations will also require moving to use Bnd with
this fix.

Signed-off-by: BJ Hargrave <[email protected]>
bjhargrave added a commit to bjhargrave/bnd that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

We support the use of enum values or string values as the annotation
element value through existing conversion support. The OSGi change in
osgi/osgi#404 will move from using enum types
to use string values which are case-insensitive equivalent to the
enum value names.

We seamlessly handle old and new annotations using the old enum values
or the new string values. Prior to this fix, Bnd already handled the
change through a fallback in Converter which uppercased the string value
before converting to an internal enum value. This change avoids the
internal enum type and processes the string value or string name of the
enum value when processing older versions of the OSGi annotations.

Signed-off-by: BJ Hargrave <[email protected]>
bjhargrave added a commit to bjhargrave/osgi that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

To address this, we replace the enum classes with simple classes holding
string constants and change the annotation elements returning the enum
values to return string values. This is generally source compatible
with usage of the OSGi annotations. Since these are CLASS retention
annotations, they are not visible at runtime and so only tools, like
Bnd, which process the annotations at tool time are affected.

Bnd will seamlessly handle old and new annotations using the old enum
values or the new string values. So moving to using the updated OSGi
annotations will not require updating to use a newer version of Bnd.
Bnd 6.2 is being updated to better handle these changes including
validation of the string values since a string return type is open
ended while an enum return type is not.

Signed-off-by: BJ Hargrave <[email protected]>
bjhargrave added a commit to bjhargrave/bnd that referenced this issue Feb 7, 2022
Using enum types in the CLASS retention bundle annotations is causing
issues for those using the annotations. Various tools, such as javadoc,
attempt to reify the elements in the annotations and since the
osgi.annotation jar is generally a scope=provided dependency, the enum
types are not available to downstream users of the jars using the
OSGi annotations and so tools generates an annoying warning.

See quarkusio/quarkus#19970 and
eclipse/microprofile-config#716.

We support the use of enum values or string values as the annotation
element value through existing conversion support. The OSGi change in
osgi/osgi#404 will move from using enum values
to use string values which are equivalent to the former enum value
names.

We seamlessly handle old and new annotations using the old enum values
or the new string values. Prior to this fix, Bnd already handled the
change through the Converter which converts the string value to an
internal enum value. This change avoids the internal enum type and
processes the string value or string name of the enum value when
processing older versions of the OSGi annotations.

Signed-off-by: BJ Hargrave <[email protected]>
@radcortez radcortez linked a pull request Feb 11, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🪲 An error in the implementation code or documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants