Apache Karaf feature dependency - apache-karaf

In feature.xml (Apache Karaf provisioning mechanism) tag feature has a dependency attribute. What does this attribute do?
For example:
<feature dependency="true">custom-feature-name</feature>
Where can I find any information on it?
After a brief googling I've only found dependency attribute on a bundle tag:
The role of the dependency attribute is to mark that a bundle is a dependency. If a dependency is already satisfied (an existing bundle already exports the same packages/version) then it doesn't get installed. This behavior happens if the declared feature resolver is installed (e.g. obr is installed).
Source:
http://karaf.922171.n3.nabble.com/features-xml-dependency-quot-true-quot-td3286359.html
But still, no information on feature tag.

It would seem that the definition of dependency for features in
<feature name="${project.name}-cxf" version="${cxfVersion}" description="Gets CXF up and running." install="auto">
<feature version="${cxfVersion}" dependency="true">cxf</feature>
</feature>
means that the feature ${project.name}-cxf does not have to start cxf, because it is declared that something else will provide it. This is indeed counterintuitive. Whoever came up with that ludicrous misnomer?
To auto install cxf, it should actually be set to false. This can be varified by looking up the name of the feature ${project.name}-cxf when dependency="true" and again set to false.
Developers of Karaf, the dependency=false should be renamed provided=true

Related

How to check whether the .NET 6 runtime is installed

As part of installation of a WPF application using .NET 6 and a WiX installer, I would like to check whether the .NET 6 runtime is installed.
WiX provides pre-defined properties to check this for .NET framework but nothing for .NET Core and beyond so I am attempting to check for the presence of a registry key.
There is a registry key that can be checked under: HKEY_LOCAL_MACHINE\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\Version
However, if I uninstall the runtime the registry key does not get removed, is there any other reliable way to check whether the runtime is installed, as well as which version is installed?
WiX 3 currently doesn't handle this natively. It is being worked on for WiX v4 (GitHub issue). Reading the issue led me to these tools as a current workaround.
https://www.nuget.org/packages/Microsoft.NET.Tools.NETCoreCheck.x86
https://www.nuget.org/packages/Microsoft.NET.Tools.NETCoreCheck.x64
You can use the files inside of these packages to check for a runtime. Either by running NetCoreCheck.exe directly or using the custom action DLL provided.
NetCoreCheck.exe -h to see help. But you'll want something like this:
netcorecheck --runtimename Microsoft.NetCore.App --runtimeversion 6.0.0
I don't know how to use the custom action dll but I do see it has two DLL exports.
ordinal hint RVA name
1 0 00001500 CheckNETRuntime
2 1 00002260 get_hostfxr_path
You may use the Custom Action DLL mentioned in Hank's answer if you want to integrate this in your WiX project.
You can use the NuGet package to obtain the dll.
Unfortunately there seems to be no documentation in existence for this DLL, so I used the source code to figure out how this works.
First you need to define a few properties that are used as input parameters for the .NET runtime check, and for the result of the check.
<Property Id="CheckNETRuntime_Framework" Value="Microsoft.AspNetCore.App" />
<Property Id="CheckNETRuntime_Version" Value="6.0.0" />
<Property Id="CheckNETRuntime_Result" />
CheckNETRuntime_Framework is the framework to search for. There are currently 3 options:
Microsoft.NETCore.App
Microsoft.AspNetCore.App
Microsoft.WindowsDesktop.App
CheckNETRuntime_Version is the version of .NET to look for.
The result will be stored in CheckNETRuntime_Result. A value of 0 indicates the runtime was found, any other value indicates it was not found.
To run the custom action, do this:
<Binary Id="CustomActions" SourceFile="NetCoreCheckCA.dll" /> <!-- This should be the path to the dll -->
<CustomAction Id="CheckRuntime" Return="ignore" BinaryKey="CustomActions" DllEntry="CheckNETRuntime" />
<InstallExecuteSequence>
<Custom Action="CheckRuntime" Before="LaunchConditions" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="CheckRuntime" Before="LaunchConditions" />
</InstallUISequence>
Note: you need to add Return="ignore" if you do not want the installer to fail when the runtime was not found (as the return value if not 0, which indicates a failure).
The CheckNETRuntime_Result property can be used elsewhere in your setup, for example you could use it in a condition:
<Condition Message=".NET 6 runtime is not installed">
<![CDATA[CheckNETRuntime_Result=0]]>
</Condition>

How can we avoid that every package in our .NET Core 3.1 project, is checked at every NuGet source during Azure DevOps pipeline?

In our .NET Core 3.1 project (REST API), we've multiple NuGet packages. General packages comes from the nuget.org source, some custom made packages are retrieved from a private source.
In Azure DevOps, we've a build pipeline with a task to restore the NuGet packages. Here we saw that every packages was checked with every source. A general package such as Swashbuckle.AspNetCore.SwaggerGen was also searched on our private source.
Due to the amount of requests from DevOps, the first attempt of the pipeline was interpreted as a DOS attack on our system. When the failed run was started again, the task succeeds without any error.
- task: DotNetCoreCLI#2
displayName: dotnet restore
inputs:
command: 'restore'
projects: '**/*.sln'
feedsToUse: 'config'
nugetConfigPath: 'src/NuGet.config'
In the tasks detail, we see the below message returning for every package.
GET private_source/nuget/FindPackagesById()?id='xunit.analyzers'&semVerLevel=2.0.0
Retrying 'FindPackagesByIdAsyncCore' for source 'private_source/nuget/FindPackagesById()?id='Microsoft.AspNetCore.Mvc.Razor'&semVerLevel=2.0.0'.
An error occurred while sending the request.
The response ended prematurely.
How can we avoid that every package in our solution, is checked at every NuGet source? Or what can we change to get a successfull build the first time?
NuGet recently introduced the feature, called Package Source Mapping: https://devblogs.microsoft.com/nuget/introducing-package-source-mapping/
Here's the nuget.config snippet from the blog post:
<!-- Define my package sources, nuget.org and contoso.com. -->
<!-- `clear` ensures no additional sources are inherited from another config file. -->
<packageSources>
<clear />
<!-- `key` can be any identifier for your source. -->
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="contoso.com" value="https://contoso.com/packages/" />
</packageSources>
<!-- Define mappings by adding package ID patterns beneath the target source. -->
<!-- Contoso.* packages will be restored from contoso.com, everything else from nuget.org. -->
<packageSourceMapping>
<!-- key value for <packageSource> should match key values from <packageSources> element -->
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="contoso.com">
<package pattern="Contoso.*" />
</packageSource>
</packageSourceMapping>
Regarding the error message:
An error occurred while sending the request. The response ended prematurely.
This suggests there's something wrong with the server or networking. A good nuget server should return HTTP 404 for packages that doesn't exist on it. Implementing package source mapping might not solve your restore problem.
I suggest creating an Azure Devops Artifacts feed having upstream source both from nuget.org and your private feed. There is no other way you can use multiple sources to do partial restore.
How can we avoid that every package in our .NET Core 3.1 project, is checked at every NuGet source during Azure DevOps pipeline?
I am afraid there is no such out of box way to resolve this restriction.
That's because no matter how we set the resource, when we restore the package for the first time, nuget.exe will iterate over each resource for every package. This problem will be alleviated when we run the pipeline again, because it is from nuget.org The packages will be cached in our private feed. When we restore again, it will be retrieved from the private feed first:
Check my previous thread for some more details.
Besides, If you want to avoid this problem the first time, you can try not to restore the entire .sln file, you can choose package.configs for the specify reject:

How can I get Ivy to bundle dependencies for MY dependencies into their own jar?

In my project, I have exactly one dependency (right now, it's early!) - Hibernate. In my Ivy config, I have the following:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency org="org.hibernate" name="hibernate-core" rev="5.4.0.Final" conf="sources->sources"/>
<dependency org="org.hibernate" name="hibernate-core" rev="5.4.0.Final" conf="binaries->default"/>
</dependencies>
And in my build.xml, I have this:
<ivy:retrieve conf="sources" pattern="war/WEB-INF/lib/[conf]/[artifact](-[classifier]).[ext]"/>
<ivy:retrieve conf="binaries" pattern="war/WEB-INF/lib/[artifact](-[classifier]).[ext]"/>
Now, in my lib folder, I have a folder called sources with exactly one jar, hibernate-core-sources.jar - perfect!! But in the lib folder itself, I don't have exactly one jar - I have 18 jars, one for each of Hibernate's dependencies (and grandparent dependencies, etc.)
What I'd really like to see is something like hibernate-core.jar and hibernate-core-deps.jar.
Is something like this possible? If it isn't, would it be possible to have it be hibernate-core.jar and my-app-deps.jar? And if THAT isn't possible, can it just bundle it all into a single my-app-deps.jar?
I'm not very experienced with Ivy, so the more explicit your answer, the better!
It's possible, but you have to be aware that when you build the classpath you may end um missing some classes and having NoClassDefFoundError thrown at runtime.
The solution is to call ivy resolve once with transitive set to false, and second time with it being set to true (which is default). After each of these you have to call retrieve but with different retrieve patterns, so the non-transitive (hibernate-core.jar) to lib folder and transitive to a temp folder from which you could create hibernate-core-deps.jar.

Symfony 4 - 3rd-party bundle commands are no longer automatically discovered

According to the documentation, a command class must extend Command or ContainerAwareCommand to be automatically discovered and registered (provided its bundle is registered in the Kernel, of course).
Since Symfony 4+, this discovery doesn't work as expected.
Try this:
composer create-project symfony/skeleton test-maxmind-sf4
cd test-maxmind-sf4
composer req cravler/maxmind-geoip-bundle dev-master
php bin/console list
You will notice that:
cravler:maxmind:geoip-update is not registered (nothing under a "cravler" namespace
Cravler\MaxMindGeoIpBundle\Command\UpdateDatabaseCommand extends ContainerAwareCommand
Bundle Cravler\MaxMindGeoIpBundle\CravlerMaxMindGeoIpBundle is registered in config/bundles.php for all environments (auto-generated recipe)
Now when I do exactly the same thing with Symfony 3, everything works properly.
composer create-project symfony/skeleton test-maxmind-sf3 ^3.0
cd test-maxmind-sf3
composer req cravler/maxmind-geoip-bundle dev-master
php bin/console list
What's missing there?
Thank you,
Ben
From the UPGRADE FROM to 4.0 Guide here:
Relying on convention-based commands discovery is not supported
anymore. Use PSR-4 based service discovery instead.
Before:
# app/config/services.yml
services:
# ...
# implicit registration of all commands in the `Command` folder
After:
# app/config/services.yml
services:
# ...
# explicit commands registration
AppBundle\Command\:
resource: '../../src/AppBundle/Command/*'
tags: ['console.command']
Hope this help
Basically you have to add a few things to your bundle's services file in order to autoconfig your services. Following the example in config/services.yaml:
# Cravler/MaxMindGeolpBundle/Resources/config/services.xml
<services>
<defaults autowire="true" autoconfigure="true" public="false" />
<prototype
namespace="Cravler\MaxMindGeoIpBundle\"
resource="../../*"
exclude="../../*/{Entity,Migrations,Tests}" />
<service id="cravler_max_mind_geo_ip.service.geo_ip_service"
public="true"
class="Cravler\MaxMindGeoIpBundle\Service\GeoIpService">
</service>
</services>
Clear the cache and your command should be there.
And then of course you should probably tweak the command itself and inject the ip service instead of locating it.
I did poke around a bit and did not find this approach documented anywhere. And as I mentioned in the comments, all the bundles I did check still explicitly defined their command services. So I'm not sure if this approach is discouraged or not.
Update: as #Matteo said in their answer, prior to 4.0 any classes defined in the Command directory were treated as commands. This scanning was considered to be magical and removed. However, around the same time, Harry Potter was added to the core team and magic was his thing. So the scanning of the Command directory was replaced with all sorts of auto wiring and auto tagging spells.
If you are absolutely sure you config is correct and command is still not recognized, try resetting composer's autoloader:
$ composer dump-autoload
This helped in my case.
I think the command should be registered within the bundle, not the app. I think this will work:
# Cravler\/axMindGeoIpBundle/src/Resources/config/services.xml
<services>
<service
id="Cravler\MaxMindGeoIpBundle\Command\UpdateDatabaseCommand"
class="Cravler\MaxMindGeoIpBundle\Command\UpdateDatabaseCommand"
public="false">
<tag name="console.command" />
</service>
</services>
The command class extends Symfony\Component\Console\Command\Command.

Imagine Bundle conflict minimum

I'd like to install liip/imagine-bundle in my symfony 2 project. But in order to make barcodes, I installed previously MopaBarcodeBundle.
MopaBarcodeBundle requires "avalanche123/imagine-bundle" which requires imagine/imagine: v0.4.1
And
LiipImagineBundle requires imagine/imagine: ~0.5,<0.7
Obviously composer detects the conflict, as he cannot unistall v0.4.1, and that version is not enough for LiipImagine.
I'd like to know how I could bypass this. Create sorts of aliases in composer and keep the two versions on my project ? I'm not a pro in version management, so I guess this is not possible.
Thank you very much for any help.
Ok, after some code inspection i figured out a way around. MopaBarcodeBundle doesn't really requires avalanche123/imagine-bundle, but it uses it in the service declaration. (To make the link with Imagine classes).
So I changed the service.xml file containing the BarcodeService declaration.
<parameter key="imagine.gd.class">Imagine\Gd\Imagine</parameter>
<service id="imagine" alias="imagine.gd" />
<service id="imagine.gd" class="%imagine.gd.class%" />
I guess thoses lines could be factorised, but i chose to keep it as it was done in avalanche123.
Also a constant from avalanche was used in 5th argument, I changed it to :
<argument>%kernel.root_dir%../web</argument>
Finally I removed avalanche, and then install a newer version of imagine/imagine

Resources