55import java .io .*;
66import java .nio .channels .FileChannel ;
77import java .nio .channels .FileLock ;
8+ import java .nio .channels .OverlappingFileLockException ;
89import java .nio .charset .StandardCharsets ;
910import java .nio .file .Files ;
1011import java .nio .file .Path ;
@@ -144,7 +145,7 @@ private static Path recycleJarFileWithLock(String resourcePath, Path jarPath) th
144145
145146 try (RandomAccessFile lockFile = new RandomAccessFile (lockPath .toFile (), "rw" );
146147 FileChannel lockChannel = lockFile .getChannel ();
147- FileLock lock = acquireLock (lockChannel , 1500 , 50 )
148+ FileLock lock = acquireLock (lockChannel , getJarRecyclingTimeout () , 50 )
148149 ) {
149150 if (lock == null ) throw new IOException ("Could not acquire lock for: " + lockPath );
150151
@@ -167,9 +168,13 @@ private static FileLock acquireLock(FileChannel lockChannel, long timeout, long
167168 long end = System .currentTimeMillis () + timeout ;
168169
169170 while (System .currentTimeMillis () < end ) {
170- FileLock lock = lockChannel .tryLock ();
171- if (lock != null ) return lock ;
172-
171+ try {
172+ FileLock lock = lockChannel .tryLock ();
173+ if (lock != null ) return lock ;
174+ } catch (OverlappingFileLockException e ) {
175+ System .err .println ("OverlappingFileLock occured." + e );
176+ throw new IOException (e );
177+ }
173178 try {
174179 Thread .sleep (retryDelay );
175180 } catch (InterruptedException e ) {
@@ -218,6 +223,30 @@ private static boolean isRecyclingEnabled() {
218223 return "true" .equalsIgnoreCase (isRecyclingEnabledValue );
219224 }
220225
226+ /**
227+ * If the recycling of jars is enabled, the timeout for the recycling/file locking operation can be set.
228+ * The value has to be a non-zero non-negative long, if the conditions are not met, it defaults to 3000ms.
229+ *
230+ * @return long, either the default of 3000ms or the value of the timeout property
231+ */
232+ private static long getJarRecyclingTimeout () {
233+ String recyclingTimeout = null != System .getProperty (AgentProperties .RECYCLE_JARS_TIMEOUT_PROPERTY ) ?
234+ System .getProperty (AgentProperties .RECYCLE_JARS_TIMEOUT_PROPERTY ) : System .getenv (AgentProperties .RECYCLE_JARS_TIMEOUT_ENV_PROPERTY );
235+
236+ final long DEFAULT_RECYCLE_TIMEOUT = 3000 ;
237+
238+ if (recyclingTimeout == null ) return DEFAULT_RECYCLE_TIMEOUT ;
239+
240+ try {
241+ long recyclingTimeoutLong = Long .parseUnsignedLong (recyclingTimeout );
242+ if (recyclingTimeoutLong <= 0 ) throw new NumberFormatException ();
243+ return recyclingTimeoutLong ;
244+ } catch (NumberFormatException nfe ) {
245+ System .err .println ("Jar Recycling Timeout property must be a non-negative non-zero long, therefore reverting to default timeout of 3000ms." );
246+ return DEFAULT_RECYCLE_TIMEOUT ;
247+ }
248+ }
249+
221250 /**
222251 * Reads the current agent version from the ocelot-version.info file
223252 *
0 commit comments