Chapter 14. Pitfalls and Troubleshooting

The sequence of steps described in this book's chapters guided you in constructing the case study. If you have followed these steps faithfully, you should not have encountered any major issues in building the components of this project.

As I have worked on this application, starting from scratch, going through the same steps, I've written the issues that I've encountered down here. I have also added a few that I had seen earlier.

This is by far not a complete list of the things that can possibly go wrong; the online forums and FAQ pages hold a wealth of information and answers to problems that other beginners and more advanced users have encountered. Be sure to consult those useful resources when you're stuck!

We'll also look at a few ways to troubleshoot your application to find hints on what's causing it to misbehave, as part of a root cause analysis activity.

The following are the common pitfalls that we'll look at in this chapter:

  • I start my bundle, but nothing happens
  • I update my bundle, but I can't see any change
  • I refresh my OBR, but the bundles don't get updated
  • The artifact JAR I need doesn't have OSGi entries in its manifest
  • I get a "No impl service available." error with any TUI command
  • I get a "No LogReaderService available" error with the log command
  • I can't add/connect to an OBR
  • I'm getting a "Jsp support is not enabled" error message
  • My JSP can't find a class that it needs

We'll also look at the following troubleshooting tips:

  • How to get debug logs from the Felix Log Service
  • How can remote debugging help?
  • Where to get answers online

Common pitfalls

This section describes some of the issues that may be encountered when developing an application on an OSGi framework in general and on the Felix framework in specific. Be sure to also read the next section, which shows a few ways to investigate your issue in an attempt to discover the root cause.

I start my bundle but nothing happens

I've created a bundle which includes a BundleActivator implementation and installed it onto the OSGi framework. When I start the bundle, I'm expecting a debug message to be printed, but I get none.

Have you declared your bundle activator in the manifest?

The framework knows which class to use as the bundle activator through the Bundle-Activator entry in the manifest.

If you're using Maven to build your project, as described in this book, to assist you in constructing the bundle OSGi headers, then the first thing to check is whether your bundle activator class is declared in the maven-bundle-plugin configuration of the POM build plugins section. Here's an example of the test.MyActivator activator:

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<!-- ... -->
<Bundle-Activator>test.MyActivator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

Tip

Refer to Chapter 5, The Book Inventory Bundle, for a review on how to write a bundle activator and how to declare it for inclusion as part of the bundle OSGi manifest headers.

If you're not using a tool to help you generate your OSGi headers, which is not recommended because manual header construction can be very tedious and error prone, then you should double-check the Bundle-Activator entry in the manifest. The Bundle-Activator manifest entry for the previous example would look like the following:

Bundle-Activator: test.MyActivator

Do you have the correct logging level set?

It may be that the bundle activator is correctly set up and your messages are not showing because they're hidden.

The framework is configured to not store debug messages because of their volume and their impact on memory usage and performance.

Tip

Refer to the Troubleshooting tips, in the following section, for more information on how to get debug level logs from the Felix Log Service.

I update my bundle, but I can't see any change

After having installed a bundle onto Felix, I've modified the source code, re-built and deployed it, and then updated it in Felix using the update command. But it looks like the old classes are still being used.

Are you updating the right bundle?

Okay, it's silly, but just in case, it's worth clearing this doubt first: if you have a large number of bundles installed on your framework, it's easy to type the wrong bundle ID in your update command without paying attention.

Double-check if the bundle ID is the right one by listing the installed bundles using the lb command on the shell console.

Are you updating the right bundle location?

In case you're not using the OBR service and instead have installed your bundle with a direct URL using the install <URL> command, make sure that you're still deploying to that same URL.

When a bundle is installed using a URL, the framework downloads it and keeps that location for future updates. This location can be overridden by specifying a new location URL when updating the bundle (refer to the section on the update command in Chapter 3,Felix Gogo).

In the case where the OBR service is used, the URL that is given to the bundle has an obr:// scheme. When this URL is opened for updates, the open stream request is intercepted and the newest compatible version of that bundle is loaded. However, when the bundle is installed using, for instance, a file:// or http:// scheme URL, the same target location is used every time.

If you've changed the bundle version after making those modifications, the deployed bundle is now located at a different URL because the bundle version is typically part of the bundle JAR name.

On Felix, you can find out the source location of a bundle by using the lb -l command and flag.

If you are using the OBR to update your bundles, make sure you've refreshed the OBR before you update the bundle! Use the repos refresh <url> command to instruct the OBR service to get a fresh listing of the bundles deployed to that repository.

Have you refreshed the bundle dependencies?

This does not apply to private classes, that is, those that are visible and used only within the bundle.

Classes that are accessible from other bundles, public classes that are in an exported package, can be used by other bundles in the framework. If another bundle depends on a package exported by your bundle and references one of those classes, there are cases where this reference does not get updated.

To request the framework to update those references to exported packages, you use the refresh command either by refreshing all the bundles (without any parameters) or by refreshing a selected set of bundles (refresh<id> . . .).

I refresh my OBR but the bundles don't get updated

I'm trying to use the OSGi Bundle Repository to update my bundle. I install and deploy my bundle using the maven-bundle-plugin, but when I list the bundles in the OBR using the obr:list command, my bundle doesn't show up.

Is the remote OBR being updated?

By default, the maven-bundle-plugin doesn't update the remote repository when the bundle is deployed. If you look closely at the build logs, you'll find the following message towards the end, a bit before the build successful message:

[INFO] Remote OBR update disabled (enable with -DremoteOBR)

To enable the remote OBR update during the deploy cycle, include the -DremoteOBR directive on the command line or the<remoteOBR /> instruction in the plugin configuration.

We've set the<remoteOBR/> instruction in the POM in this book. Here's an example of how to enable it using the command-line directive:

mvn -DremoteOBR clean deploy

Now this works well in the case when the project packaging is set to bundle:

<project>
<!-- ... -->
<packaging>bundle</packaging>

If it's not the case, refer to the bundle online documentation for the configuration required to enable projects with other packaging types for bundle deploy.

Tip

Also refer to Chapter 5 for a review on how to set up your distributionManagement configuration for bundle deploy.

The artifact JAR I need doesn't have OSGi entries in its manifest

I have a dependency on a library that doesn't have any OSGi entries in its manifest. When I install it on the framework, the packages it holds are not registered and my dependency is not satisfied.

Creating the bundle manually

In Chapter 13, Improving the Graphics, we've looked at one way of adding the missing OSGi manifest entries, the manual way. Basically, it consists of inspecting the package contents of the Java Archive and creating the bundle manifest based on those.

This is only suitable for the simplest cases, namely, the ones where the JAR being modified doesn't have external dependencies (or where you deem those dependencies can be ignored), and where the resulting manifest entries are simple enough to be safely filled manually.

Using the BND tool

For more complex cases, it's recommended to use a tool to generate the manifest entries. Luckily, such a tool exists.

The maven-bundle-plugin that we've used in this book as part of the build process is based on the BND tool created by Peter Kriens (OSGi Technical Officer). BND is a powerful tool that helps in creating and diagnosing OSGi bundles.

A more detailed set of documentation (as well as the download links) is available on the tool's web page (http://www.aqute.biz/Code/Bnd).

The following instructions only target to solve the specific problem described here, but the tool provides a larger set of useful features. The version of the BND tool available at the writing of this is 0.0.384.

Let's take the example of the json JAR we worked with in Chapter 13. If you run the following command:



java -jar bnd-0.0.384.jar wrap json-20090211.jar

The tool will analyze the contents of the JAR and generate json-20090211.bar a new archive that contains the modified manifest file.

Unzip the archive and take a look at the generated manifest:

Manifest-Version: 1.0
Export-Package: org.json
Bundle-Version: 0
Tool: Bnd-0.0.384
Bnd-LastModified: 1279997110578
Bundle-Name: json-20090211
Bundle-ManifestVersion: 2
Created-By: 1.6.0_10-rc (Sun Microsystems Inc.)
Import-Package: org.json;resolution:=optional
Bundle-SymbolicName: json-20090211
Originally-Created-By: 1.6.0_07 (Sun Microsystems Inc.)

Most of the legwork is already done for you; there's just a few additional steps to make it complete. The previously highlighted lines show the entries to be modified:

  • Modify the Bundle-Version to be that of the artifact (in this case, 20090211).
  • Modify the Bundle-SymbolicName, removing the version from it. This will allow a straightforward upgrade in the framework when a newer version of the artifact is available. Optionally, you can also modify it to be fully qualified (org.json).

The following listing shows the updated manifest:

Manifest-Version: 1.0
Export-Package: org.json
Bundle-Version: 20090211
Tool: Bnd-0.0.384
Bnd-LastModified: 1279997110578
Bundle-Name: json-20090211
Bundle-ManifestVersion: 2
Created-By: 1.6.0_10-rc (Sun Microsystems Inc.)
Import-Package: org.json;resolution:=optional
Bundle-SymbolicName: org.json
Originally-Created-By: 1.6.0_07 (Sun Microsystems Inc.)

All that's left is to repackage the artifact, optionally changing its extension to .jar.

I get a "No impl service available" error with any shell command

I've installed a bundle using the obr:deploy command, which has failed for some reason, but now I get an error message "No impl service available" for every command I run on the shell.

Re-initialize the environment

This problem will occur if the install has caused the shell service to stop and it was unable to start again. The easiest way to fix this is to reset the environment.

To reset the environment to the way it was initially, delete the bundle-cache directory. You'll need to reinstall the bundles that you had added. For that, you can use a script such as the one I have used in Chapter 8,Adding a Command-Line Interface.

I get a "No LogReaderService available" error with the log command

I want to check the logs so I've tried the log command, but I'm getting a "No LogReaderService available" error message:

g! log info

No LogReaderService available

Do you have a Log Service installed?

The availability of the log command does not necessarily mean that a Log Service or that a Log Reader Service is installed. It merely provides a means to access the installed Log Reader Service's stored log entries.

This message means that an active Log Reader Service was not found on the framework. You need to install and start one.

Tip

Refer to Chapter 10, Improving the Logging, for more details on the Log Service and how to install the simple Felix Log Service and Log Reader service implementations.

I can't add/connect to an OBR

I've tried adding a remote OBR to my list of repositories using the repos add command, but I get an error message and the URL doesn't show in the repos list command output.

Is that URL valid?

First of all, double-check that the URL that you're using is valid, that is, it's well formed and actually points to a repository file.

A quick check is to point your web browser to that URL; you should be able to see the repository XML contents. If your browser cannot load that file, it means that the URL is no good.

Does the OBR have the right format?

Another possibility for this problem could be the format of the XML file located by the URL. The OBR service expects the repository descriptor to have a specific format. There are some repositories that do not follow this format and cannot be used with the Felix Bundle Repository service.

As a next step to the previous check, make sure that the contents of the repository file follow the required structure.

Tip

For more details on the OSGi Bundle Repository, have a look at Chapter 6,Using the OSGi Bundle Repository.

Do you need a proxy to access the Internet?

If your browser requires a proxy to access the internet, then so will the Bundle Repository Service. You need to provide the proxy configuration to the framework. This can either be done as a command-line directive using -D<prop>=<value> entries in the startup script, or in the system.properties file under the conf directory.

The following are the property names that are used for proxy configuration:

  • http.proxyHost: The host name or IP address of the proxy server
  • http.proxyPort: The port of the proxy server
  • http.proxyAuth: The username and password to use when connecting to the proxy server, separated by a colon (for example, myuser:mypass)

Check the Felix online configuration documentation for more details on this.

I'm getting a "Jsp support is not enabled" error message

I'm trying to start my web application bundle, but I get error messages about JSP support not being enabled, like:

2010.06.22 19:10:12 ERROR - Bundle:com.packtpub.felix.bookshelf-webapp -
[ERROR] com.packtpub.felix.bookshelf.webapp.Activator :
[com.packtpub.felix.bookshelf.webapp.Activator-0]
The callback method validate has thrown an exception : Jsp support is not enabled. Is org.ops4j.pax.web.jsp bundle installed? -
java.lang.UnsupportedOperationException: Jsp support is not enabled. Is org.ops4j.pax.web.jsp bundle installed?

Did you install JSP support?

Check if the JSP extension for your selected Web Container implementation is installed. If you're using Pax Web, then refer to Chapter 13 for the installation procedure.

My JSP can't find a class that it needs

I've written a JSP which imports a class that's in another bundle. The bundle with that class is correctly installed on the framework, but my JSP is failing to compile; there's an error saying that this class cannot be resolved to a type.

For example, here I have a JSP (index.jsp) that imports the class test.example.ExternalClass:

<%@ page import="test.example.ExternalClass"%>

When attempting to access that JSP in a browser, after starting the web application bundle, I get the error message:

Problem accessing /test/index.jsp. Reason:
Unable to compile class for JSP:
An error occurred at line: 11 in the jsp file: /test/index.jsp

ExternalClass cannot be resolved to a type

Mainly, there are two potential reasons for this situation.

Is that class on an exported package?

Make sure that the bundle that's supposed to provide the class (here ExternalClass) properly exports its package. The framework will only make classes in exported packages available for other bundles.

To rule this potential root cause out, double-check the Export-Package manifest entry in the bundle, that provides this class. It must include the package that contains the class ExternalClass.

Does the web application bundle import the required class package?

If you're using the maven-bundle-plugin to generate the OSGi manifest entries, it will look for the packages to include in the Import-Package manifest entry by inspecting the Java sources. However, it will not look into JSPs to include the packages they import.

The packages required by JSP files need to be specified to be included as part of the Import-Package manifest entry.

This is done in the plugin configuration section of the project POM:

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<!-- ... -->
<Import-Package>test.example,*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

Notice that the package entry is followed by "*". This requests the plugin to also include the other detected packages along with this manually included one.

Tip

Review Chapter 13 for the steps needed for the implementation of a web application bundle.

If you're not using an automated way to construct the Import-Package entry, then just make sure to include the required packages when setting it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.41.212