You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Łukasz Dywicki <lu...@code-house.org> on 2017/01/24 13:04:54 UTC

Custom range resolver

I been digging with my collegue aroudn maven ranges for some time and
we reached point where we would like to customize them. Because we are
using OSGi and maven resolver embedded in Karaf (which is also aether
based) and also some version ranges in XML descriptors (which are
interpreted as osgi ranges) we ended up having a certain gap. The
major problem is lower and upper bound inclusion/excllusion. As found
in ealier mails from this month 2.0.0-SNAPSHOT is smaller than 2.0.0
meaning it is included in [1,2) range. I managed to get rid of this
inclusion by using 1.max bound: [1,1.max], but then 1.0.0-SNAPSHOT is
not in the range. To avoid that I did [1.min, 1.max] range. So far so
good, but lower and upper bound in osgi will not work. When I will
install 1.0.0.SNAPSHOT (which is 1.0.0-SNAPSHOT in maven) it will not
match 1.0.0.min range because osgi treats qualifier with "startsWith"
logic. It is not aware of what snapshot means, for osgi framework its
just a string sequence.

I know ranges in build might be wrong, but I know how to use them and
I use them together with osgi so I am sure my build results will
match.

I managed to complete a code which embeds osgi range resolution inside
aether's VersionRangeResolver implementation. It is straight forward,
covered by simple tests and works as expected. Even if its not working
as expected it can be found by unit tests and fixed. What is hardest
for me now is binding this resolver into build so maven's
implementation of VersionRangeResolver gets replaced by mine. For this
reason I created .mvn/extensions.xml inside project root with my
artifact id:

<?xml version="1.0" encoding="UTF-8"?>
<extensions>
    <extension>
        <groupId>org.code-house.maven</groupId>
        <artifactId>osgi</artifactId>
        <version>3.3.9-SNAPSHOT</version>
    </extension>
</extensions>

During launch with verbose output I see my extension loaded:
[DEBUG] org.code-house.maven:osgi:jar:3.3.9-SNAPSHOT:
[DEBUG]    org.apache.maven:maven-core:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-model:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-settings:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-settings-builder:jar:3.3.9:compile
[DEBUG]          org.apache.maven:maven-builder-support:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-repository-metadata:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-artifact:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-plugin-api:jar:3.3.9:compile
[DEBUG]       org.apache.maven:maven-model-builder:jar:3.3.9:compile
[DEBUG]       org.eclipse.aether:aether-util:jar:1.0.2.v20150114:compile
[DEBUG]       org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.2:compile
[DEBUG]          javax.enterprise:cdi-api:jar:1.0:compile
[DEBUG]             javax.annotation:jsr250-api:jar:1.0:compile
[DEBUG]          org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.2:compile
[DEBUG]       com.google.inject:guice:jar:no_aop:4.0:compile
[DEBUG]       org.codehaus.plexus:plexus-interpolation:jar:1.21:compile
[DEBUG]       org.codehaus.plexus:plexus-utils:jar:3.0.22:compile
[DEBUG]       org.codehaus.plexus:plexus-classworlds:jar:2.5.2:compile
[DEBUG]       org.codehaus.plexus:plexus-component-annotations:jar:1.6:compile
[DEBUG]       org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
[DEBUG]          org.sonatype.plexus:plexus-cipher:jar:1.4:compile
[DEBUG]       org.apache.commons:commons-lang3:jar:3.4:compile
[DEBUG]    org.eclipse.aether:aether-api:jar:1.0.2.v20150114:compile
[DEBUG]    org.eclipse.aether:aether-impl:jar:1.0.2.v20150114:compile
[DEBUG]       org.eclipse.aether:aether-spi:jar:1.0.2.v20150114:compile
[DEBUG]    com.google.inject:guice:jar:4.0:compile
[DEBUG]       javax.inject:javax.inject:jar:1:compile
[DEBUG]       aopalliance:aopalliance:jar:1.0:compile
[DEBUG]       com.google.guava:guava:jar:16.0.1:compile
[DEBUG]    org.osgi:org.osgi.core:jar:6.0.0:compile
[DEBUG]    org.slf4j:slf4j-log4j12:jar:1.7.22:compile
[DEBUG]       org.slf4j:slf4j-api:jar:1.7.22:compile
[DEBUG]       log4j:log4j:jar:1.2.17:compile

Extension gets initialized as well:
[DEBUG] Extension realms for project
com.example.web:model:bundle:4.0.0-SNAPSHOT:
[ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
[DEBUG] Created new class realm project>com.example.web:model:4.0.0-SNAPSHOT
[DEBUG] Populating class realm project>com.example.web:model:4.0.0-SNAPSHOT
[DEBUG] Looking up lifecyle mappings for packaging bundle from
ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
ClassRealm[maven.api, parent: null]]
[DEBUG] Extension realms for project
com.example.web:parent:pom:4.0.0-SNAPSHOT:
[ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
[DEBUG] Looking up lifecyle mappings for packaging pom from
ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
ClassRealm[maven.api, parent: null]]
[DEBUG] Extension realms for project
com.example.web:pom:4.0.0-SNAPSHOT:
[ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
[DEBUG] Created new class realm project>com.example.web:4.0.0-SNAPSHOT
[DEBUG] Populating class realm project>com.example.web:4.0.0-SNAPSHOT
[DEBUG] Looking up lifecyle mappings for packaging pom from
ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
ClassRealm[maven.api, parent: null]]
[DEBUG] Extension realms for project
com.example:example:pom:3.0.4-SNAPSHOT:
[ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
[DEBUG] Looking up lifecyle mappings for packaging pom from
ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
ClassRealm[maven.api, parent: null]]
[DEBUG] === REACTOR BUILD PLAN ================================================
[DEBUG] Project: com.example.web:model:bundle:4.0.0-SNAPSHOT
[DEBUG] Tasks:   [clean, install]
[DEBUG] Style:   Regular

I see DefaultVersionRangeResolver initialized before my extension. One
of initializations is quite early during start up of maven, and second
when actual build is launched. There is quite long stack trace with
guice/plexus/sisu invocations to build this up but finally my
extension get called. Most interesting part, which **seems to be a
bug**, is DefaultVersionRangeResolver always gets called for first
level dependencies and my implementation of resolver gets called for
anything below that level. This makes it completely useless because I
have ranges in first level, not lower.

I also couldn't manage to get plexus test container looking up my
implementation as default one. To let plexus initialize it and use for
tests I have to use hint, otherwise I always get default
implementation, however hint causes complete ignoring of extension
when building real project. Should I provide integration test to
confirm a runtime bug? Any tips how to customize plexus container
during tests so it will locate my extension are also welcome.

Source code of resolver:
https://github.com/splatch/aether-osgi-range-resolver

Kind regards,
Lukasz
--
Apache Karaf Committer & PMC
Twitter: @ldywicki
Blog: http://dywicki.pl
Code-House - http://code-house.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Custom range resolver

Posted by Łukasz Dywicki <lu...@code-house.org>.
I saw some support for custom extensions in some takari artifacts
which allows to do integration testing. Anyhow I managed to override
defaults by creating custom plexus components.xml for test which is
fine because it literally simulates what extension does with custom
export package. I will take a look on maven-its once I will have
sampel projects to build.

Best regards,
Lukasz

2017-01-27 14:05 GMT+01:00 Robert Scholte <rf...@apache.org>:
> On Tue, 24 Jan 2017 14:04:54 +0100, Łukasz Dywicki <lu...@code-house.org>
> wrote:
>
>> I been digging with my collegue aroudn maven ranges for some time and
>> we reached point where we would like to customize them. Because we are
>> using OSGi and maven resolver embedded in Karaf (which is also aether
>> based) and also some version ranges in XML descriptors (which are
>> interpreted as osgi ranges) we ended up having a certain gap. The
>> major problem is lower and upper bound inclusion/excllusion. As found
>> in ealier mails from this month 2.0.0-SNAPSHOT is smaller than 2.0.0
>> meaning it is included in [1,2) range. I managed to get rid of this
>> inclusion by using 1.max bound: [1,1.max], but then 1.0.0-SNAPSHOT is
>> not in the range. To avoid that I did [1.min, 1.max] range. So far so
>> good, but lower and upper bound in osgi will not work. When I will
>> install 1.0.0.SNAPSHOT (which is 1.0.0-SNAPSHOT in maven) it will not
>> match 1.0.0.min range because osgi treats qualifier with "startsWith"
>> logic. It is not aware of what snapshot means, for osgi framework its
>> just a string sequence.
>>
>> I know ranges in build might be wrong, but I know how to use them and
>> I use them together with osgi so I am sure my build results will
>> match.
>>
>> I managed to complete a code which embeds osgi range resolution inside
>> aether's VersionRangeResolver implementation. It is straight forward,
>> covered by simple tests and works as expected. Even if its not working
>> as expected it can be found by unit tests and fixed. What is hardest
>> for me now is binding this resolver into build so maven's
>> implementation of VersionRangeResolver gets replaced by mine. For this
>> reason I created .mvn/extensions.xml inside project root with my
>> artifact id:
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <extensions>
>>     <extension>
>>         <groupId>org.code-house.maven</groupId>
>>         <artifactId>osgi</artifactId>
>>         <version>3.3.9-SNAPSHOT</version>
>>     </extension>
>> </extensions>
>>
>> During launch with verbose output I see my extension loaded:
>> [DEBUG] org.code-house.maven:osgi:jar:3.3.9-SNAPSHOT:
>> [DEBUG]    org.apache.maven:maven-core:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-model:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-settings:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-settings-builder:jar:3.3.9:compile
>> [DEBUG]          org.apache.maven:maven-builder-support:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-repository-metadata:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-artifact:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-plugin-api:jar:3.3.9:compile
>> [DEBUG]       org.apache.maven:maven-model-builder:jar:3.3.9:compile
>> [DEBUG]       org.eclipse.aether:aether-util:jar:1.0.2.v20150114:compile
>> [DEBUG]       org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.2:compile
>> [DEBUG]          javax.enterprise:cdi-api:jar:1.0:compile
>> [DEBUG]             javax.annotation:jsr250-api:jar:1.0:compile
>> [DEBUG]
>> org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.2:compile
>> [DEBUG]       com.google.inject:guice:jar:no_aop:4.0:compile
>> [DEBUG]       org.codehaus.plexus:plexus-interpolation:jar:1.21:compile
>> [DEBUG]       org.codehaus.plexus:plexus-utils:jar:3.0.22:compile
>> [DEBUG]       org.codehaus.plexus:plexus-classworlds:jar:2.5.2:compile
>> [DEBUG]
>> org.codehaus.plexus:plexus-component-annotations:jar:1.6:compile
>> [DEBUG]       org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
>> [DEBUG]          org.sonatype.plexus:plexus-cipher:jar:1.4:compile
>> [DEBUG]       org.apache.commons:commons-lang3:jar:3.4:compile
>> [DEBUG]    org.eclipse.aether:aether-api:jar:1.0.2.v20150114:compile
>> [DEBUG]    org.eclipse.aether:aether-impl:jar:1.0.2.v20150114:compile
>> [DEBUG]       org.eclipse.aether:aether-spi:jar:1.0.2.v20150114:compile
>> [DEBUG]    com.google.inject:guice:jar:4.0:compile
>> [DEBUG]       javax.inject:javax.inject:jar:1:compile
>> [DEBUG]       aopalliance:aopalliance:jar:1.0:compile
>> [DEBUG]       com.google.guava:guava:jar:16.0.1:compile
>> [DEBUG]    org.osgi:org.osgi.core:jar:6.0.0:compile
>> [DEBUG]    org.slf4j:slf4j-log4j12:jar:1.7.22:compile
>> [DEBUG]       org.slf4j:slf4j-api:jar:1.7.22:compile
>> [DEBUG]       log4j:log4j:jar:1.2.17:compile
>>
>> Extension gets initialized as well:
>> [DEBUG] Extension realms for project
>> com.example.web:model:bundle:4.0.0-SNAPSHOT:
>> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
>> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
>> [DEBUG] Created new class realm
>> project>com.example.web:model:4.0.0-SNAPSHOT
>> [DEBUG] Populating class realm
>> project>com.example.web:model:4.0.0-SNAPSHOT
>> [DEBUG] Looking up lifecyle mappings for packaging bundle from
>> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
>> ClassRealm[maven.api, parent: null]]
>> [DEBUG] Extension realms for project
>> com.example.web:parent:pom:4.0.0-SNAPSHOT:
>> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
>> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
>> [DEBUG] Looking up lifecyle mappings for packaging pom from
>> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
>> ClassRealm[maven.api, parent: null]]
>> [DEBUG] Extension realms for project
>> com.example.web:pom:4.0.0-SNAPSHOT:
>> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
>> [DEBUG] Created new class realm project>com.example.web:4.0.0-SNAPSHOT
>> [DEBUG] Populating class realm project>com.example.web:4.0.0-SNAPSHOT
>> [DEBUG] Looking up lifecyle mappings for packaging pom from
>> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
>> ClassRealm[maven.api, parent: null]]
>> [DEBUG] Extension realms for project
>> com.example:example:pom:3.0.4-SNAPSHOT:
>> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
>> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
>> [DEBUG] Looking up lifecyle mappings for packaging pom from
>> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
>> ClassRealm[maven.api, parent: null]]
>> [DEBUG] === REACTOR BUILD PLAN
>> ================================================
>> [DEBUG] Project: com.example.web:model:bundle:4.0.0-SNAPSHOT
>> [DEBUG] Tasks:   [clean, install]
>> [DEBUG] Style:   Regular
>>
>> I see DefaultVersionRangeResolver initialized before my extension. One
>> of initializations is quite early during start up of maven, and second
>> when actual build is launched. There is quite long stack trace with
>> guice/plexus/sisu invocations to build this up but finally my
>> extension get called. Most interesting part, which **seems to be a
>> bug**, is DefaultVersionRangeResolver always gets called for first
>> level dependencies and my implementation of resolver gets called for
>> anything below that level. This makes it completely useless because I
>> have ranges in first level, not lower.
>>
>> I also couldn't manage to get plexus test container looking up my
>> implementation as default one. To let plexus initialize it and use for
>> tests I have to use hint, otherwise I always get default
>> implementation, however hint causes complete ignoring of extension
>> when building real project. Should I provide integration test to
>> confirm a runtime bug? Any tips how to customize plexus container
>> during tests so it will locate my extension are also welcome.
>
>
> The plexus test container is only about the container (CDI), it is not aware
> of a Maven context or extensions.
> So I wonder if it is possible to test extensions like this.
> Instead have a look at
> https://git1-us-west.apache.org/repos/asf?p=maven-integration-testing.git;a=summary
>
> Robert
>
>>
>> Source code of resolver:
>> https://github.com/splatch/aether-osgi-range-resolver
>>
>> Kind regards,
>> Lukasz
>> --
>> Apache Karaf Committer & PMC
>> Twitter: @ldywicki
>> Blog: http://dywicki.pl
>> Code-House - http://code-house.org
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
>> For additional commands, e-mail: users-help@maven.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Custom range resolver

Posted by Robert Scholte <rf...@apache.org>.
On Tue, 24 Jan 2017 14:04:54 +0100, Łukasz Dywicki <lu...@code-house.org>  
wrote:

> I been digging with my collegue aroudn maven ranges for some time and
> we reached point where we would like to customize them. Because we are
> using OSGi and maven resolver embedded in Karaf (which is also aether
> based) and also some version ranges in XML descriptors (which are
> interpreted as osgi ranges) we ended up having a certain gap. The
> major problem is lower and upper bound inclusion/excllusion. As found
> in ealier mails from this month 2.0.0-SNAPSHOT is smaller than 2.0.0
> meaning it is included in [1,2) range. I managed to get rid of this
> inclusion by using 1.max bound: [1,1.max], but then 1.0.0-SNAPSHOT is
> not in the range. To avoid that I did [1.min, 1.max] range. So far so
> good, but lower and upper bound in osgi will not work. When I will
> install 1.0.0.SNAPSHOT (which is 1.0.0-SNAPSHOT in maven) it will not
> match 1.0.0.min range because osgi treats qualifier with "startsWith"
> logic. It is not aware of what snapshot means, for osgi framework its
> just a string sequence.
>
> I know ranges in build might be wrong, but I know how to use them and
> I use them together with osgi so I am sure my build results will
> match.
>
> I managed to complete a code which embeds osgi range resolution inside
> aether's VersionRangeResolver implementation. It is straight forward,
> covered by simple tests and works as expected. Even if its not working
> as expected it can be found by unit tests and fixed. What is hardest
> for me now is binding this resolver into build so maven's
> implementation of VersionRangeResolver gets replaced by mine. For this
> reason I created .mvn/extensions.xml inside project root with my
> artifact id:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <extensions>
>     <extension>
>         <groupId>org.code-house.maven</groupId>
>         <artifactId>osgi</artifactId>
>         <version>3.3.9-SNAPSHOT</version>
>     </extension>
> </extensions>
>
> During launch with verbose output I see my extension loaded:
> [DEBUG] org.code-house.maven:osgi:jar:3.3.9-SNAPSHOT:
> [DEBUG]    org.apache.maven:maven-core:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-model:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-settings:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-settings-builder:jar:3.3.9:compile
> [DEBUG]          org.apache.maven:maven-builder-support:jar:3.3.9:compile
> [DEBUG]        
> org.apache.maven:maven-repository-metadata:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-artifact:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-plugin-api:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-model-builder:jar:3.3.9:compile
> [DEBUG]       org.eclipse.aether:aether-util:jar:1.0.2.v20150114:compile
> [DEBUG]       org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.2:compile
> [DEBUG]          javax.enterprise:cdi-api:jar:1.0:compile
> [DEBUG]             javax.annotation:jsr250-api:jar:1.0:compile
> [DEBUG]           
> org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.2:compile
> [DEBUG]       com.google.inject:guice:jar:no_aop:4.0:compile
> [DEBUG]       org.codehaus.plexus:plexus-interpolation:jar:1.21:compile
> [DEBUG]       org.codehaus.plexus:plexus-utils:jar:3.0.22:compile
> [DEBUG]       org.codehaus.plexus:plexus-classworlds:jar:2.5.2:compile
> [DEBUG]        
> org.codehaus.plexus:plexus-component-annotations:jar:1.6:compile
> [DEBUG]       org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
> [DEBUG]          org.sonatype.plexus:plexus-cipher:jar:1.4:compile
> [DEBUG]       org.apache.commons:commons-lang3:jar:3.4:compile
> [DEBUG]    org.eclipse.aether:aether-api:jar:1.0.2.v20150114:compile
> [DEBUG]    org.eclipse.aether:aether-impl:jar:1.0.2.v20150114:compile
> [DEBUG]       org.eclipse.aether:aether-spi:jar:1.0.2.v20150114:compile
> [DEBUG]    com.google.inject:guice:jar:4.0:compile
> [DEBUG]       javax.inject:javax.inject:jar:1:compile
> [DEBUG]       aopalliance:aopalliance:jar:1.0:compile
> [DEBUG]       com.google.guava:guava:jar:16.0.1:compile
> [DEBUG]    org.osgi:org.osgi.core:jar:6.0.0:compile
> [DEBUG]    org.slf4j:slf4j-log4j12:jar:1.7.22:compile
> [DEBUG]       org.slf4j:slf4j-api:jar:1.7.22:compile
> [DEBUG]       log4j:log4j:jar:1.2.17:compile
>
> Extension gets initialized as well:
> [DEBUG] Extension realms for project
> com.example.web:model:bundle:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Created new class realm  
> project>com.example.web:model:4.0.0-SNAPSHOT
> [DEBUG] Populating class realm  
> project>com.example.web:model:4.0.0-SNAPSHOT
> [DEBUG] Looking up lifecyle mappings for packaging bundle from
> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example.web:parent:pom:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example.web:pom:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Created new class realm project>com.example.web:4.0.0-SNAPSHOT
> [DEBUG] Populating class realm project>com.example.web:4.0.0-SNAPSHOT
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example:example:pom:3.0.4-SNAPSHOT:
> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] === REACTOR BUILD PLAN  
> ================================================
> [DEBUG] Project: com.example.web:model:bundle:4.0.0-SNAPSHOT
> [DEBUG] Tasks:   [clean, install]
> [DEBUG] Style:   Regular
>
> I see DefaultVersionRangeResolver initialized before my extension. One
> of initializations is quite early during start up of maven, and second
> when actual build is launched. There is quite long stack trace with
> guice/plexus/sisu invocations to build this up but finally my
> extension get called. Most interesting part, which **seems to be a
> bug**, is DefaultVersionRangeResolver always gets called for first
> level dependencies and my implementation of resolver gets called for
> anything below that level. This makes it completely useless because I
> have ranges in first level, not lower.
>
> I also couldn't manage to get plexus test container looking up my
> implementation as default one. To let plexus initialize it and use for
> tests I have to use hint, otherwise I always get default
> implementation, however hint causes complete ignoring of extension
> when building real project. Should I provide integration test to
> confirm a runtime bug? Any tips how to customize plexus container
> during tests so it will locate my extension are also welcome.

The plexus test container is only about the container (CDI), it is not  
aware of a Maven context or extensions.
So I wonder if it is possible to test extensions like this.
Instead have a look at  
https://git1-us-west.apache.org/repos/asf?p=maven-integration-testing.git;a=summary

Robert

>
> Source code of resolver:
> https://github.com/splatch/aether-osgi-range-resolver
>
> Kind regards,
> Lukasz
> --
> Apache Karaf Committer & PMC
> Twitter: @ldywicki
> Blog: http://dywicki.pl
> Code-House - http://code-house.org
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Custom range resolver

Posted by Łukasz Dywicki <lu...@code-house.org>.
Since it is starting to get heavier into maven core I am moving
discussion to dev mailing list.

I've started digging around and there is no clear indication what
happens with these extensions. Some of implemented extensions I've
found over internet use sisu, some other uses just plexus and in their
cases these weys of doing extensions do work. There is no single
documentation entry about which way of IoC binding stuff should be
used in which case. It is great that it is possible to write core
extensions but without better resources they never will be done by
anyone else than maven core commiters. I already spent two days with
debugger trying to determine what happens. So far my results are
following:

1. As said ealier - it is not possible to wire custom
VersionRangeResolver with sisu @Named annotation (and metadata),
declared class doesn't get even initialized.
2. With plexus component.xml declared class gets loaded and checked
against dependencies, but it is not used for injections up to some
stage. Even after extension realms are created maven.ext still does
not look up for plexus/components.xml.

I managed to get it working (and still not failing maven) by forcing
export of META-INF/plexus/components.xml from my extension:
<extension>
    <exportedPackages>
        <exportedPackage>META-INF/plexus/components.xml</exportedPackage>
        <exportedPackage>org.code_house.maven.osgi.resolver</exportedPackage>
    </exportedPackages>

</extension>

I am not sure if its a valid approach. I found this by checking really
low level classwords stuf and for me it seems like hacking into maven
core instead of extending it. Shouldn't it be done by default that
extension components are also taken in consideration before maven core
without declaring plexus configuration as exported package?

Trace is following:
1. After extensions are resolved there is new plexus container created
with maven.ext realm and plexus.core as parent.
2. Plexus looks up for META-INF/plexus/components.xml
3. This goes to classRealm[maven.ext].getResources where parent class
loader is favored (making self first and parent first strategy
variations useless if parent class loader is used)
4. Forwarded to SelfFirstStrategy.getResources where first imports,
then self, then parent realms are used
5. Since extension META-INF entries of extensions are not declared as
"exports" it "imports" always goes back to plexus.core realm backed by
maven defaults.

Now some thoughts about last point. It works now for me with just one
extension which gets chance to override maven.ext namespace
components.xml but it will break any other extensions which would like
to contribute something to maven.ext namespace, even if its in
different area. Sisu's @Priority annotation is worthless as long as
provided bindings are not loaded in same run, and because of ignoring
contributed components.

For example takari's local repository implementation which uses sisu +
@Named to customize aether works because it is injected correctly
because place which uses it looks for multiple implementations.
Injected value is List<LocalRepositoryManagerFactory> not singleton
making injection working in completely different way. It is not clear
to me how polyglot maven extension have chance of working without my
hack because it does not override maven.ext namespace components.xml
but still have chance to customize maven's
org.apache.maven.model.building.ModelProcessor.
I understand that extensions can not influence plexus.core realm but
in this case maven.ext realm should include core extension realms
while looking up for resources.

Cheers,
Lukasz
--
Apache Karaf Committer & PMC
Twitter: @ldywicki
Blog: http://dywicki.pl
Code-House - http://code-house.org

2017-01-24 14:04 GMT+01:00 Łukasz Dywicki <lu...@code-house.org>:
> I been digging with my collegue aroudn maven ranges for some time and
> we reached point where we would like to customize them. Because we are
> using OSGi and maven resolver embedded in Karaf (which is also aether
> based) and also some version ranges in XML descriptors (which are
> interpreted as osgi ranges) we ended up having a certain gap. The
> major problem is lower and upper bound inclusion/excllusion. As found
> in ealier mails from this month 2.0.0-SNAPSHOT is smaller than 2.0.0
> meaning it is included in [1,2) range. I managed to get rid of this
> inclusion by using 1.max bound: [1,1.max], but then 1.0.0-SNAPSHOT is
> not in the range. To avoid that I did [1.min, 1.max] range. So far so
> good, but lower and upper bound in osgi will not work. When I will
> install 1.0.0.SNAPSHOT (which is 1.0.0-SNAPSHOT in maven) it will not
> match 1.0.0.min range because osgi treats qualifier with "startsWith"
> logic. It is not aware of what snapshot means, for osgi framework its
> just a string sequence.
>
> I know ranges in build might be wrong, but I know how to use them and
> I use them together with osgi so I am sure my build results will
> match.
>
> I managed to complete a code which embeds osgi range resolution inside
> aether's VersionRangeResolver implementation. It is straight forward,
> covered by simple tests and works as expected. Even if its not working
> as expected it can be found by unit tests and fixed. What is hardest
> for me now is binding this resolver into build so maven's
> implementation of VersionRangeResolver gets replaced by mine. For this
> reason I created .mvn/extensions.xml inside project root with my
> artifact id:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <extensions>
>     <extension>
>         <groupId>org.code-house.maven</groupId>
>         <artifactId>osgi</artifactId>
>         <version>3.3.9-SNAPSHOT</version>
>     </extension>
> </extensions>
>
> During launch with verbose output I see my extension loaded:
> [DEBUG] org.code-house.maven:osgi:jar:3.3.9-SNAPSHOT:
> [DEBUG]    org.apache.maven:maven-core:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-model:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-settings:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-settings-builder:jar:3.3.9:compile
> [DEBUG]          org.apache.maven:maven-builder-support:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-repository-metadata:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-artifact:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-plugin-api:jar:3.3.9:compile
> [DEBUG]       org.apache.maven:maven-model-builder:jar:3.3.9:compile
> [DEBUG]       org.eclipse.aether:aether-util:jar:1.0.2.v20150114:compile
> [DEBUG]       org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.2:compile
> [DEBUG]          javax.enterprise:cdi-api:jar:1.0:compile
> [DEBUG]             javax.annotation:jsr250-api:jar:1.0:compile
> [DEBUG]          org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.2:compile
> [DEBUG]       com.google.inject:guice:jar:no_aop:4.0:compile
> [DEBUG]       org.codehaus.plexus:plexus-interpolation:jar:1.21:compile
> [DEBUG]       org.codehaus.plexus:plexus-utils:jar:3.0.22:compile
> [DEBUG]       org.codehaus.plexus:plexus-classworlds:jar:2.5.2:compile
> [DEBUG]       org.codehaus.plexus:plexus-component-annotations:jar:1.6:compile
> [DEBUG]       org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
> [DEBUG]          org.sonatype.plexus:plexus-cipher:jar:1.4:compile
> [DEBUG]       org.apache.commons:commons-lang3:jar:3.4:compile
> [DEBUG]    org.eclipse.aether:aether-api:jar:1.0.2.v20150114:compile
> [DEBUG]    org.eclipse.aether:aether-impl:jar:1.0.2.v20150114:compile
> [DEBUG]       org.eclipse.aether:aether-spi:jar:1.0.2.v20150114:compile
> [DEBUG]    com.google.inject:guice:jar:4.0:compile
> [DEBUG]       javax.inject:javax.inject:jar:1:compile
> [DEBUG]       aopalliance:aopalliance:jar:1.0:compile
> [DEBUG]       com.google.guava:guava:jar:16.0.1:compile
> [DEBUG]    org.osgi:org.osgi.core:jar:6.0.0:compile
> [DEBUG]    org.slf4j:slf4j-log4j12:jar:1.7.22:compile
> [DEBUG]       org.slf4j:slf4j-api:jar:1.7.22:compile
> [DEBUG]       log4j:log4j:jar:1.2.17:compile
>
> Extension gets initialized as well:
> [DEBUG] Extension realms for project
> com.example.web:model:bundle:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Created new class realm project>com.example.web:model:4.0.0-SNAPSHOT
> [DEBUG] Populating class realm project>com.example.web:model:4.0.0-SNAPSHOT
> [DEBUG] Looking up lifecyle mappings for packaging bundle from
> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example.web:parent:pom:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.code-house.maven:osgi:3.3.9-SNAPSHOT,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2],
> ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:model:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example.web:pom:4.0.0-SNAPSHOT:
> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Created new class realm project>com.example.web:4.0.0-SNAPSHOT
> [DEBUG] Populating class realm project>com.example.web:4.0.0-SNAPSHOT
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] Extension realms for project
> com.example:example:pom:3.0.4-SNAPSHOT:
> [ClassRealm[extension>org.apache.felix:maven-bundle-plugin:3.2.0,
> parent: sun.misc.Launcher$AppClassLoader@18b4aac2]]
> [DEBUG] Looking up lifecyle mappings for packaging pom from
> ClassRealm[project>com.example.web:4.0.0-SNAPSHOT, parent:
> ClassRealm[maven.api, parent: null]]
> [DEBUG] === REACTOR BUILD PLAN ================================================
> [DEBUG] Project: com.example.web:model:bundle:4.0.0-SNAPSHOT
> [DEBUG] Tasks:   [clean, install]
> [DEBUG] Style:   Regular
>
> I see DefaultVersionRangeResolver initialized before my extension. One
> of initializations is quite early during start up of maven, and second
> when actual build is launched. There is quite long stack trace with
> guice/plexus/sisu invocations to build this up but finally my
> extension get called. Most interesting part, which **seems to be a
> bug**, is DefaultVersionRangeResolver always gets called for first
> level dependencies and my implementation of resolver gets called for
> anything below that level. This makes it completely useless because I
> have ranges in first level, not lower.
>
> I also couldn't manage to get plexus test container looking up my
> implementation as default one. To let plexus initialize it and use for
> tests I have to use hint, otherwise I always get default
> implementation, however hint causes complete ignoring of extension
> when building real project. Should I provide integration test to
> confirm a runtime bug? Any tips how to customize plexus container
> during tests so it will locate my extension are also welcome.
>
> Source code of resolver:
> https://github.com/splatch/aether-osgi-range-resolver
>
> Kind regards,
> Lukasz
> --
> Apache Karaf Committer & PMC
> Twitter: @ldywicki
> Blog: http://dywicki.pl
> Code-House - http://code-house.org

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org