2009/2/23 Krishnaveni Krishnarajah <[email protected]>
> Hi All,
> I am trying to calculate time taken to load the bundles in Felix. I played
> around with some profiler tool such JProfiler but didn't get any easy way
> out.
> I finally wrote a small program to calculate the time taken. It is
>
> import java.io.BufferedReader;
> import java.io.InputStream;
> import java.io.InputStreamReader;
>
> public class CalculateTimeTaken {
>
> /**
> * @param args
> */
> public static void main(String[] args) {
> // Get the start time of the process
> long start = System.currentTimeMillis();
> System.out.println("Start: " + start);
>
> Runtime rt = Runtime.getRuntime();
> try {
>
> String command1 = "java -jar
> C:\\Users\\KK\\Desktop\\felix-1.4.1\\bin\\felix.jar";
>
> Process pr = rt.exec("cmd /c " + command1);
> InputStream is = pr.getErrorStream();
> BufferedReader br = new BufferedReader(new InputStreamReader(is));
> System.out.println("ERROR STARTS");
> String line = null;
> while ((line = br.readLine()) != null) {
> System.out.println(line);
> }
> System.out.println("ERROR END");
> int exitval = pr.waitFor();
> System.out.println("exit status is " + exitval);
> } catch (Exception e) {
>
> e.printStackTrace();
> }
>
> // Get the end time of the process
> long end = System.currentTimeMillis();
> System.out.println("End : " + end);
>
> long elapsedTime = end - start;
>
> // Show how long it took to finish the process
> System.out.println("The process took approximately: " + elapsedTime
> + " mili seconds");
>
> }
>
> }
>
>
> However, this fails with following error
>
> Start: 1235369156728
> ERROR STARTS
> Auto-properties install: org.osgi.framework.BundleException: Unable to
> cache
> bundle: file:bundle/org.apache.felix.shell-1.0.2.jar
> Auto-properties install: org.osgi.framework.BundleException: Unable to
> cache
> bundle: file:bundle/org.apache.felix.shell.tui-1.0.2.jar
> Auto-properties install: org.osgi.framework.BundleException: Unable to
> cache
> bundle: file:bundle/org.apache.felix.bundlerepository-1.2.1.jar
> Auto-properties start: org.osgi.framework.BundleException: Unable to cache
> bundle: file:bundle/org.apache.felix.shell-1.0.2.jar
> Auto-properties start: org.osgi.framework.BundleException: Unable to cache
> bundle: file:bundle/org.apache.felix.shell.tui-1.0.2.jar
> Auto-properties start: org.osgi.framework.BundleException: Unable to cache
> bundle: file:bundle/org.apache.felix.bundlerepository-1.2.1.jar
>
Looks like it's picking up the config.properties file from the Felix
installation
(if you look at Main.java in Felix it uses the framework JAR location to
look
for the default configuration)
Unfortunately the default configuration contains relative bundle references
(as you can see in the above warning messages) which means that it can't
find these bundles - this is because we don't have an installer, otherwise
it
could fill in the absolute paths when you first install Felix
Let's say you run your program in C:\Temp...
it launches C:\Users\KK\Desktop\felix-1.4.1\bin\felix.jar
which loads C:\Users\KK\Desktop\felix-1.4.1\conf\config.properties
which refers to the "bundle" directory relative to the current directory
but your CWD is C:\Temp and C:\Temp\bundle does not exist :(
you might think the answer is for the main launcher to "cd" to the
installation
where the property files are so the relative references are ok, but this
would
not work if the installation folder was read-only and is generally a bad
idea.
the real solution is to use the -Dfelix.config.properties setting to point
Felix
to your own config file where you can give the correct bundle references
BUT... there is an even better option for your situation, which is embedding
which would avoid all the issues with handling external processes, I/O, etc.
and provide much more accurate benchmarking
take a look at the simple launcher in the OSGi in Action examples:
http://code.google.com/p/osgi-in-action/source/browse/trunk/launcher/src/main/java/launcher/Main.java
this is a single file that embeds Felix and installs (and starts) bundles
from
the given directory. You could easily add instrumentation to time this
startup,
you also might want to use System.nanoTime() (Java 5) for more accuracy
when timing short intervals.
After this, it hangs ...
>
well for one you're not consuming the output stream which means the process
could block when the output buffer is full - to avoid this sort of issue and
the
perils of timing one Java process from a different process you should really
use embedding (see above) which avoids all this forking around :)
but this particular hang is more likely to be because the default behaviour
of
Felix is to keep running until someone stops the main system bundle, or
kills
the process. Again embedding gives you much more control over this, take
a look at the following doc:
http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html
HTH
Any help on what the issue might be?
>
> By the way, is there a better way to calculate the time taken to load
> bundles ??
>
if you use embedding you can calculate the individual time to load each
bundle - but there will be all sorts of factors coming into play such as the
existing set of loaded bundles, etc. that could potentially skew results
(adding a bundle is not a trivial operation - it can have knock-on effects
on unresolved bundles, etc. - you will probably find individual timings vary
depending on the order that you install and start bundles, even though the
total time may remain relatively constant)
for a more detailed breakdown of where the time goes I'd strongly suggest
you use a profiler (like YourKit / JProfiler) which you can attach to your
tests
> Thanks,
> Krishnaveni Krishnarajah
>
--
Cheers, Stuart