How can I know what bundles I should not include in a Karaf features file? - apache-karaf

In a Karaf features file if I include certain bundles then Karaf stops working correctly.
How can I know what bundles I should not include in a features file? for example, if I added these bundles in the features file in Karaf on Windows, Karaf is not happy and acts strange. I assume its because Karaf already provides Java interfaces for these bundles.
<bundle>mvn:org.osgi/org.osgi.core/4.3.1</bundle>
<bundle>mvn:org.osgi/org.osgi.compendium/5.0.0</bundle>
Also is there a programmatic way to determine this?
Is there a list of bundles which I should not include?
I understand that Karaf uses pax-logging rather than those slf4j.
In more detail, my SBT project compiles a list of dependent bundles for my bundle, in my list that I get back from my code I get the org.osgi.core and org.osgi.compendium. They are dependents of my osgi bundle which is my main project. Now, the problem is, how can I know that Karaf does not want this installed as part of my features?

Thou' shall not install other framework packages besides the framework ;)
This is an absolut NOGO!
As Karaf already provides everything you need, in that case the Framework.
So don't even think about adding the std. framework packages to your OSGi env, they are already all there.
If you want to have certain compendium packages.
Make sure you Install the implementing bundle, as you already pointed out, the pax-logging bundles already provide everything needed for the osgi logging compendium services.
Same is true for Pax-Web and the OSGi HttpService packages.
You'll find a lot of already pre-registered OSGi compendium services with Karaf,
if you need more, install the implementation, not the spec bundle.
edit
nop programmatic or Karaf internal way can tell you about to not include those bundles. It's just something commonly known.
An implementing bundle always also will bring you the needed osgi packages.

Related

Can MR-Jars overwrite classes from other jars?

I have a jar that works on Java 8.
I would like to create a new jar, that is going to be Multi-Release JAR but empty, just with 'patched' classes in META-INF/versions.
I would like to have a separate jar, so people can include it on Java9, otherwise, they use the default one. Why? Because so many tools are not yet prepared for Java9 MR-Jars.
Would this be possible? Would Java9 MR-Jar override classes from others jars?
Why?
The idea behind Multi-Release jars is that they provide simple patching. In my humble opinion, the way MR jars works is not satisfying.
There are two reasons why I can't make 2 separate Jars:
try to make cross-compile source base that works with Java8 and Java9. You would end up with folders like java, java8 and java9... and then have the build produce two jars, two poms... Yeah, good luck.
Imagine that I even build a library for java9. What about transient dependencies? That would mean that all other libraries that uses mine, would need to have jre8 version that depends on my jre8 version. Just because there is Java9 version!
Here is the story:
My A is a Java library built on Java8 but packaged as Multi-Release Jar which means it contains additional classes for when jar is run on Java9. Additional classes are built separately on JDK9 and I copied them manually (yeah, I know, but it works for now).
Unfortunately, some tools and servers (Jetty) are not aware of MR Jars and this makes them NOT working.
For that reason, I have A-jre8 version of my library, that comes without any extra classes, so servers can use it.
However, if user is using library B that depends on my A, he will still get the MRJar version of A and this will fail again. I want to be able to prevent this somehow. And I can't say to B: hey, could you make B-jre8?
Possible solution
JAR is just about packaging!
Allow the separate jar to patch existing jar.
In my case, I would just include A.jar9 and Java would consider A.jar and A.jar9 together as a package. No need for META-INF/versions. Very clean. And, best of all, it would help in situations like above! If run on Java8, the jar9 jar would make no difference; if run on Java9 the jar9 jar would patch the jar with the same name. Simple as that. No transitive dependency hell.
Rename classes in META-INF/versions.
Common Oracle, have you ever heard about the classpath scanning? Could you at least rename the classes in versions to e.g. *.class9 so not to be caught by existing classpath scanners.
As it is today (Java v9.0.4) - no.

What is symfony in the vendor folder?

When I create an app using composer, or install another app created using composer, there is a vendor/symfony folder included.
For example, I installed Laravel using composer. The folder vendor/symfony is present. I am not specifically referencing this in my Laravel app at all.
What is this folder, and it needed? Does the app use it, or composer use it? So if I am using an app created using Composer and dont use composer myself, can it safely be deleted and the app still run? Or could the app be using it?
Thanks
Answer is quite simple: Laravel uses Symfony components.
Check this article: http://www.sitepoint.com/build-php-framework-symfony-components/
Improved Routing Engine
Laravel 4.1 features a totally re-written routing layer. The API is
the same; however, registering routes is a full 100% faster compared
to 4.0. The entire engine has been greatly simplified, and the
dependency on Symfony Routing has been minimized to the compiling of
route expressions.
http://laravel.com/docs/master/releases
The "vendor" folder is a standard in every application / framework that uses composer to manage dependencies. In the "vendor" folder you will find all dependencies (read: libraries) that your applicatication requires.
But you will also find all libraries that your libraries require. In order to minimize code duplication, and thanks to the composer system, most open source projects now reuse parts from other open source projects.
BTW, this is great.
Symfony components are excellent and well documented, so they are currently used by many other frameworks and applications.
Inside the "vendor" you may find other libraries that you did not specifically require yourself, but as long as your correctly use composer, that's not something you should worry about.

Symfony2: How to handle PHP Unit bootstrap file for contributed bundle?

What do I use as the autoload file for my PHP Unit configuration file for my contributed bundle?
I'm writing unit tests for my first contributed Symfony 2 bundle. I'm not sure how to handle the XML configuration file phpunit.xml.dist for PHP Unit. I know I should write my own config file(instead of relying on the one provided by Symfony Framework), but I've seen a few different ways people handle the bootstrap file that the config uses.
Symfony framework apps have a PHP Unit config file in the app/ folder and it uses bootstrap.php.cache as the autoloader, which really just defers to the composer autoloader in the vendor directory.
Several bundles I've looked at have their own bootstrap file but try and locate some other autoload file on the filesystem, making assumptions about where it may be. That doesn't seem right to me, but perhaps it is?
The best practices don't get into specifics here.
Best practices for unit testing is to test a small unit of functionality at a time, this unit should not rely on external influences and doesn't make sense to use bootstrap.php.cache as that is intended to bootstrap the entire symfony framework.
Your tests within a bundle should be able to execute on their own if someone were to checkout your bundle and contribute to it, they should be able to run tests there with only your code and dependencies. An ideal scenario would be that no bootstrap is necessary to set up the test suite, all you need is the autoloader. This is why many bundles have a bootstrap script that loads the autoloader.
There are two scenarios on the autoloader location relative to the bundle, either your bundle is installed standalone and it will be in vendor/autoload.php or your bundle is installed as a dependency, which in a standard configuration would you would fall back to a project autoloader if that exists.
This is variable depending on your setup and usage of target dir... You would need to traverse upward at least two levels to account for vendor name and package name, then if you have a target directory configuration you would need to traverse upwards the number of directories in your target path.

Need Pointers | Using JDBCTemplate | CQ 5.5

I need some pointers/suggestions on following scenario.
Scenario:
We are trying to use JDBCTemplate in CQ 5.5 for querying database (Oracle 11g). As first step we have integrated CQ with Spring Framework. Now for JDBCTemplate to work it requires JDBC driver that needs to be loaded separately into CQ as it is not available with Spring jars. The jar that is required is available here http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html and jar in my case is “ojdbc6.jar” that contains OracleDriver class (JavaDoc: *http://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleDriver.html*) required to register the driver to create connection with Database.
Problems/Suggestions required on following points:
As oracle 11g is commercial product so there is no repository available online for it (for pom dependencies), we need to create a separate local repository for it. (Need pointers; is there any other way to do it?)
Jar mentioned above is not OSGi. So how to approach in that case? (I have created OSGi bundle by following directions mentioned here http://cq-ops.tumblr.com/post/21893960212/how-to-turn-a-jdbc-driver-jar-into-an-osgi-bundle-jar)
In this process of converting this jar to OSGi Bundle I have to remove versions mentioned with Imported Packages in MANIFEST.MF file. (As I understand that CQ by-default picks the latest version that is available for any class, there may be problem when a new version of any class is available that is not compatible with current version. Need pointers; should this be looked into priority? Has anybody faced any issue due to this in any project)
Current Status:
By converting ojdbc5.jar to OSGi bundle; I was able to use JDBCTemplate. But looking for some pointers to check is there any other approach someone has followed in other project to achieve scenario mentioned above?
The oracle driver is not published to any public maven repo. So indeed you will have to put the jar into your own maven repo
In Apache Karaf there is a nice feature where you write wrap: in front of a bundle url and it automatically creates a bundle on the fly using the bnd tool.
If CQ does not have such a feature then you will have to create the bundle on your own. In this case the maven bundle plugin can help you. You can depend on the oracle jar using a maven dependency. Then you can define exports for the packages of the oracle jar. Bnd should then automatically inline the classes in you bundle jar. Another option is the maven shade plugin. You can take a look at the source of the servicemix bundles. There you find poms to bundle a lot of plain jars.
Not sure what exactly you mean. As far as I know the oracle driver does not have any external dependencies.
I have written a DB tutorial for Apache Karaf that explains how to deal with the oracle driver and how to create data sources without depending on the concrete driver.
The solutions in the tutorial can not be used 1:1 in CQ but it will surely give you some pointers.

Received a main jar file with other jar files that need to be in the classpath. Whats the best way to include this main jar in my maven project?

So i received a java api from a client and the main code is in main.jar. But the instructions he gave me require me to add these other jars (a.jar, b.jar, etc..) into the classpath whenever I want to use main.jar. These other supporting jars are things like Xerces, jakarta-oro, and a few other publicly available libraries. The problem is i don't know what versions they are, so i'm not sure if there would be issues if i just update the pom.xml file in my app to depend on main.jar and also have dependencies to these other jars as well with the latest versions of them.
Whats the best strategy for using main.jar in my maven application? I'm planning on adding main.jar to our internal maven repository, but what should i do about the xerces, jakarta-oro, and other jars when i dont know what versions they are?
Thanks
If you are lucky the file /META-INF/MANIFEST.MF inside a.jar, b.jar etc. contains an entry "Implementation-Version" or some other useful information which tell you what version they are. If not, you can download the latest release(s) from the project web site and check if they have the same file size as your bundled dependencies.
You may also come to the idea to bundle the dependencies with the main.jar in one big jar, but this may become funny, when you have the dependencies twice in your classpath at some point in the future...
What about just asking the client what version numbers this dependencies have?
If you don't have any information about these third-party libraries, just add them to src/resources/META-INF/lib and commit to SVN. That's the best way, if we're talking about black box approach.

Resources