changeset 326:54cbfb3a5469

fixed LRU cache behaviour in case of failure. Tests added
author Jiri Vanek <jvanek@redhat.com>
date Wed, 01 Feb 2012 18:46:57 +0100
parents 847e4e6d0e06
children 466a2440ed59
files ChangeLog netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java netx/net/sourceforge/jnlp/cache/CacheUtil.java netx/net/sourceforge/jnlp/cache/LruCacheException.java netx/net/sourceforge/jnlp/resources/Messages.properties netx/net/sourceforge/jnlp/util/PropertiesFile.java tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer1.jnlp tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer1_1.jnlp tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer2.jnlp tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer2_1.jnlp tests/jnlp_tests/signed/CacheReproducer/srcs/CacheReproducer.java tests/jnlp_tests/signed/CacheReproducer/testcases/CacheReproducerTest.java tests/jnlp_tests/signed/SimpletestSigned1/resources/SimpletestSigned1.jnlp tests/jnlp_tests/signed/SimpletestSigned1/srcs/SimpletestSigned1.java tests/netx/jnlp_testsengine/net/sourceforge/jnlp/ServerAccess.java
diffstat 15 files changed, 766 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Jan 27 16:20:22 2012 -0500
+++ b/ChangeLog	Wed Feb 01 18:46:57 2012 +0100
@@ -1,3 +1,31 @@
+2012-02-01 Jiri Vanek<jvanek@redhat.com>
+
+	Fix for PR844
+	* netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java: (getLRUSortedEntries)
+	instead of error throwing own LRU exception. Also catches more then
+	NumberFormatException
+	(clearLRUSortedEntries) new method - making soft clearing of cache public
+	(clearCache) now return true if cache was cleared, false otherwise 
+	(or exception)
+	* netx/net/sourceforge/jnlp/cache/CacheUtil.java: (getCacheFileIfExist) 
+	does three tires to load cache. If ifrst fails, then recently_used file
+	is emptied both in memory and on disc. When second attemmpt fails, then
+	LRU cache is forcibly cleared. if clearing fails, then error is thrown.
+	If it pass, then one more try to load entries is allowed. When third
+	attempt fails, then error is  thrown.
+	* /netx/net/sourceforge/jnlp/cache/LruCacheException.java:
+	new file, for purpose of catching this particular exception
+	* netx/net/sourceforge/jnlp/util/PropertiesFile.java: (store) tries to 
+	mkdirs to its path. It is better then to fail when no cache directory exists.
+	* tests/jnlp_tests/signed/CacheReproducer: new  reproducr trying severals 
+	way of corupted cache on several types of jnlp files. Is signed because
+	of reflection used.
+	* tests/jnlp_tests/signed/SimpletestSigned1: signed hello world to be
+	used in  CacheReproducer tests.
+	* tests/netx/jnlp_testsengine/net/sourceforge/jnlp/ServerAccess.java: 
+	timeout for processes doubled, as clear cache methods sometimes took
+	more then original allowed.
+
 2012-01-27  Deepak Bhole <dbhole@redhat.com>
 
 	PR852: Classloader not being flushed after last applet from a site is closed
--- a/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java	Fri Jan 27 16:20:22 2012 -0500
+++ b/netx/net/sourceforge/jnlp/cache/CacheLRUWrapper.java	Wed Feb 01 18:46:57 2012 +0100
@@ -36,6 +36,8 @@
  */
 package net.sourceforge.jnlp.cache;
 
+import static  net.sourceforge.jnlp.runtime.Translator.R;
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.channels.FileLock;
@@ -178,10 +180,8 @@
 
                     int c = t1.compareTo(t2);
                     return c < 0 ? 1 : (c > 0 ? -1 : 0);
-                } catch (NumberFormatException e) {
-                    // Perhaps an error is too harsh. Maybe just somehow turn
-                    // caching off if this is the case.
-                    throw new InternalError("Corrupt LRU file entries");
+                } catch (Exception e) {
+                    throw new LruCacheException(R("Corrupt LRU file entries"));
                 }
             }
         });
@@ -249,4 +249,8 @@
     public String generateKey(String path) {
         return System.currentTimeMillis() + "," + getIdForCacheFolder(path);
     }
+
+    void clearLRUSortedEntries() {
+        cacheOrder.clear();
+    }
 }
--- a/netx/net/sourceforge/jnlp/cache/CacheUtil.java	Fri Jan 27 16:20:22 2012 -0500
+++ b/netx/net/sourceforge/jnlp/cache/CacheUtil.java	Wed Feb 01 18:46:57 2012 +0100
@@ -144,16 +144,16 @@
      * process is using them can be quite disasterous. Hence why Launcher creates lock files
      * and we check for those by calling {@link #okToClearCache()}
      */
-    public static void clearCache() {
+    public static boolean clearCache() {
 
         if (!okToClearCache()) {
             System.err.println(R("CCannotClearCache"));
-            return;
+            return false;
         }
 
         File cacheDir = new File(CacheUtil.cacheDir);
         if (!(cacheDir.isDirectory())) {
-            return;
+            return false;
         }
 
         if (JNLPRuntime.isDebug()) {
@@ -165,6 +165,7 @@
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
+        return true;
     }
 
     /**
@@ -322,7 +323,37 @@
     private static File getCacheFileIfExist(File urlPath) {
         synchronized (lruHandler) {
             File cacheFile = null;
-            List<Entry<String, String>> entries = lruHandler.getLRUSortedEntries();
+            int tries = 0;
+            List<Entry<String, String>> entries = null;
+            do {
+                try {
+                    tries++;
+                    entries = lruHandler.getLRUSortedEntries();
+                } catch (LruCacheException ex) {
+                    if (tries == 1) {
+                        ex.printStackTrace();
+                        System.out.println(R("CFakeCache"));
+                        lruHandler.clearLRUSortedEntries();
+                        lruHandler.store();
+                        System.out.println(R("CFakedCache"));
+                    } else if (tries == 2) {
+                        ex.printStackTrace();
+                        System.out.println(R("CStillCorupted"));
+                        boolean clearingresult = CacheUtil.clearCache();
+                        if (!clearingresult) {
+                            throw new InternalError(R("CCleaningUnsuccessful"));
+                        }
+                        System.out.println(R("CClearedReloading"));
+                        lruHandler.clearLRUSortedEntries();
+                        lruHandler.store();
+                        System.out.println(R("CReloadRestarting"));
+
+                    } else {
+                        throw new InternalError(R("CStillBroken"));
+                    }
+
+                }
+            } while (entries == null);
             // Start searching from the most recent to least recent.
             for (Entry<String, String> e : entries) {
                 final String key = e.getKey();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/cache/LruCacheException.java	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,52 @@
+/* LruCacheException.java -- Thrown when cache is corrupted.
+Copyright (C) 2012 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+package net.sourceforge.jnlp.cache;
+
+class LruCacheException extends RuntimeException {
+
+    public LruCacheException() {
+        super();
+    }
+
+    public LruCacheException(String string) {
+        super(string);
+    }
+
+    public LruCacheException(Throwable cause) {
+        super(cause);
+    }
+}
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties	Fri Jan 27 16:20:22 2012 -0500
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties	Wed Feb 01 18:46:57 2012 +0100
@@ -190,6 +190,13 @@
 CChooseCacheInfo=Netx needs a location for storing cache files.
 CChooseCacheDir=Cache directory
 CCannotClearCache=Can not clear cache at this time
+CFakeCache=Cache is corrupt. Disabling.
+CFakedCache=Cache is corrupt and has been disabled. It is strongly recommended that you run 'javaws -Xclearcache' and rerun your application as soon as possible.
+CStillCorupted=Cache is still corrupt, clearing it.
+CCleaningUnsuccessful=Unable to clear cache due to running javaws instance. Please try to shut down all instances of javaws, run 'javaws -Xclearcache', and rerun your jnlp file
+CClearedReloading=Cache cleared, re-loading.
+CReloadRestarting=Cache re-loaded and application re-starting. It is strongly recommended that you run 'javaws -Xclearcache' and re-run your application as soon as possible.
+CStillBroken=Unable to fix corrupt cache. Please shutdown all javaws instances, run 'javaws -Xclearcache', and re-start your application.
 
 # Security
 SFileReadAccess=The application has requested read access to {0}. Do you want to allow this action?
--- a/netx/net/sourceforge/jnlp/util/PropertiesFile.java	Fri Jan 27 16:20:22 2012 -0500
+++ b/netx/net/sourceforge/jnlp/util/PropertiesFile.java	Wed Feb 01 18:46:57 2012 +0100
@@ -134,6 +134,7 @@
         OutputStream s = null;
         try {
             try {
+                file.getParentFile().mkdirs();
                 s = new FileOutputStream(file);
                 store(s, header);
             } finally {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer1.jnlp	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<jnlp spec="1.0"
+      codebase="./"
+      href="CacheReproducer1.jnlp">
+    <information>
+        <title>Just prints out "Good simple javaws exapmle" using reflection call from CacheReproducer.jar SimpletestSigned1.jar</title>
+    </information>
+    <resources>
+        <jar href="CacheReproducer.jar" main="true"/>
+        <jar href="SimpletestSigned1.jar" main="false" download="eager"/>  
+    </resources>
+    <application-desc main-class="CacheReproducer"/>
+     <security>
+      <all-permissions/>
+    </security>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer1_1.jnlp	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<jnlp spec="1.0"
+      codebase="./"
+      href="CacheReproducer1_1.jnlp">
+    <information>
+        <title>Just prints out "Good simple javaws exapmle" using reflection call from CacheReproducer.jar SimpletestSigned1.jar</title>
+    </information>
+    <resources>
+        <jar href="CacheReproducer.jar" main="true"/>
+        <jar href="SimpletestSigned1.jar" main="false" download="lazy"/>
+    </resources>
+    <application-desc main-class="CacheReproducer"/>
+     <security>
+      <all-permissions/>
+    </security>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer2.jnlp	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<jnlp spec="1.0"
+      codebase="./"
+      href="CacheReproducer2.jnlp">
+    <information>
+        <title>Just prints out "Good simple javaws exapmle" using reflection call from CacheReproducer.jar SimpletestSigned1.jar</title>
+    </information>
+    <resources>
+        <jar href="SimpletestSigned1.jar" main="false" download="eager"/>
+        <jar href="CacheReproducer.jar" main="true"/>
+    </resources>
+    <application-desc main-class="CacheReproducer"/>
+     <security>
+      <all-permissions/>
+    </security>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/resources/CacheReproducer2_1.jnlp	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?> 
+<jnlp spec="1.0"
+      codebase="./"
+      href="CacheReproducer2_1.jnlp">
+    <information>
+        <title><title>Just prints out "Good simple javaws exapmle" using reflection call from CacheReproducer.jar SimpletestSigned1.jar</title></title>
+    </information>
+    <resources>
+        <jar href="SimpletestSigned1.jar" main="false" download="lazy"/>
+        <jar href="CacheReproducer.jar" main="true"/>
+    </resources>
+    <application-desc main-class="CacheReproducer"/>
+     <security>
+      <all-permissions/>
+    </security>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/srcs/CacheReproducer.java	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,47 @@
+/* CacheReproducer.java
+Copyright (C) 2012 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+import java.lang.reflect.*;
+
+public class CacheReproducer{
+
+    public static void main(String[] args) throws Exception{
+        Class c1= Class.forName("SimpletestSigned1");
+        Method m1=c1.getDeclaredMethod("main",args.getClass());
+        m1.invoke((Object) null, (Object)args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/CacheReproducer/testcases/CacheReproducerTest.java	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,427 @@
+/* CacheReproducerTest.java
+Copyright (C) 2012 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import net.sourceforge.jnlp.ServerAccess;
+import net.sourceforge.jnlp.ServerAccess.ProcessResult;
+import org.junit.AfterClass;
+import org.junit.Assert;
+
+import org.junit.Test;
+
+public class CacheReproducerTest {
+
+    private static final ServerAccess server = new ServerAccess();
+    private static final List<String> clear = Arrays.asList(new String[]{server.getJavawsLocation(), "-Xclearcache"});
+    private static final List<String> trusted = Arrays.asList(new String[]{"-Xtrustall", ServerAccess.HEADLES_OPTION});
+    private static final String home = System.getProperty("user.home");
+    private static final String name = System.getProperty("user.name");
+    private static final String tmp = System.getProperty("java.io.tmpdir");
+    private static final File icedteaDir = new File(home + "/" + ".icedtea");
+    private static final File icedteaCache = new File(icedteaDir, "cache");
+    private static final File icedteaCacheFile = new File(icedteaCache, "recently_used");
+    private static final File netxLock = new File(tmp + "/" + name + "/netx/locks/netx_running");
+    private static final String lre = "LruCacheException";
+    private static final String corruptRegex = "\\d{13}";
+    private static final Pattern corruptPatern = Pattern.compile(corruptRegex);
+    private static final String corruptString = "156dsf1562kd5";
+
+    @Test
+    public void cacheIsWorkingTest() throws Exception {
+        clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+    }
+
+    @Test
+    public void cacheIsWorkingTestSigned() throws Exception {
+        clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1Signed());
+        assertCacheIsNotEmpty();
+    }
+
+     private class ParallelSimpleTestRunner extends Thread {
+           public boolean b=false;
+            @Override
+            public void run() {
+                try {
+
+                    ServerAccess.ProcessResult pr = runSimpleTest1();
+                    evaluateSimpleTest1OkCache(pr);
+                    b=true;
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        };
+
+    @Test
+    public void startParallelInstancesUponBrokenCache() throws Exception {
+        clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        breakCache1();
+        ParallelSimpleTestRunner t1=new ParallelSimpleTestRunner();
+        ParallelSimpleTestRunner t2=new ParallelSimpleTestRunner();
+        ParallelSimpleTestRunner t3=new ParallelSimpleTestRunner();
+        t1.start();
+        t2.start();
+        t3.start();
+        int c=0;
+        while(true){
+            c++;
+            Thread.sleep(100);
+            if (c>600) throw new Error("threads have not died in time");
+            if (!t1.isAlive() && !t2.isAlive() && !t3.isAlive()) break;
+        }
+        Thread.sleep(1000);
+        Assert.assertTrue(t1.b);
+        Assert.assertTrue(t2.b);
+        Assert.assertTrue(t3.b);
+    }
+
+
+    private void assertCacheIsNotEmpty() {
+        Assert.assertTrue("icedtea cache " + icedteaCache.getAbsolutePath() + " should exist some any run", icedteaCache.exists());
+        Assert.assertTrue("icedtea cache file " + icedteaCacheFile.getAbsolutePath() + " should exist some any run", icedteaCacheFile.exists());
+        Assert.assertTrue("icedtea cache file " + icedteaCacheFile.getAbsolutePath() + " should not be empty", icedteaCacheFile.length() > 0);
+    }
+
+    @Test
+    public void coruptAndRunCache1() throws Exception {
+        clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        breakCache1();
+        ProcessResult pr = runSimpleTest1();
+        assertLruExceptionAppeared(pr);
+        evaluateSimpleTest1OkCache(pr);
+        clearAndEvaluateCache();
+        ProcessResult pr2 = runSimpleTest1();
+        evaluateSimpleTest1OkCache(pr2);
+        assertLruExceptionNOTappeared(pr2);
+    }
+
+    @Test
+    public void coruptAndRunCache2() throws Exception {
+         clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        breakCache1();
+        ProcessResult pr = runSimpleTest1();
+        assertLruExceptionAppeared(pr);
+        evaluateSimpleTest1OkCache(pr);
+        ProcessResult pr3 = runSimpleTest1();
+        evaluateSimpleTest1OkCache(pr3);
+        assertLruExceptionNOTappeared(pr3);
+        clearAndEvaluateCache();
+        ProcessResult pr2 = runSimpleTest1();
+        evaluateSimpleTest1OkCache(pr2);
+        assertLruExceptionNOTappeared(pr2);
+    }
+
+    private void assertLruExceptionNOTappeared(ProcessResult pr2) {
+        Assert.assertFalse("serr should NOT contain " + lre, pr2.stderr.contains(lre));
+    }
+
+    private void assertLruExceptionAppeared(ProcessResult pr) {
+        Assert.assertTrue("serr should contain " + lre, pr.stderr.contains(lre));
+    }
+
+    @Test
+    public void coruptAndRunCache1Signed() throws Exception {
+         clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        breakCache1();
+        ProcessResult pr = runSimpleTest1Signed();
+        assertLruExceptionAppeared(pr);
+        evaluateSimpleTest1OkCache(pr);
+        clearAndEvaluateCache();
+        ProcessResult pr2 = runSimpleTest1Signed();
+        evaluateSimpleTest1OkCache(pr2);
+        assertLruExceptionNOTappeared(pr2);
+    }
+
+    @Test
+    public void coruptAndRunCache2Signed() throws Exception {
+         clearAndEvaluateCache();
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        breakCache1();
+        ProcessResult pr = runSimpleTest1Signed();
+        assertLruExceptionAppeared(pr);
+        evaluateSimpleTest1OkCache(pr);
+        ProcessResult pr3 = runSimpleTest1Signed();
+        evaluateSimpleTest1OkCache(pr3);
+        assertLruExceptionNOTappeared(pr3);
+        clearAndEvaluateCache();
+        ProcessResult pr2 = runSimpleTest1Signed();
+        evaluateSimpleTest1OkCache(pr2);
+        assertLruExceptionNOTappeared(pr2);
+    }
+
+    @Test
+    public void clearCacheUnsucessfully() throws Exception {
+        evaluateSimpleTest1OkCache(runSimpleTest1());
+        assertCacheIsNotEmpty();
+        ProcessResult pr;
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    System.out.println("connecting deadlocktest request");
+                    System.err.println("connecting deadlocktest request");
+                    ServerAccess.ProcessResult pr = server.executeJavawsHeadless(null, "/deadlocktest.jnlp");
+                    System.out.println(pr.stdout);
+                    System.err.println(pr.stderr);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        });
+        t.start();
+        Thread.sleep(1000);
+        pr = tryToClearcache();
+        System.out.println(pr.stdout);
+        System.err.println(pr.stderr);
+        String q = "Can not clear cache at this time";
+        Assert.assertTrue("Stderr should contain " + q + ", but did not.", pr.stderr.contains(q));
+        assertCacheIsNotEmpty();
+    }
+
+     
+    //next four tests are designed to ensure, that corupted cache wil not break already loaded cached files
+    public static final String CR1 = "CacheReproducer1";
+    public static final String CR2 = "CacheReproducer2";
+    public static final String CR11 = "CacheReproducer1_1";
+    public static final String CR21 = "CacheReproducer2_1";
+
+    public void testsBody(String id, int breaker) throws Exception {
+        clearAndEvaluateCache();
+        ProcessResult pr1 = runSimpleTestSigned(id);
+        assertLruExceptionNOTappeared(pr1);
+        evaluateSimpleTest1OkCache(pr1);
+        if (breaker < 0) {
+            breakCache1();
+        } else {
+            breakCache2(breaker);
+        }
+        ProcessResult pr2 = runSimpleTestSigned(id);
+        assertLruExceptionAppeared(pr2);
+        evaluateSimpleTest1OkCache(pr2);
+    }
+
+    @Test
+    public void testAlreadyLoadedCached1() throws Exception {
+        testsBody(CR1, 1);
+        testsBody(CR1, 2);
+        testsBody(CR1, -1);
+    }
+
+    @Test
+    public void testAlreadyLoadedCached2() throws Exception {
+        testsBody(CR2, 1);
+        testsBody(CR2, 2);
+        testsBody(CR2, -1);
+    }
+
+    @Test
+    public void testAlreadyLoadedCached11() throws Exception {
+        testsBody(CR11, 1);
+        testsBody(CR11, 2);
+        testsBody(CR11, -1);
+    }
+
+    @Test
+    public void testAlreadyLoadedCached21() throws Exception {
+        testsBody(CR21, 1);
+        testsBody(CR21, 2);
+        testsBody(CR21, -1);
+    }
+
+    @AfterClass
+    public static void clearCache() throws Exception {
+        clearAndEvaluateCache();
+    }
+
+    private static void clearAndEvaluateCache() throws Exception {
+        clearAndEvaluateCache(true);
+    }
+
+    private static void clearAndEvaluateCache(boolean force) throws Exception {
+        System.out.println("clearing cache");
+        System.err.println("clearing cache");
+        if (force) {
+            if (netxLock.isFile()) {
+                boolean b = netxLock.delete();
+                junit.framework.Assert.assertTrue(b);
+            }
+
+        }
+        tryToClearcache();
+        Assert.assertFalse("icedtea cache " + icedteaCache.getAbsolutePath() + " should not exist after clearing", icedteaCache.exists());
+    }
+
+    private static String loadFile(File f) throws FileNotFoundException, UnsupportedEncodingException, IOException {
+        BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(icedteaCacheFile), "UTF-8"));
+        StringBuilder sb = new StringBuilder();
+        while (true) {
+            String s = r.readLine();
+            if (s == null) {
+                break;
+            }
+            sb.append(s).append("\n");
+
+        }
+        return sb.toString();
+    }
+
+    private static String loadCacheFile() throws IOException {
+        return loadFile(icedteaCacheFile);
+    }
+
+    @Test
+    public void assertBreakersAreWorking() {
+        String s = "#netx file\n"
+                + "#Mon Dec 12 16:20:46 CET 2011\n"
+                + "1323703236508,0=/home/xp13/.icedtea/cache/0/http/localhost/ReadPropertiesBySignedHack.jnlp\n"
+                + "1323703243086,2=/home/xp14/.icedtea/cache/2/http/localhost/ReadProperties.jar\n"
+                + "1323703243082,1=/home/xp15/.icedtea/cache/1/http/localhost/ReadPropertiesBySignedHack.jar";
+        String sp[] = s.split("\n");
+
+        String ss[] = breakAll(s).split("\n");
+        for (int i = 0; i < 2; i++) {
+            Assert.assertEquals(sp[i], ss[i]);
+
+        }
+        for (int i = 2; i < ss.length; i++) {
+            Assert.assertNotSame(sp[i], ss[i]);
+
+        }
+        String sb = breakOne(s, 0);
+        junit.framework.Assert.assertEquals(s, sb);
+        for (int x = 1; x <= 3; x++) {
+            String[] sx = breakOne(s, x).split("\n");
+            for (int i = 0; i < sx.length; i++) {
+                if (i == x + 1) {
+                    Assert.assertNotSame(sp[i], sx[i]);
+                } else {
+                    Assert.assertEquals(sp[i], sx[i]);
+                }
+
+            }
+        }
+        String sbb = breakOne(s, 4);
+        Assert.assertEquals(s, sbb);
+    }
+
+    private static String breakAll(String s) {
+        return s.replaceAll(corruptRegex, corruptString);
+    }
+
+    private static String breakOne(String s, int i) {
+        Matcher m1 = corruptPatern.matcher(s);
+        int x = 0;
+        while (m1.find()) {
+            x++;
+            String r = (m1.group(0));
+            if (x == i) {
+                return s.replace(r, corruptString);
+            }
+        }
+        return s;
+    }
+
+    private static void breakCache1() throws IOException {
+        String s = loadCacheFile();
+        s = breakAll(s);
+        ServerAccess.saveFile(s, icedteaCacheFile);
+    }
+
+    private static void breakCache2(int i) throws FileNotFoundException, UnsupportedEncodingException, IOException {
+        String s = loadCacheFile();
+        s = breakOne(s, i);
+        ServerAccess.saveFile(s, icedteaCacheFile);
+    }
+
+    private static ServerAccess.ProcessResult runSimpleTest1() throws Exception {
+        return runSimpleTest1(null, "simpletest1");
+    }
+
+    private static ServerAccess.ProcessResult runSimpleTest1(List<String> args, String s) throws Exception {
+        System.out.println("connecting " + s + " request");
+        System.err.println("connecting " + s + " request");
+        ServerAccess.ProcessResult pr2 = server.executeJavawsHeadless(args, "/" + s + ".jnlp");
+        System.out.println(pr2.stdout);
+        System.err.println(pr2.stderr);
+        return pr2;
+    }
+
+    private static ServerAccess.ProcessResult runSimpleTest1Signed() throws Exception {
+        return runSimpleTestSigned("SimpletestSigned1");
+    }
+
+    private static ServerAccess.ProcessResult runSimpleTestSigned(String id) throws Exception {
+        return runSimpleTest1(trusted, id);
+    }
+
+    private static void evaluateSimpleTest1OkCache(ServerAccess.ProcessResult pr2) throws Exception {
+        String s = "Good simple javaws exapmle";
+        Assert.assertTrue("test stdout should contain " + s + " but didn't", pr2.stdout.contains(s));
+        Assert.assertFalse(pr2.wasTerminated);
+        Assert.assertEquals((Integer) 0, pr2.returnValue);
+    }
+
+    private static ProcessResult tryToClearcache() throws Exception {
+        ServerAccess.ProcessResult pr1 = ServerAccess.executeProcess(clear);
+        System.out.println(pr1.stdout);
+        System.err.println(pr1.stderr);
+        return pr1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/SimpletestSigned1/resources/SimpletestSigned1.jnlp	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,53 @@
+<!--
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+
+ -->
+<?xml version="1.0" encoding="utf-8"?>
+<jnlp spec="1.0" href="SimpletestSigned1.jnlp" codebase=".">
+  <information>
+    <title>simpletest1</title>
+    <vendor>NetX</vendor>
+    <homepage href="http://jnlp.sourceforge.net/netx/"/>
+    <description>simpletest1</description>
+    <offline/>
+  </information>
+  <resources>
+    <j2se version="1.4+"/>
+    <jar href="SimpletestSigned1.jar"/>
+  </resources>
+  <application-desc main-class="SimpletestSigned1">
+  </application-desc>
+</jnlp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/jnlp_tests/signed/SimpletestSigned1/srcs/SimpletestSigned1.java	Wed Feb 01 18:46:57 2012 +0100
@@ -0,0 +1,43 @@
+/* SimpletestSigned1.java
+Copyright (C) 2012 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version.
+ */
+
+public class SimpletestSigned1{
+
+    public static void main(String[] args){
+        System.out.println("Good simple javaws exapmle");
+    }
+}
--- a/tests/netx/jnlp_testsengine/net/sourceforge/jnlp/ServerAccess.java	Fri Jan 27 16:20:22 2012 -0500
+++ b/tests/netx/jnlp_testsengine/net/sourceforge/jnlp/ServerAccess.java	Wed Feb 01 18:46:57 2012 +0100
@@ -108,7 +108,7 @@
      * timeout in ms to let process to finish, before assasin wil kill it.
      * This can be changed in runtime, but will affect all following tasks
      */
-    public static long PROCESS_TIMEOUT = 10 * 1000;//ms
+    public static long PROCESS_TIMEOUT = 20 * 1000;//ms
     /**
      * all terminated processes are stored here. As wee need to 'wait' to termination to be finished.
      */