You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2022/09/20 08:40:19 UTC
[maven-resolver] branch master updated: Add a tool to verify file locking on OS/FS/Java combo. (#198)
This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new 9ca3751d Add a tool to verify file locking on OS/FS/Java combo. (#198)
9ca3751d is described below
commit 9ca3751daea8c492ee661022862fdaeea7d230af
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Tue Sep 20 10:40:13 2022 +0200
Add a tool to verify file locking on OS/FS/Java combo. (#198)
Using this tool users can validate will file locking work from
them from single host. This does NOT validate distributed
locking, only the file locking.
---
.../src/main/java/TestNioLock.java | 196 +++++++++++++++++++++
1 file changed, 196 insertions(+)
diff --git a/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/TestNioLock.java b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/TestNioLock.java
new file mode 100644
index 00000000..5d906553
--- /dev/null
+++ b/maven-resolver-demos/maven-resolver-demo-snippets/src/main/java/TestNioLock.java
@@ -0,0 +1,196 @@
+// CHECKSTYLE_OFF: RegexpHeader
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A simple tool to check file locking on your OS/FS/Java combo. To use this tool, just copy it to baseDir on
+ * the volume you plan to use as local repository and compile and run it:
+ * <ul>
+ * <li><pre>javac TestNioLock.java</pre></li>
+ * <li><pre>java TestNioLock test someFile 1000</pre></li>
+ * </ul>
+ */
+public class TestNioLock
+{
+ private static final int EC_WON = 10;
+
+ private static final int EC_LOST = 20;
+
+ private static final int EC_FAILED = 30;
+
+ private static final int EC_ERROR = 100;
+
+ public static void main( String[] args ) throws IOException, InterruptedException
+ {
+ if ( args.length != 3 )
+ {
+ System.out.println( "TestNioLock <test|perform> <file> <sleepMs>" );
+ System.exit( EC_ERROR );
+ }
+
+ String mode = args[0];
+ Path path = Paths.get( args[1] ).toAbsolutePath();
+ Path latchFile = path.getParent().resolve( TestNioLock.class.getName() + ".latchFile" );
+
+ if ( Files.isDirectory( path ) )
+ {
+ System.out.println( "The <file> cannot be directory." );
+ System.exit( EC_ERROR );
+ }
+ if ( !Files.isRegularFile( latchFile ) )
+ {
+ Files.createFile( latchFile );
+ }
+
+ if ( "test".equals( mode ) )
+ {
+ System.out.println( "Testing file locking on" );
+ System.out.println(
+ " Java " + System.getProperty( "java.version" ) + ", " + System.getProperty( "java.vendor" ) );
+ System.out.println(
+ " OS " + System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + " "
+ + System.getProperty( "os.arch" ) );
+
+ FileStore fileStore = Files.getFileStore( path.getParent() );
+ System.out.println( " FS " + fileStore.name() + " " + fileStore.type() );
+ System.out.println();
+
+ AtomicInteger oneResult = new AtomicInteger( -1 );
+ AtomicInteger twoResult = new AtomicInteger( -1 );
+ CountDownLatch latch = new CountDownLatch( 2 );
+ String javaCmd = System.getProperty( "java.home" ) + "/bin/java";
+
+ try ( FileChannel latchChannel = FileChannel.open( latchFile, StandardOpenOption.READ,
+ StandardOpenOption.WRITE ) )
+ {
+ try ( FileLock latchLock = latchChannel.lock( 0L, 1L, false ) )
+ {
+ new Thread( () ->
+ {
+ try
+ {
+ oneResult.set( new ProcessBuilder( javaCmd, TestNioLock.class.getName(),
+ "perform", args[1], args[2] ).inheritIO().start().waitFor() );
+ }
+ catch ( Exception e )
+ {
+ oneResult.set( EC_FAILED );
+ }
+ finally
+ {
+ latch.countDown();
+ }
+ } ).start();
+ new Thread( () ->
+ {
+ try
+ {
+ twoResult.set( new ProcessBuilder( javaCmd, TestNioLock.class.getName(),
+ "perform", args[1], args[2] ).inheritIO().start().waitFor() );
+ }
+ catch ( Exception e )
+ {
+ twoResult.set( EC_FAILED );
+ }
+ finally
+ {
+ latch.countDown();
+ }
+ } ).start();
+
+ Thread.sleep( 1000 ); // give them a bit of time (to both block)
+ latchLock.release();
+ latch.await();
+ }
+ }
+
+
+ int oneExit = oneResult.get();
+ int twoExit = twoResult.get();
+ if ( ( oneExit == EC_WON && twoExit == EC_LOST ) || ( oneExit == EC_LOST && twoExit == EC_WON ) )
+ {
+ System.out.println( "OK" );
+ System.exit( 0 );
+ }
+ else
+ {
+ System.out.println( "FAILED: one=" + oneExit + " two=" + twoExit );
+ System.exit( EC_FAILED );
+ }
+ }
+ else if ( "perform".equals( mode ) )
+ {
+ String processName = ManagementFactory.getRuntimeMXBean().getName();
+ System.out.println( processName + " > started" );
+ boolean won = false;
+ long sleepMs = Long.parseLong( args[2] );
+ try ( FileChannel latchChannel = FileChannel.open( latchFile, StandardOpenOption.READ ) )
+ {
+ try ( FileLock latchLock = latchChannel.lock( 0L, 1L, true ) )
+ {
+ System.out.println( processName + " > latchLock acquired" );
+ try ( FileChannel channel = FileChannel.open( path, StandardOpenOption.READ,
+ StandardOpenOption.WRITE, StandardOpenOption.CREATE ) )
+ {
+ try ( FileLock lock = channel.tryLock( 0L, 1L, false ) )
+ {
+ if ( lock != null && lock.isValid() && !lock.isShared() )
+ {
+ System.out.println( processName + " > WON" );
+ won = true;
+ Thread.sleep( sleepMs );
+ }
+ else
+ {
+ System.out.println( processName + " > LOST" );
+ }
+ }
+ }
+ }
+ }
+ System.out.println( processName + " > ended" );
+ if ( won )
+ {
+ System.exit( EC_WON );
+ }
+ else
+ {
+ System.exit( EC_LOST );
+ }
+ }
+ else
+ {
+ System.err.println( "Unknown mode: " + mode );
+ }
+ System.exit( EC_ERROR );
+ }
+}
\ No newline at end of file