Hi,
I survey the issue Harmony-4942, found the Harmony's behavior of finding "jndi.properties" file is not the same as ri's: Harmony re-search the whole CLASSPATH every construction time, while ri just search once when using a classloader to
find the file at first time. The following code prove it:

=============begin=============

            URL url = new File("test1").toURL();
            URLClassLoader cltest1 = new URLClassLoader(new URL[] { url },
                    Thread.currentThread().getContextClassLoader());
            Thread test1 = new Thread(new Runnable() {

                public void run() {
                    try {
                        System.out.println("test1 classloader"
                                + Thread.currentThread()
                                        .getContextClassLoader());
                        FileOutputStream fos = new FileOutputStream(
                                "test1/jndi.properties");
                        PrintStream ps = new PrintStream(fos);
                        ps

.println("java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory");

ps.println("java.naming.provider.url=http://test1";);
                        ps.close();

                        InitialContext context = new InitialContext();
                        System.out.println("test1.context=    " + context);
                        System.out.println("test1.context.env="
                                + context.getEnvironment());

                        File file = new File("test1/jndi.properties");
                        file.delete();

                        // create new properties file with different values
                        fos = new FileOutputStream(
                                "test1/jndi.properties");
                        ps = new PrintStream(fos);
                        ps

.println("java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory");

ps.println("java.naming.provider.url=http://test1.new";);
                        ps.close();

                        context = new InitialContext();
                        System.out.println("test1.new.context=" + context);
                        System.out.println("test1.new.context.env="
                                + context.getEnvironment());

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            });
            // use different classloader
            test1.setContextClassLoader(cltest1);

            test1.start();

            url = new File("test2").toURL();
URLClassLoader clSrc = new URLClassLoader(new URL[] { url }, Thread
                    .currentThread().getContextClassLoader());

            Thread test2 = new Thread(new Runnable() {

                public void run() {
                    try {
                        System.out.println("test2 classloader"
                                + Thread.currentThread()
                                        .getContextClassLoader());
                        FileOutputStream fos = new FileOutputStream(
                                "test2/jndi.properties");
                        PrintStream ps = new PrintStream(fos);
                        ps

.println("java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory");

ps.println("java.naming.provider.url=http://test2";);
                        ps.close();
                        InitialContext context = new InitialContext();
                        System.out.println("test2.context=    " + context);
                        System.out.println("test2.context.env="
                                + context.getEnvironment());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            });

            // use different classloader
            test2.setContextClassLoader(clSrc);
            test2.start();

===================end=================
(I slightly modify MyDefaultInitialContextFactory, add environment values to MyInitialContext after initial)

the output is below, using jre1.6.0:

============start output===============

test1 [EMAIL PROTECTED]
test1.context=    [EMAIL PROTECTED]
test1.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory, java.naming.provider.url=http://test1}
[EMAIL PROTECTED]
test1.new.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory, java.naming.provider.url=http://test1}
test2 [EMAIL PROTECTED]
test2.context=    [EMAIL PROTECTED]
test2.context.env={java.naming.factory.initial=regis.jndi.MyDefaultInitialContextFactory, java.naming.provider.url=http://test2}

=============end output=================

So under same classloader, ri just search property file once.

In harmony we can use a map to hold property values for each classloader to avoid search at every construction time. But i found Harmony is still slower than ri at first time to constuct InitialContext object, the most time is consumed at
org.apache.harmony.jndi.internal.EnvironmentReader line 233:
p.load(is);

Then i write some sample code to test performance of Properties.load():

Properties pro = new Properties();
         URL url = new

URL("jar:file:/home/bahamut/harmony/trunk/deploy/jdk/jre/lib/boot/jndi.jar!/jndi.properties");
         InputStream in = url.openStream();
         long start = System.currentTimeMillis();
         pro.load(in);
         long end = System.currentTimeMillis();
         System.out.println("time: " + (end - start));
         in.close();

         pro = new Properties();
         url = new

URL("jar:file:/home/bahamut/harmony/trunk/deploy/jdk/jre/lib/boot/jndi.jar!/jndi.properties");
         in = url.openStream();
         start = System.currentTimeMillis();
         pro.load(in);
         end = System.currentTimeMillis();
         System.out.println("time: " + (end - start));
         in.close();

output of ri:
time: 1
time: 0

output of harmony:
time: 231
time: 1

Harmony is slower than ri *two hundred* times!!
in above test, property file is in jndi.jar about 230k, if not in jar file, the time of harmony and ri are very close, so i think there must be some problems of archive module. Is it because of we using different algorithm with ri,
or our implementation has bugs?

Best Regards,
Regis.

Reply via email to