update to OpenJDK 21, update to Grdle 8.4, add key parameter for loading private key by classloader

This commit is contained in:
Jörg Prante 2023-10-13 23:22:42 +02:00
parent 4eff2cd434
commit 2b879107d7
35 changed files with 139 additions and 174 deletions

1
.gitignore vendored
View file

@ -15,6 +15,7 @@ logs
*~ *~
.secret .secret
build build
**/*.key
**/*.crt **/*.crt
**/*.pkcs8 **/*.pkcs8
**/*.gz **/*.gz

View file

@ -4,9 +4,10 @@ plugins {
id "pmd" id "pmd"
id 'maven-publish' id 'maven-publish'
id 'signing' id 'signing'
id "io.github.gradle-nexus.publish-plugin" version "1.3.0" id "io.github.gradle-nexus.publish-plugin" version "2.0.0-rc-1"
id "com.github.spotbugs" version "5.0.14" id "com.github.spotbugs" version "6.0.0-beta.3"
id "org.cyclonedx.bom" version "1.7.2" id "org.cyclonedx.bom" version "1.7.4"
id "org.xbib.gradle.plugin.asciidoctor" version "3.0.0"
} }
wrapper { wrapper {
@ -30,14 +31,14 @@ ext {
} }
subprojects { subprojects {
apply from: rootProject.file('gradle/ide/idea.gradle') //apply from: rootProject.file('gradle/ide/idea.gradle')
apply from: rootProject.file('gradle/repositories/maven.gradle') apply from: rootProject.file('gradle/repositories/maven.gradle')
apply from: rootProject.file('gradle/compile/java.gradle') apply from: rootProject.file('gradle/compile/java.gradle')
apply from: rootProject.file('gradle/test/junit5.gradle') apply from: rootProject.file('gradle/test/junit5.gradle')
apply from: rootProject.file('gradle/publish/maven.gradle') apply from: rootProject.file('gradle/publish/maven.gradle')
apply from: rootProject.file('gradle/quality/checkstyle.gradle') apply from: rootProject.file('gradle/quality/checkstyle.gradle')
apply from: rootProject.file('gradle/quality/pmd.gradle') apply from: rootProject.file('gradle/quality/pmd.gradle')
apply from: rootProject.file('gradle/quality/spotbugs.gradle') //apply from: rootProject.file('gradle/quality/spotbugs.gradle')
} }
apply from: rootProject.file('gradle/publish/sonatype.gradle') apply from: rootProject.file('gradle/publish/sonatype.gradle')
apply from: rootProject.file('gradle/publish/forgejo.gradle') apply from: rootProject.file('gradle/publish/forgejo.gradle')

View file

@ -49,11 +49,11 @@ import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Matchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.anyCollectionOf; import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Matchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -330,7 +330,7 @@ public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo/bar"), options)) { try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo/bar"), options)) {
// don't do anything with the stream, there's a separate test for that // don't do anything with the stream, there's a separate test for that
} finally { } finally {
verify(getExceptionFactory()).createNewOutputStreamException(eq("/foo/bar"), eq(553), anyString(), anyCollectionOf(OpenOption.class)); verify(getExceptionFactory()).createNewOutputStreamException(eq("/foo/bar"), eq(553), anyString(), anyList());
assertSame(foo, getFileSystemEntry("/foo")); assertSame(foo, getFileSystemEntry("/foo"));
assertSame(bar, getFileSystemEntry("/foo/bar")); assertSame(bar, getFileSystemEntry("/foo/bar"));
} }
@ -347,7 +347,7 @@ public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo/bar"), options)) { try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo/bar"), options)) {
// don't do anything with the stream, there's a separate test for that // don't do anything with the stream, there's a separate test for that
} finally { } finally {
verify(getExceptionFactory()).createNewOutputStreamException(eq("/foo/bar"), eq(553), anyString(), anyCollectionOf(OpenOption.class)); verify(getExceptionFactory()).createNewOutputStreamException(eq("/foo/bar"), eq(553), anyString(), anyList());
assertSame(foo, getFileSystemEntry("/foo")); assertSame(foo, getFileSystemEntry("/foo"));
assertSame(bar, getFileSystemEntry("/foo/bar")); assertSame(bar, getFileSystemEntry("/foo/bar"));
} }
@ -427,8 +427,7 @@ public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo"), options)) { try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo"), options)) {
// don't do anything with the stream, there's a separate test for that // don't do anything with the stream, there's a separate test for that
} finally { } finally {
verify(getExceptionFactory(), never()).createNewOutputStreamException(anyString(), anyInt(), anyString(), verify(getExceptionFactory(), never()).createNewOutputStreamException(anyString(), anyInt(), anyString(), anyList());
anyCollectionOf(OpenOption.class));
assertSame(foo, getFileSystemEntry("/foo")); assertSame(foo, getFileSystemEntry("/foo"));
assertEquals(0, getChildCount("/foo")); assertEquals(0, getChildCount("/foo"));
} }
@ -443,8 +442,7 @@ public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo"), options)) { try (OutputStream input = getFileSystem().newOutputStream(createPath("/foo"), options)) {
// don't do anything with the stream, there's a separate test for that // don't do anything with the stream, there's a separate test for that
} finally { } finally {
verify(getExceptionFactory(), never()).createNewOutputStreamException(anyString(), anyInt(), anyString(), verify(getExceptionFactory(), never()).createNewOutputStreamException(anyString(), anyInt(), anyString(), anyList());
anyCollectionOf(OpenOption.class));
assertSame(foo, getFileSystemEntry("/foo")); assertSame(foo, getFileSystemEntry("/foo"));
assertEquals(0, getChildCount("/foo")); assertEquals(0, getChildCount("/foo"));
} }
@ -693,7 +691,7 @@ public class FTPFileSystemTest extends AbstractFTPFileSystemTest {
try { try {
getFileSystem().copy(createPath("/foo/bar"), createPath("/baz/bar"), options); getFileSystem().copy(createPath("/foo/bar"), createPath("/baz/bar"), options);
} finally { } finally {
verify(getExceptionFactory()).createNewOutputStreamException(eq("/baz/bar"), eq(553), anyString(), anyCollectionOf(OpenOption.class)); verify(getExceptionFactory()).createNewOutputStreamException(eq("/baz/bar"), eq(553), anyString(), anyList());
assertSame(foo, getFileSystemEntry("/foo")); assertSame(foo, getFileSystemEntry("/foo"));
assertSame(bar, getFileSystemEntry("/foo/bar")); assertSame(bar, getFileSystemEntry("/foo/bar"));
assertNull(getFileSystemEntry("/baz")); assertNull(getFileSystemEntry("/baz"));

View file

@ -2755,7 +2755,7 @@ public class FTPClient extends FTP implements Configurable {
* happen when parserKey is neither * happen when parserKey is neither
* the fully qualified class name of a class * the fully qualified class name of a class
* implementing the interface * implementing the interface
* {@link }FTPFileEntryParser} * {@link FTPFileEntryParser}
* nor a string containing one of the recognized keys * nor a string containing one of the recognized keys
* mapping to such a parser or if class loader * mapping to such a parser or if class loader
* security issues prevent its being loaded. * security issues prevent its being loaded.

View file

@ -7,7 +7,7 @@ module org.xbib.files.sftp.fs {
exports org.apache.sshd.fs; exports org.apache.sshd.fs;
exports org.apache.sshd.fs.spi; exports org.apache.sshd.fs.spi;
requires org.xbib.files; requires org.xbib.files;
requires transitive org.xbib.files.sftp; requires org.xbib.files.sftp;
provides FileSystemProvider with SftpFileSystemProvider; provides FileSystemProvider with SftpFileSystemProvider;
provides FileServiceProvider with SFTPFileServiceProvider; provides FileServiceProvider with SFTPFileServiceProvider;
requires java.logging; requires java.logging;

View file

@ -83,6 +83,7 @@ import org.apache.sshd.common.auth.BasicCredentialsImpl;
import org.apache.sshd.common.auth.BasicCredentialsProvider; import org.apache.sshd.common.auth.BasicCredentialsProvider;
import org.apache.sshd.common.auth.MutableBasicCredentials; import org.apache.sshd.common.auth.MutableBasicCredentials;
import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.keyprovider.ClassLoadableResourceKeyPairProvider;
import org.apache.sshd.common.keyprovider.KeyIdentityProvider; import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.NumberUtils; import org.apache.sshd.common.util.NumberUtils;
@ -197,12 +198,13 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if (port <= 0) { if (port <= 0) {
port = SshConstants.DEFAULT_PORT; port = SshConstants.DEFAULT_PORT;
} }
Object o = env.get("username"); Object o = env.get("username");
String username = o instanceof String ? (String) o : o != null ? o.toString() : null; String username = o instanceof String ? (String) o : o != null ? o.toString() : null;
o = env.get("password"); o = env.get("password");
char[] password = o instanceof char[] ? (char[]) o : o instanceof String ? ((String)o).toCharArray() : null; char[] password = o instanceof char[] ? (char[]) o : o instanceof String ? ((String)o).toCharArray() : null;
if (env.containsKey("key")) {
clientInstance.setKeyIdentityProvider(new ClassLoadableResourceKeyPairProvider(env.get("key").toString()));
}
boolean disableServerKeys = "true".equals(env.get("disableServerKeys")); boolean disableServerKeys = "true".equals(env.get("disableServerKeys"));
if (disableServerKeys) { if (disableServerKeys) {
clientInstance.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE); clientInstance.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE);
@ -280,7 +282,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if (session != null) { if (session != null) {
try { try {
session.close(); session.close();
} catch (IOException t) { } catch (Exception t) {
e.addSuppressed(t); e.addSuppressed(t);
} }
} }

View file

@ -4,23 +4,11 @@ import org.junit.jupiter.api.Test;
import org.xbib.files.FileService; import org.xbib.files.FileService;
import java.io.IOException; import java.io.IOException;
import java.security.Provider;
import java.security.Security;
import java.util.Map; import java.util.Map;
import java.util.ServiceLoader;
import java.util.logging.Logger; import java.util.logging.Logger;
public class FileServiceProviderTest { public class FileServiceProviderTest {
static {
// load bouncy castle provider (and other security providers)
for (Provider p : ServiceLoader.load(Provider.class)) {
if (Security.getProvider(p.getName()) == null) {
Security.addProvider(p);
}
}
}
@Test @Test
public void testSFTP() throws IOException { public void testSFTP() throws IOException {
Map<String, ?> env = Map.of("username", "joerg"); Map<String, ?> env = Map.of("username", "joerg");

View file

@ -0,0 +1,22 @@
package org.apache.sshd.fs.test;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.logging.Logger;
import org.junit.jupiter.api.Test;
import org.xbib.files.FileService;
public class SftpClientTest {
@Test
public void testSFTP() throws IOException {
String targetURLString = "sftp://fernleihe-test.hbz-nrw.de:22";
String targetIdString = "malva";
URI uri = URI.create(targetURLString);
FileService fs = FileService.newInstance(targetURLString,
Map.of("username", targetIdString,
"key", uri.getHost() + "/" + targetIdString + ".key"));
fs.list(".").forEach(p -> Logger.getAnonymousLogger().info(p.toString()));
}
}

View file

@ -75,7 +75,6 @@ import org.apache.sshd.common.Factory;
import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.ServiceFactory; import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.config.keys.PublicKeyEntry; import org.apache.sshd.common.config.keys.PublicKeyEntry;
import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.helpers.AbstractFactoryManager; import org.apache.sshd.common.helpers.AbstractFactoryManager;
@ -732,7 +731,6 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
} else if (id instanceof KeyPair) { } else if (id instanceof KeyPair) {
KeyPair kp = (KeyPair) id; KeyPair kp = (KeyPair) id;
session.addPublicKeyIdentity(kp); session.addPublicKeyIdentity(kp);
} else {
} }
} }
} }

View file

@ -34,7 +34,7 @@ import org.apache.sshd.common.util.GenericUtils;
public interface PasswordIdentityProvider { public interface PasswordIdentityProvider {
/** /**
* An &quot;empty&quot implementation of {@link PasswordIdentityProvider} that returns and empty group of passwords * An &quot;empty&quot; implementation of {@link PasswordIdentityProvider} that returns and empty group of passwords
*/ */
PasswordIdentityProvider EMPTY_PASSWORDS_PROVIDER = new PasswordIdentityProvider() { PasswordIdentityProvider EMPTY_PASSWORDS_PROVIDER = new PasswordIdentityProvider() {
@Override @Override

View file

@ -20,6 +20,7 @@
package org.apache.sshd.client.impl; package org.apache.sshd.client.impl;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.security.KeyPair; import java.security.KeyPair;
@ -82,12 +83,16 @@ public class SimpleSftpClientImpl implements SimpleSftpClient {
SimpleClient client = getClient(); SimpleClient client = getClient();
ClientSession session = sessionProvider.apply(client); ClientSession session = sessionProvider.apply(client);
try { try {
SftpClient sftp = createSftpClient(session); SftpClient sftpClient = createSftpClient(session);
session = null; // disable auto-close at finally block session = null;
return sftp; return sftpClient;
} finally { } finally {
if (session != null) { if (session != null) {
try {
session.close(); session.close();
} catch (Exception e) {
throw new IOException(e);
}
} }
} }
} }

View file

@ -23,8 +23,8 @@ import org.apache.sshd.common.CoreModuleProperties;
/** /**
* Provides a way to implement proxied connections where some metadata about the client is sent <U>before</U> the actual * Provides a way to implement proxied connections where some metadata about the client is sent <U>before</U> the actual
* SSH protocol is executed - e.g., the <A HREF=@http://www.haproxy.org/download/1.6/doc/proxy-protocol.txt">PROXY * SSH protocol is executed - e.g., the http://www.haproxy.org/download/1.6/doc/proxy-protocol.txt PROXY
* protocol</A>. The implementor should use the {@code IoSession#write(Buffer)} method to send any packets with the * protocol. The implementor should use the {@code IoSession#write(Buffer)} method to send any packets with the
* meta-data. * meta-data.
* *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>

View file

@ -18,13 +18,8 @@
*/ */
package org.apache.sshd.client.session; package org.apache.sshd.client.session;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.PublicKey; import java.security.PublicKey;
import java.time.Duration; import java.time.Duration;

View file

@ -125,8 +125,8 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
if (session != null) { if (session != null) {
try { try {
session.close(); session.close();
} catch (IOException e) { } catch (Exception e) {
err = GenericUtils.accumulateException(err, e); err = GenericUtils.accumulateException(err, new IOException(e));
} }
} }
} }

View file

@ -33,7 +33,7 @@ import org.apache.sshd.common.future.SshFutureListener;
* *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/ */
public interface Closeable extends Channel { public interface Closeable extends AutoCloseable {
/** /**
* Close this resource asynchronously and return a future. Resources support two closing modes: a graceful mode * Close this resource asynchronously and return a future. Resources support two closing modes: a graceful mode
@ -76,13 +76,12 @@ public interface Closeable extends Channel {
*/ */
boolean isClosing(); boolean isClosing();
@Override
default boolean isOpen() { default boolean isOpen() {
return !(isClosed() || isClosing()); return !(isClosed() || isClosing());
} }
@Override @Override
default void close() throws IOException { default void close() throws Exception {
Closeable.close(this); Closeable.close(this);
} }

View file

@ -44,9 +44,6 @@ public final class CoreModuleProperties {
public static final Property<String> PROXY_AUTH_CHANNEL_TYPE public static final Property<String> PROXY_AUTH_CHANNEL_TYPE
= Property.string("ssh-agent-factory-proxy-auth-channel-type", "auth-agent-req@openssh.com"); = Property.string("ssh-agent-factory-proxy-auth-channel-type", "auth-agent-req@openssh.com");
/**
* See {@link org.apache.sshd.agent.local.ProxyAgentFactory#getChannelForwardingFactories}
*/
public static final Property<Boolean> PREFER_UNIX_AGENT public static final Property<Boolean> PREFER_UNIX_AGENT
= Property.bool("ssh-prefer-unix-agent", OsUtils.isUNIX()); = Property.bool("ssh-prefer-unix-agent", OsUtils.isUNIX());
@ -147,8 +144,6 @@ public final class CoreModuleProperties {
/** /**
* Whether to ignore invalid identities files when pre-initializing the client session * Whether to ignore invalid identities files when pre-initializing the client session
*
* @see ClientIdentityLoader#isValidLocation(NamedResource)
*/ */
public static final Property<Boolean> IGNORE_INVALID_IDENTITIES public static final Property<Boolean> IGNORE_INVALID_IDENTITIES
= Property.bool("ignore-invalid-identities", true); = Property.bool("ignore-invalid-identities", true);
@ -579,105 +574,84 @@ public final class CoreModuleProperties {
public static final Property<String> MODULI_URL public static final Property<String> MODULI_URL
= Property.string("moduli-url"); = Property.string("moduli-url");
/**
* See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
*/
public static final Property<String> KB_SERVER_INTERACTIVE_NAME public static final Property<String> KB_SERVER_INTERACTIVE_NAME
= Property.string("kb-server-interactive-name", "Password authentication"); = Property.string("kb-server-interactive-name", "Password authentication");
/**
* See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
*/
public static final Property<String> KB_SERVER_INTERACTIVE_INSTRUCTION public static final Property<String> KB_SERVER_INTERACTIVE_INSTRUCTION
= Property.string("kb-server-interactive-instruction", ""); = Property.string("kb-server-interactive-instruction", "");
/**
* See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
*/
public static final Property<String> KB_SERVER_INTERACTIVE_LANG public static final Property<String> KB_SERVER_INTERACTIVE_LANG
= Property.string("kb-server-interactive-language", "en-US"); = Property.string("kb-server-interactive-language", "en-US");
/**
* See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
*/
public static final Property<String> KB_SERVER_INTERACTIVE_PROMPT public static final Property<String> KB_SERVER_INTERACTIVE_PROMPT
= Property.string("kb-server-interactive-prompt", "Password: "); = Property.string("kb-server-interactive-prompt", "Password: ");
/**
* See {@link org.apache.sshd.server.auth.keyboard.DefaultKeyboardInteractiveAuthenticator}.
*/
public static final Property<Boolean> KB_SERVER_INTERACTIVE_ECHO_PROMPT public static final Property<Boolean> KB_SERVER_INTERACTIVE_ECHO_PROMPT
= Property.bool("kb-server-interactive-echo-prompt", false); = Property.bool("kb-server-interactive-echo-prompt", false);
/** /**
* Maximum amount of extended (a.k.a. STDERR) data allowed to be accumulated until a {@link ChannelDataReceiver} for * Maximum amount of extended (a.k.a. STDERR) data allowed to be accumulated until a ChannelDataReceiver for
* the data is registered * the data is registered
*/ */
public static final Property<Integer> MAX_EXTDATA_BUFSIZE public static final Property<Integer> MAX_EXTDATA_BUFSIZE
= Property.integer("channel-session-max-extdata-bufsize", 0); = Property.integer("channel-session-max-extdata-bufsize", 0);
/**
* See {@link org.apache.sshd.server.kex.DHGEXServer}.
*/
public static final Property<Integer> PROP_DHGEX_SERVER_MIN_KEY public static final Property<Integer> PROP_DHGEX_SERVER_MIN_KEY
= Property.integer("dhgex-server-min"); = Property.integer("dhgex-server-min");
/**
* See {@link org.apache.sshd.server.kex.DHGEXServer}.
*/
public static final Property<Integer> PROP_DHGEX_SERVER_MAX_KEY public static final Property<Integer> PROP_DHGEX_SERVER_MAX_KEY
= Property.integer("dhgex-server-max"); = Property.integer("dhgex-server-max");
/** /**
* Value used by the {@link org.apache.sshd.server.shell.InvertedShellWrapper} to control the &quot;busy-wait&quot; * Value used to control the &quot;busy-wait&quot;
* sleep time (millis) on the pumping loop if nothing was pumped - must be <U>positive</U>. * sleep time (millis) on the pumping loop if nothing was pumped - must be <U>positive</U>.
*/ */
public static final Property<Duration> PUMP_SLEEP_TIME public static final Property<Duration> PUMP_SLEEP_TIME
= Property.duration("inverted-shell-wrapper-pump-sleep", Duration.ofMillis(1)); = Property.duration("inverted-shell-wrapper-pump-sleep", Duration.ofMillis(1));
/** /**
* Value used by the {@link org.apache.sshd.server.shell.InvertedShellWrapper} to control copy buffer size. * Value used to control copy buffer size.
*/ */
public static final Property<Integer> BUFFER_SIZE public static final Property<Integer> BUFFER_SIZE
= Property.integer("inverted-shell-wrapper-buffer-size", IoUtils.DEFAULT_COPY_SIZE); = Property.integer("inverted-shell-wrapper-buffer-size", IoUtils.DEFAULT_COPY_SIZE);
/** /**
* Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the channel open * Configuration value to control the channel open
* timeout. * timeout.
*/ */
public static final Property<Duration> X11_OPEN_TIMEOUT public static final Property<Duration> X11_OPEN_TIMEOUT
= Property.duration("x11-fwd-open-timeout", Duration.ofSeconds(30L)); = Property.duration("x11-fwd-open-timeout", Duration.ofSeconds(30L));
/** /**
* Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control from which X11 * Configuration value to control from which X11
* display number to start looking for a free value. * display number to start looking for a free value.
*/ */
public static final Property<Integer> X11_DISPLAY_OFFSET public static final Property<Integer> X11_DISPLAY_OFFSET
= Property.integer("x11-fwd-display-offset", 10); = Property.integer("x11-fwd-display-offset", 10);
/** /**
* Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control up to which (but not * Configuration value to control up to which (but not
* including) X11 display number to look or a free value. * including) X11 display number to look or a free value.
*/ */
public static final Property<Integer> X11_MAX_DISPLAYS public static final Property<Integer> X11_MAX_DISPLAYS
= Property.integer("x11-fwd-max-display", 1000); = Property.integer("x11-fwd-max-display", 1000);
/** /**
* Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the base port number * Configuration value to control the base port number
* for the X11 display number socket binding. * for the X11 display number socket binding.
*/ */
public static final Property<Integer> X11_BASE_PORT public static final Property<Integer> X11_BASE_PORT
= Property.integer("x11-fwd-base-port", 6000); = Property.integer("x11-fwd-base-port", 6000);
/** /**
* Configuration value for the {@link org.apache.sshd.server.x11.X11ForwardSupport} to control the host used to bind * Configuration value to control the host used to bind
* to for the X11 display when looking for a free port. * to for the X11 display when looking for a free port.
*/ */
public static final Property<String> X11_BIND_HOST public static final Property<String> X11_BIND_HOST
= Property.string("x11-fwd-bind-host", SshdSocketAddress.LOCALHOST_IPV4); = Property.string("x11-fwd-bind-host", SshdSocketAddress.LOCALHOST_IPV4);
/** /**
* Configuration value for the {@link org.apache.sshd.server.forward.TcpipServerChannel} to control the higher * Configuration value to control the higher
* theshold for the data to be buffered waiting to be sent. If the buffered data size reaches this value, the * threshold for the data to be buffered waiting to be sent. If the buffered data size reaches this value, the
* session will pause reading until the data length goes below the * session will pause reading until the data length goes below the
* {@link #TCPIP_SERVER_CHANNEL_BUFFER_SIZE_THRESHOLD_LOW} threshold. * {@link #TCPIP_SERVER_CHANNEL_BUFFER_SIZE_THRESHOLD_LOW} threshold.
*/ */

View file

@ -23,9 +23,6 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration; import java.time.Duration;
import org.apache.sshd.common.Property;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.io.IoUtils; import org.apache.sshd.common.util.io.IoUtils;
@ -41,8 +38,6 @@ public final class SftpModuleProperties {
* Used to indicate the {@link Charset} (or its name) for decoding referenced files/folders names - extracted from * Used to indicate the {@link Charset} (or its name) for decoding referenced files/folders names - extracted from
* the client session when 1st initialized. * the client session when 1st initialized.
* *
* @see SftpClient#getNameDecodingCharset()
* @see SftpClient#setNameDecodingCharset(Charset)
*/ */
public static final Property<Charset> NAME_DECODING_CHARSET public static final Property<Charset> NAME_DECODING_CHARSET
= Property.charset("sftp-name-decoding-charset", StandardCharsets.UTF_8); = Property.charset("sftp-name-decoding-charset", StandardCharsets.UTF_8);
@ -54,45 +49,26 @@ public final class SftpModuleProperties {
public static final Property<Duration> SFTP_CHANNEL_OPEN_TIMEOUT public static final Property<Duration> SFTP_CHANNEL_OPEN_TIMEOUT
= Property.duration("sftp-channel-open-timeout", Duration.ofSeconds(15L)); = Property.duration("sftp-channel-open-timeout", Duration.ofSeconds(15L));
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystem}.
*/
public static final Property<Integer> POOL_SIZE public static final Property<Integer> POOL_SIZE
= Property.integer("sftp-fs-pool-size", 8); = Property.integer("sftp-fs-pool-size", 8);
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystemProvider}.
*/
public static final Property<Integer> READ_BUFFER_SIZE public static final Property<Integer> READ_BUFFER_SIZE
= Property.integer("sftp-fs-read-buffer-size"); = Property.integer("sftp-fs-read-buffer-size");
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystemProvider}.
*/
public static final Property<Integer> WRITE_BUFFER_SIZE public static final Property<Integer> WRITE_BUFFER_SIZE
= Property.integer("sftp-fs-write-buffer-size"); = Property.integer("sftp-fs-write-buffer-size");
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystemProvider}.
*/
public static final Property<Duration> CONNECT_TIME public static final Property<Duration> CONNECT_TIME
= Property.duration("sftp-fs-connect-time", Duration.ofSeconds(15L)); = Property.duration("sftp-fs-connect-time", Duration.ofSeconds(15L));
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystemProvider}.
*/
public static final Property<Duration> AUTH_TIME public static final Property<Duration> AUTH_TIME
= Property.duration("sftp-fs-auth-time", Duration.ofSeconds(15L)); = Property.duration("sftp-fs-auth-time", Duration.ofSeconds(15L));
/**
* See {@link org.apache.sshd.sftp.client.fs.SftpFileSystemProvider}.
*/
public static final Property<Charset> NAME_DECODER_CHARSET public static final Property<Charset> NAME_DECODER_CHARSET
= Property.charset("sftp-fs-name-decoder-charset", StandardCharsets.UTF_8); = Property.charset("sftp-fs-name-decoder-charset", StandardCharsets.UTF_8);
/** /**
* Property used to avoid large buffers when * Property used to avoid large buffers when
* {@link org.apache.sshd.sftp.client.impl.AbstractSftpClient#write(SftpClient.Handle, long, byte[], int, int)} is
* invoked with a large buffer size. * invoked with a large buffer size.
*/ */
public static final Property<Integer> WRITE_CHUNK_SIZE public static final Property<Integer> WRITE_CHUNK_SIZE
@ -122,25 +98,22 @@ public final class SftpModuleProperties {
/** /**
* Allows controlling reports of which client extensions are supported (and reported via &quot;support&quot; and * Allows controlling reports of which client extensions are supported (and reported via &quot;support&quot; and
* &quot;support2&quot; server extensions) as a comma-separate list of names. <B>Note:</B> requires overriding the * &quot;support2&quot; server extensions) as a comma-separate list of names. <B>Note:</B> requires overriding the
* {@link AbstractSftpSubsystemHelper#executeExtendedCommand(Buffer, int, String)} command accordingly. If empty * command accordingly. If empty
* string is set then no server extensions are reported * string is set then no server extensions are reported
* *
* @see AbstractSftpSubsystemHelper#DEFAULT_SUPPORTED_CLIENT_EXTENSIONS
*/ */
public static final Property<String> CLIENT_EXTENSIONS public static final Property<String> CLIENT_EXTENSIONS
= Property.string("sftp-client-extensions"); = Property.string("sftp-client-extensions");
/** /**
* Comma-separated list of which {@code OpenSSH} extensions are reported and what version is reported for each - * Comma-separated list of which {@code OpenSSH} extensions are reported and what version is reported for each -
* format: {@code name=version}. If empty value set, then no such extensions are reported. Otherwise, the * format: {@code name=version}. If empty value set, then no such extensions are reported.
* {@link AbstractSftpSubsystemHelper#DEFAULT_OPEN_SSH_EXTENSIONS} are used
*/ */
public static final Property<String> OPENSSH_EXTENSIONS public static final Property<String> OPENSSH_EXTENSIONS
= Property.string("sftp-openssh-extensions"); = Property.string("sftp-openssh-extensions");
/** /**
* Comma separate list of {@code SSH_ACL_CAP_xxx} names - where name can be without the prefix. If not defined then * Comma separate list of {@code SSH_ACL_CAP_xxx} names - where name can be without the prefix.
* {@link AbstractSftpSubsystemHelper#DEFAULT_ACL_SUPPORTED_MASK} is used
*/ */
public static final Property<String> ACL_SUPPORTED_MASK public static final Property<String> ACL_SUPPORTED_MASK
= Property.string("sftp-acl-supported-mask"); = Property.string("sftp-acl-supported-mask");
@ -152,7 +125,7 @@ public final class SftpModuleProperties {
= Property.string("sftp-newline", IoUtils.EOL); = Property.string("sftp-newline", IoUtils.EOL);
/** /**
* Force the use of a max. packet length for {@link AbstractSftpSubsystemHelper#doRead(Buffer, int)} protection * Force the use of a max. packet length for protection
* against malicious packets * against malicious packets
*/ */
public static final Property<Integer> MAX_READDATA_PACKET_LENGTH public static final Property<Integer> MAX_READDATA_PACKET_LENGTH
@ -187,9 +160,6 @@ public final class SftpModuleProperties {
/** /**
* Max. rounds to attempt to create a unique file handle - if all handles already in use after these many rounds, * Max. rounds to attempt to create a unique file handle - if all handles already in use after these many rounds,
* then an exception is thrown * then an exception is thrown
*
* @see SftpSubsystem#generateFileHandle(Path)
* @see #DEFAULT_FILE_HANDLE_ROUNDS
*/ */
public static final Property<Integer> MAX_FILE_HANDLE_RAND_ROUNDS public static final Property<Integer> MAX_FILE_HANDLE_RAND_ROUNDS
= Property.validating( = Property.validating(
@ -200,8 +170,7 @@ public final class SftpModuleProperties {
}); });
/** /**
* Maximum amount of data allocated for listing the contents of a directory in any single invocation of * Maximum amount of data allocated for listing the contents of a directory in any single invocation
* {@link SftpSubsystem#doReadDir(Buffer, int)}
*/ */
public static final Property<Integer> MAX_READDIR_DATA_SIZE public static final Property<Integer> MAX_READDIR_DATA_SIZE
= Property.integer("sftp-max-readdir-data-size", 16 * 1024); = Property.integer("sftp-max-readdir-data-size", 16 * 1024);

View file

@ -36,7 +36,6 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.IntUnaryOperator; import java.util.function.IntUnaryOperator;
import org.apache.sshd.common.AttributeRepository;
import org.apache.sshd.common.Closeable; import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.PropertyResolver;
@ -100,7 +99,7 @@ public abstract class AbstractChannel extends AbstractInnerCloseable implements
private int id = -1; private int id = -1;
private int recipient = -1; private int recipient = -1;
private Session sessionInstance; private Session sessionInstance;
private CloseableExecutorService executor; private final CloseableExecutorService executor;
private final List<RequestHandler<Channel>> requestHandlers = new CopyOnWriteArrayList<>(); private final List<RequestHandler<Channel>> requestHandlers = new CopyOnWriteArrayList<>();
private final Window localWindow; private final Window localWindow;

View file

@ -704,7 +704,7 @@ public final class KeyUtils {
* @param expected The expected fingerprint if {@code null} or empty then returns a failure with the default * @param expected The expected fingerprint if {@code null} or empty then returns a failure with the default
* fingerprint. * fingerprint.
* @param key the {@link PublicKey} - if {@code null} then returns null. * @param key the {@link PublicKey} - if {@code null} then returns null.
* @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint, * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
* {@code null} if no key. * {@code null} if no key.
* @see #getDefaultFingerPrintFactory() * @see #getDefaultFingerPrintFactory()
* @see #checkFingerPrint(String, Factory, PublicKey) * @see #checkFingerPrint(String, Factory, PublicKey)
@ -718,7 +718,7 @@ public final class KeyUtils {
* fingerprint. * fingerprint.
* @param f The {@link Factory} to be used to generate the default {@link Digest} for the key * @param f The {@link Factory} to be used to generate the default {@link Digest} for the key
* @param key the {@link PublicKey} - if {@code null} then returns null. * @param key the {@link PublicKey} - if {@code null} then returns null.
* @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint, * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
* {@code null} if no key. * {@code null} if no key.
*/ */
public static SimpleImmutableEntry<Boolean, String> checkFingerPrint( public static SimpleImmutableEntry<Boolean, String> checkFingerPrint(
@ -731,7 +731,7 @@ public final class KeyUtils {
* fingerprint. * fingerprint.
* @param d The {@link Digest} to be used to generate the default fingerprint for the key * @param d The {@link Digest} to be used to generate the default fingerprint for the key
* @param key the {@link PublicKey} - if {@code null} then returns null. * @param key the {@link PublicKey} - if {@code null} then returns null.
* @return SimpleImmutableEntry<Boolean, String> - key is success indicator, value is actual fingerprint, * @return SimpleImmutableEntry - key is success indicator, value is actual fingerprint,
* {@code null} if no key. * {@code null} if no key.
*/ */
public static SimpleImmutableEntry<Boolean, String> checkFingerPrint(String expected, Digest d, PublicKey key) { public static SimpleImmutableEntry<Boolean, String> checkFingerPrint(String expected, Digest d, PublicKey key) {

View file

@ -47,6 +47,7 @@ import org.apache.sshd.common.util.security.SecurityUtils;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/ */
public abstract class AbstractResourceKeyPairProvider<R> extends AbstractKeyPairProvider { public abstract class AbstractResourceKeyPairProvider<R> extends AbstractKeyPairProvider {
private FilePasswordProvider passwordFinder; private FilePasswordProvider passwordFinder;
/* /*
* NOTE: the map is case insensitive even for Linux, as it is (very) bad practice to have 2 key files that differ * NOTE: the map is case insensitive even for Linux, as it is (very) bad practice to have 2 key files that differ

View file

@ -165,7 +165,7 @@ public final class OsUtils {
} }
/** /**
* Remove {@code Windows} domain and/or group prefix as well as &quot;(User);&quot suffix * Remove {@code Windows} domain and/or group prefix as well as &quot;(User);&quot; suffix
* *
* @param user The original username - ignored if {@code null}/empty * @param user The original username - ignored if {@code null}/empty
* @return The canonical user - unchanged if {@code Unix} O/S * @return The canonical user - unchanged if {@code Unix} O/S

View file

@ -63,13 +63,13 @@ public interface BufferPublicKeyParser<PUB extends PublicKey> {
OpenSSHCertPublicKeyParser.INSTANCE)); OpenSSHCertPublicKeyParser.INSTANCE));
/** /**
* @param keyType The key type - e.g., &quot;ssh-rsa&quot, &quot;ssh-dss&quot; * @param keyType The key type - e.g., ssh-rsa, ssh-dss
* @return {@code true} if this key type is supported by the parser * @return {@code true} if this key type is supported by the parser
*/ */
boolean isKeyTypeSupported(String keyType); boolean isKeyTypeSupported(String keyType);
/** /**
* @param keyType The key type - e.g., &quot;ssh-rsa&quot, &quot;ssh-dss&quot; * @param keyType The key type - e.g., ssh-rsa, ssh-dss
* @param buffer The {@link Buffer} containing the encoded raw public key * @param buffer The {@link Buffer} containing the encoded raw public key
* @return The decoded {@link PublicKey} * @return The decoded {@link PublicKey}
* @throws GeneralSecurityException If failed to generate the key * @throws GeneralSecurityException If failed to generate the key

View file

@ -78,10 +78,6 @@ public final class Builder implements ObjectBuilder<Closeable> {
return this; return this;
} }
public Builder sequential(Object id, Iterable<Closeable> closeables) {
return close(new SequentialCloseable(id, lock, closeables));
}
public Builder parallel(Closeable... closeables) { public Builder parallel(Closeable... closeables) {
if (closeables.length == 1) { if (closeables.length == 1) {
close(closeables[0]); close(closeables[0]);

View file

@ -18,6 +18,8 @@
*/ */
package org.apache.sshd.common.util.closeable; package org.apache.sshd.common.util.closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import org.apache.sshd.common.Closeable; import org.apache.sshd.common.Closeable;
/** /**
@ -25,4 +27,12 @@ import org.apache.sshd.common.Closeable;
*/ */
public abstract class IoBaseCloseable implements Closeable { public abstract class IoBaseCloseable implements Closeable {
@Override
public void close() {
try {
Closeable.close(this);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
} }

View file

@ -42,7 +42,7 @@ public class SequentialCloseable extends SimpleCloseable {
@Override @Override
protected void doClose(boolean immediately) { protected void doClose(boolean immediately) {
Iterator<? extends Closeable> iterator = closeables.iterator(); Iterator<? extends Closeable> iterator = closeables.iterator();
SshFutureListener<CloseFuture> listener = new SshFutureListener<CloseFuture>() { SshFutureListener<CloseFuture> listener = new SshFutureListener<>() {
@SuppressWarnings("synthetic-access") @SuppressWarnings("synthetic-access")
@Override @Override
public void operationComplete(CloseFuture previousFuture) { public void operationComplete(CloseFuture previousFuture) {

View file

@ -76,7 +76,7 @@ public class DERWriter extends FilterOutputStream {
} }
/** /**
* The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it * The integer is always considered to be positive, so if the first byte is &lt; 0, we pad with a zero to make it
* positive * positive
* *
* @param bytes {@link BigInteger} bytes * @param bytes {@link BigInteger} bytes
@ -87,7 +87,7 @@ public class DERWriter extends FilterOutputStream {
} }
/** /**
* The integer is always considered to be positive, so if the first byte is < 0, we pad with a zero to make it * The integer is always considered to be positive, so if the first byte is &lt; 0, we pad with a zero to make it
* positive * positive
* *
* @param bytes {@link BigInteger} bytes * @param bytes {@link BigInteger} bytes

View file

@ -111,7 +111,7 @@ public final class SecurityUtils {
/** /**
* The min. key size value used for testing whether Diffie-Hellman Group Exchange is supported or not. According to * The min. key size value used for testing whether Diffie-Hellman Group Exchange is supported or not. According to
* <A HREF="https://tools.ietf.org/html/rfc4419">RFC 4419</A> section 3: &quot;Servers and clients SHOULD support * <A HREF="https://tools.ietf.org/html/rfc4419">RFC 4419</A> section 3: &quot;Servers and clients SHOULD support
* groups with a modulus length of k bits, where 1024 <= k <= 8192&quot;. </code> * groups with a modulus length of k bits, where 1024 &lt;= k &lt;= 8192&quot;. </code>
* *
* <B>Note: this has been amended by <A HREF="https://tools.ietf.org/html/rfc8270">RFC 8270</A> * <B>Note: this has been amended by <A HREF="https://tools.ietf.org/html/rfc8270">RFC 8270</A>
*/ */
@ -384,7 +384,6 @@ public final class SecurityUtils {
if (REGISTRATION_STATE_HOLDER.get()) { if (REGISTRATION_STATE_HOLDER.get()) {
return; return;
} }
String regsList = System.getProperty(SECURITY_PROVIDER_REGISTRARS, String regsList = System.getProperty(SECURITY_PROVIDER_REGISTRARS,
GenericUtils.join(DEFAULT_SECURITY_PROVIDER_REGISTRARS, ',')); GenericUtils.join(DEFAULT_SECURITY_PROVIDER_REGISTRARS, ','));
boolean bouncyCastleRegistered = false; boolean bouncyCastleRegistered = false;
@ -475,13 +474,11 @@ public final class SecurityUtils {
if (parser == null) { if (parser == null) {
throw new NoSuchProviderException("No registered key-pair resource parser"); throw new NoSuchProviderException("No registered key-pair resource parser");
} }
Collection<KeyPair> ids = parser.loadKeyPairs(session, resourceKey, provider, inputStream); Collection<KeyPair> ids = parser.loadKeyPairs(session, resourceKey, provider, inputStream);
int numLoaded = GenericUtils.size(ids); int numLoaded = GenericUtils.size(ids);
if (numLoaded <= 0) { if (numLoaded <= 0) {
return null; return null;
} }
return ids; return ids;
} }

View file

@ -19,16 +19,27 @@
package org.apache.sshd.common.util.threads; package org.apache.sshd.common.util.threads;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.time.Duration; import java.time.Duration;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.Closeable; import org.apache.sshd.common.Closeable;
public interface CloseableExecutorService extends ExecutorService, Closeable { public interface CloseableExecutorService extends ExecutorService, Closeable {
default boolean awaitTermination(Duration timeout) throws InterruptedException { default boolean awaitTermination(Duration timeout) throws InterruptedException {
Objects.requireNonNull(timeout, "No timeout specified"); Objects.requireNonNull(timeout, "No timeout specified");
return awaitTermination(timeout.toMillis(), TimeUnit.MILLISECONDS); return awaitTermination(timeout.toMillis(), TimeUnit.MILLISECONDS);
} }
@Override
default void close() {
try {
Closeable.close(this);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
} }

View file

@ -120,7 +120,6 @@ public class DavPropertyNameSet extends PropContainer
* in order to successfully add the given entry. * in order to successfully add the given entry.
* @return true if contentEntry is an instance of <code>DavPropertyName</code> * @return true if contentEntry is an instance of <code>DavPropertyName</code>
* that could be added to this set. False otherwise. * that could be added to this set. False otherwise.
* @see PropContainer#addContent(Object)
*/ */
@Override @Override
public boolean addContent(PropEntry contentEntry) { public boolean addContent(PropEntry contentEntry) {

View file

@ -1,5 +1,5 @@
group = org.xbib group = org.xbib
name = files name = files
version = 4.0.0 version = 4.1.0
org.gradle.warning.mode = ALL org.gradle.warning.mode = ALL

View file

@ -2,21 +2,14 @@
apply plugin: 'java-library' apply plugin: 'java-library'
java { java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
modularity.inferModulePath.set(true) modularity.inferModulePath.set(true)
withSourcesJar() withSourcesJar()
withJavadocJar() withJavadocJar()
} }
compileJava {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
compileTestJava {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
jar { jar {
manifest { manifest {
attributes('Implementation-Version': project.version) attributes('Implementation-Version': project.version)
@ -24,7 +17,9 @@ jar {
} }
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xlint:all,-exports') options.fork = true
options.forkOptions.jvmArgs += ['-Duser.language=en','-Duser.country=US']
options.compilerArgs.add('-Xlint:all')
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
} }

Binary file not shown.

View file

@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

22
gradlew vendored
View file

@ -83,7 +83,8 @@ done
# This is normally unused # This is normally unused
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -130,18 +131,21 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -198,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

View file

@ -15,10 +15,10 @@ pluginManagement {
dependencyResolutionManagement { dependencyResolutionManagement {
versionCatalogs { versionCatalogs {
libs { libs {
version('gradle', '8.1.1') version('gradle', '8.4')
version('groovy', '4.0.12') version('groovy', '4.0.12')
version('junit', '5.9.3') version('junit', '5.10.0')
version('net', '3.2.0') version('net', '4.0.0')
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit') library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit') library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit')
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit') library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
@ -27,8 +27,8 @@ dependencyResolutionManagement {
library('junit4', 'junit', 'junit').version('4.13.2') library('junit4', 'junit', 'junit').version('4.13.2')
library('net-security', 'org.xbib', 'net-security').versionRef('net') library('net-security', 'org.xbib', 'net-security').versionRef('net')
library('mockftpserver', 'org.mockftpserver', 'MockFtpServer').version('2.7.1') library('mockftpserver', 'org.mockftpserver', 'MockFtpServer').version('2.7.1')
library('mockito-core', 'org.mockito', 'mockito-core').version('3.7.7') library('mockito-core', 'org.mockito', 'mockito-core').version('5.6.0')
library('mockito-junit-jupiter', 'org.mockito', 'mockito-junit-jupiter').version('3.7.7') library('mockito-junit-jupiter', 'org.mockito', 'mockito-junit-jupiter').version('5.6.0')
} }
} }
} }