diff --git a/azure/src/main/java/ch/cyberduck/core/azure/AzureProtocol.java b/azure/src/main/java/ch/cyberduck/core/azure/AzureProtocol.java
index 06f463bad7e..ad8e937637b 100644
--- a/azure/src/main/java/ch/cyberduck/core/azure/AzureProtocol.java
+++ b/azure/src/main/java/ch/cyberduck/core/azure/AzureProtocol.java
@@ -24,13 +24,16 @@
import ch.cyberduck.core.LocaleFactory;
import ch.cyberduck.core.LoginOptions;
import ch.cyberduck.core.PathContainerService;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.text.DefaultLexicographicOrderComparator;
import java.util.Comparator;
import com.microsoft.azure.storage.core.Base64;
+import com.google.auto.service.AutoService;
+@AutoService(Protocol.class)
public class AzureProtocol extends AbstractProtocol {
@Override
diff --git a/backblaze/src/main/java/ch/cyberduck/core/b2/B2Protocol.java b/backblaze/src/main/java/ch/cyberduck/core/b2/B2Protocol.java
index 53047c46bcf..56fea997872 100644
--- a/backblaze/src/main/java/ch/cyberduck/core/b2/B2Protocol.java
+++ b/backblaze/src/main/java/ch/cyberduck/core/b2/B2Protocol.java
@@ -17,6 +17,7 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.PathContainerService;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.synchronization.ComparisonService;
import ch.cyberduck.core.synchronization.DefaultComparisonService;
@@ -24,7 +25,9 @@
import ch.cyberduck.core.text.DefaultLexicographicOrderComparator;
import java.util.Comparator;
+import com.google.auto.service.AutoService;
+@AutoService(Protocol.class)
public class B2Protocol extends AbstractProtocol {
@Override
diff --git a/box/src/main/java/ch/cyberduck/core/box/BoxProtocol.java b/box/src/main/java/ch/cyberduck/core/box/BoxProtocol.java
index 3434bd8c55c..626aeb8b0ce 100644
--- a/box/src/main/java/ch/cyberduck/core/box/BoxProtocol.java
+++ b/box/src/main/java/ch/cyberduck/core/box/BoxProtocol.java
@@ -16,11 +16,14 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.synchronization.ComparisonService;
import ch.cyberduck.core.synchronization.DefaultComparisonService;
import ch.cyberduck.core.synchronization.ETagComparisonService;
+import com.google.auto.service.AutoService;
+@AutoService(Protocol.class)
public class BoxProtocol extends AbstractProtocol {
@Override
diff --git a/brick/src/main/java/ch/cyberduck/core/brick/BrickProtocol.java b/brick/src/main/java/ch/cyberduck/core/brick/BrickProtocol.java
index b6d273844a8..02c5ba7551e 100644
--- a/brick/src/main/java/ch/cyberduck/core/brick/BrickProtocol.java
+++ b/brick/src/main/java/ch/cyberduck/core/brick/BrickProtocol.java
@@ -19,9 +19,13 @@
import ch.cyberduck.core.Credentials;
import ch.cyberduck.core.CredentialsConfigurator;
import ch.cyberduck.core.LoginOptions;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.features.Pairing;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class BrickProtocol extends AbstractProtocol {
@Override
diff --git a/cli/src/main/java/ch/cyberduck/cli/Terminal.java b/cli/src/main/java/ch/cyberduck/cli/Terminal.java
index 90748ea2ff9..fa9f1009b32 100644
--- a/cli/src/main/java/ch/cyberduck/cli/Terminal.java
+++ b/cli/src/main/java/ch/cyberduck/cli/Terminal.java
@@ -16,54 +16,25 @@
*/
import ch.cyberduck.core.*;
-import ch.cyberduck.core.azure.AzureProtocol;
-import ch.cyberduck.core.b2.B2Protocol;
-import ch.cyberduck.core.box.BoxProtocol;
-import ch.cyberduck.core.brick.BrickProtocol;
import ch.cyberduck.core.cdn.Distribution;
-import ch.cyberduck.core.ctera.CteraProtocol;
-import ch.cyberduck.core.dav.DAVProtocol;
-import ch.cyberduck.core.dav.DAVSSLProtocol;
-import ch.cyberduck.core.deepbox.DeepboxProtocol;
-import ch.cyberduck.core.dropbox.DropboxProtocol;
import ch.cyberduck.core.editor.DefaultEditorListener;
import ch.cyberduck.core.editor.Editor;
import ch.cyberduck.core.editor.EditorFactory;
import ch.cyberduck.core.exception.AccessDeniedException;
import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.exception.NotfoundException;
-import ch.cyberduck.core.ftp.FTPProtocol;
-import ch.cyberduck.core.ftp.FTPTLSProtocol;
-import ch.cyberduck.core.googledrive.DriveProtocol;
-import ch.cyberduck.core.googlestorage.GoogleStorageProtocol;
-import ch.cyberduck.core.hubic.HubicProtocol;
import ch.cyberduck.core.io.DisabledStreamListener;
-import ch.cyberduck.core.irods.IRODSProtocol;
import ch.cyberduck.core.local.Application;
import ch.cyberduck.core.local.ApplicationFinder;
import ch.cyberduck.core.local.ApplicationFinderFactory;
import ch.cyberduck.core.local.TemporaryFileServiceFactory;
import ch.cyberduck.core.logging.LoggerPrintStream;
-import ch.cyberduck.core.manta.MantaProtocol;
-import ch.cyberduck.core.nextcloud.NextcloudProtocol;
-import ch.cyberduck.core.nio.LocalProtocol;
-import ch.cyberduck.core.onedrive.OneDriveProtocol;
-import ch.cyberduck.core.onedrive.SharepointProtocol;
-import ch.cyberduck.core.onedrive.SharepointSiteProtocol;
-import ch.cyberduck.core.openstack.SwiftProtocol;
-import ch.cyberduck.core.owncloud.OwncloudProtocol;
import ch.cyberduck.core.pool.SessionPool;
import ch.cyberduck.core.preferences.Preferences;
import ch.cyberduck.core.preferences.PreferencesFactory;
-import ch.cyberduck.core.s3.S3Protocol;
-import ch.cyberduck.core.sds.SDSProtocol;
-import ch.cyberduck.core.sftp.SFTPProtocol;
-import ch.cyberduck.core.smb.SMBProtocol;
-import ch.cyberduck.core.spectra.SpectraProtocol;
import ch.cyberduck.core.ssl.CertificateStoreX509TrustManager;
import ch.cyberduck.core.ssl.DefaultTrustManagerHostnameCallback;
import ch.cyberduck.core.ssl.PreferencesX509KeyManager;
-import ch.cyberduck.core.storegate.StoregateProtocol;
import ch.cyberduck.core.threading.DisabledAlertCallback;
import ch.cyberduck.core.threading.DisconnectBackgroundAction;
import ch.cyberduck.core.threading.SessionBackgroundAction;
@@ -103,6 +74,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
+import java.util.ServiceLoader;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -135,38 +107,9 @@ public Terminal(final TerminalPreferences defaults, final Options options, final
public Terminal(final ProtocolFactory protocols, final TerminalPreferences defaults, final Options options, final CommandLine input) {
this.protocols = protocols;
this.preferences = defaults.withDefaults(input);
- this.protocols.register(
- new FTPProtocol(),
- new FTPTLSProtocol(),
- new SFTPProtocol(),
- new DAVProtocol(),
- new DAVSSLProtocol(),
- new SMBProtocol(),
- new SwiftProtocol(),
- new S3Protocol(),
- new GoogleStorageProtocol(),
- new AzureProtocol(),
- new IRODSProtocol(),
- new SpectraProtocol(),
- new B2Protocol(),
- new DriveProtocol(),
- new HubicProtocol(),
- new DropboxProtocol(),
- new DropboxProtocol(),
- new OneDriveProtocol(),
- new SharepointProtocol(),
- new SharepointSiteProtocol(),
- new LocalProtocol(),
- new SDSProtocol(),
- new MantaProtocol(),
- new StoregateProtocol(),
- new BrickProtocol(),
- new NextcloudProtocol(),
- new OwncloudProtocol(),
- new CteraProtocol(),
- new BoxProtocol(),
- new DeepboxProtocol()
- );
+ for(Protocol p : ServiceLoader.load(Protocol.class)) {
+ protocols.register(p);
+ }
this.options = options;
log.info("Parsed options {} from input {}", options, input);
this.input = input;
diff --git a/core/pom.xml b/core/pom.xml
index 06a6e9734f8..b567780e816 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -139,6 +139,11 @@
com.joyent.util
fast-md5
+
+ com.google.auto.service
+ auto-service-annotations
+ 1.1.1
+
junit
junit
diff --git a/ctera/src/main/java/ch/cyberduck/core/ctera/CteraProtocol.java b/ctera/src/main/java/ch/cyberduck/core/ctera/CteraProtocol.java
index 261395c1822..24e8161917c 100644
--- a/ctera/src/main/java/ch/cyberduck/core/ctera/CteraProtocol.java
+++ b/ctera/src/main/java/ch/cyberduck/core/ctera/CteraProtocol.java
@@ -18,6 +18,7 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.Credentials;
import ch.cyberduck.core.LoginOptions;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.dav.DAVSSLProtocol;
import ch.cyberduck.core.preferences.PreferencesFactory;
@@ -25,6 +26,9 @@
import ch.cyberduck.core.synchronization.DefaultComparisonService;
import ch.cyberduck.core.synchronization.ETagComparisonService;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class CteraProtocol extends AbstractProtocol {
public static final String CTERA_REDIRECT_URI = String.format("%s:websso",
diff --git a/deepbox/src/main/java/ch/cyberduck/core/deepbox/DeepboxProtocol.java b/deepbox/src/main/java/ch/cyberduck/core/deepbox/DeepboxProtocol.java
index 143ca93b178..3204a24a25e 100644
--- a/deepbox/src/main/java/ch/cyberduck/core/deepbox/DeepboxProtocol.java
+++ b/deepbox/src/main/java/ch/cyberduck/core/deepbox/DeepboxProtocol.java
@@ -16,8 +16,12 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class DeepboxProtocol extends AbstractProtocol {
@Override
public String getIdentifier() {
diff --git a/dracoon/src/main/java/ch/cyberduck/core/sds/SDSProtocol.java b/dracoon/src/main/java/ch/cyberduck/core/sds/SDSProtocol.java
index bad81b01684..79e8b84ec14 100644
--- a/dracoon/src/main/java/ch/cyberduck/core/sds/SDSProtocol.java
+++ b/dracoon/src/main/java/ch/cyberduck/core/sds/SDSProtocol.java
@@ -16,6 +16,7 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.features.Pairing;
import ch.cyberduck.core.features.Scheduler;
@@ -29,6 +30,9 @@
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SDSProtocol extends AbstractProtocol {
@Override
public String getIdentifier() {
diff --git a/dropbox/src/main/java/ch/cyberduck/core/dropbox/DropboxProtocol.java b/dropbox/src/main/java/ch/cyberduck/core/dropbox/DropboxProtocol.java
index 8f91db633f4..40cf7ef08b2 100644
--- a/dropbox/src/main/java/ch/cyberduck/core/dropbox/DropboxProtocol.java
+++ b/dropbox/src/main/java/ch/cyberduck/core/dropbox/DropboxProtocol.java
@@ -17,8 +17,12 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class DropboxProtocol extends AbstractProtocol {
@Override
diff --git a/eue/src/main/java/ch/cyberduck/core/eue/EueProtocol.java b/eue/src/main/java/ch/cyberduck/core/eue/EueProtocol.java
index b5a4b88ade4..3714e2ed3ee 100644
--- a/eue/src/main/java/ch/cyberduck/core/eue/EueProtocol.java
+++ b/eue/src/main/java/ch/cyberduck/core/eue/EueProtocol.java
@@ -16,11 +16,15 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.synchronization.ComparisonService;
import ch.cyberduck.core.synchronization.DefaultComparisonService;
import ch.cyberduck.core.synchronization.ETagComparisonService;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class EueProtocol extends AbstractProtocol {
@Override
diff --git a/freenet/src/main/java/ch/cyberduck/core/freenet/FreenetProtocol.java b/freenet/src/main/java/ch/cyberduck/core/freenet/FreenetProtocol.java
index a66a9c1fcbf..9a892d8766f 100644
--- a/freenet/src/main/java/ch/cyberduck/core/freenet/FreenetProtocol.java
+++ b/freenet/src/main/java/ch/cyberduck/core/freenet/FreenetProtocol.java
@@ -16,9 +16,13 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WebUrlProvider;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class FreenetProtocol extends AbstractProtocol {
@Override
diff --git a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPProtocol.java b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPProtocol.java
index 1f87ce004c7..8f8578ee01c 100644
--- a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPProtocol.java
+++ b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPProtocol.java
@@ -20,10 +20,14 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class FTPProtocol extends AbstractProtocol {
@Override
diff --git a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPTLSProtocol.java b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPTLSProtocol.java
index f69930620cb..cba44506037 100644
--- a/ftp/src/main/java/ch/cyberduck/core/ftp/FTPTLSProtocol.java
+++ b/ftp/src/main/java/ch/cyberduck/core/ftp/FTPTLSProtocol.java
@@ -20,10 +20,14 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class FTPTLSProtocol extends AbstractProtocol {
@Override
public String getIdentifier() {
diff --git a/googledrive/src/main/java/ch/cyberduck/core/googledrive/DriveProtocol.java b/googledrive/src/main/java/ch/cyberduck/core/googledrive/DriveProtocol.java
index c4687351e37..b756770b821 100644
--- a/googledrive/src/main/java/ch/cyberduck/core/googledrive/DriveProtocol.java
+++ b/googledrive/src/main/java/ch/cyberduck/core/googledrive/DriveProtocol.java
@@ -17,8 +17,12 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class DriveProtocol extends AbstractProtocol {
@Override
diff --git a/googlestorage/src/main/java/ch/cyberduck/core/googlestorage/GoogleStorageProtocol.java b/googlestorage/src/main/java/ch/cyberduck/core/googlestorage/GoogleStorageProtocol.java
index 72f66bbfd35..a612b178dfc 100644
--- a/googlestorage/src/main/java/ch/cyberduck/core/googlestorage/GoogleStorageProtocol.java
+++ b/googlestorage/src/main/java/ch/cyberduck/core/googlestorage/GoogleStorageProtocol.java
@@ -21,6 +21,7 @@
import ch.cyberduck.core.DirectoryDelimiterPathContainerService;
import ch.cyberduck.core.LocaleFactory;
import ch.cyberduck.core.PathContainerService;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.features.Location;
import ch.cyberduck.core.synchronization.ChainedComparisonService;
@@ -38,6 +39,9 @@
import java.util.Set;
import java.util.stream.Collectors;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public final class GoogleStorageProtocol extends AbstractProtocol {
@Override
diff --git a/hubic/src/main/java/ch/cyberduck/core/hubic/HubicProtocol.java b/hubic/src/main/java/ch/cyberduck/core/hubic/HubicProtocol.java
index 9e246c40b62..15c08ac3f5e 100644
--- a/hubic/src/main/java/ch/cyberduck/core/hubic/HubicProtocol.java
+++ b/hubic/src/main/java/ch/cyberduck/core/hubic/HubicProtocol.java
@@ -17,9 +17,13 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.openstack.SwiftProtocol;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class HubicProtocol extends AbstractProtocol {
@Override
diff --git a/irods/src/main/java/ch/cyberduck/core/irods/IRODSProtocol.java b/irods/src/main/java/ch/cyberduck/core/irods/IRODSProtocol.java
index 20fa56feaf3..c8e48bdea4e 100644
--- a/irods/src/main/java/ch/cyberduck/core/irods/IRODSProtocol.java
+++ b/irods/src/main/java/ch/cyberduck/core/irods/IRODSProtocol.java
@@ -19,10 +19,14 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public final class IRODSProtocol extends AbstractProtocol {
@Override
diff --git a/manta/src/main/java/ch/cyberduck/core/manta/MantaProtocol.java b/manta/src/main/java/ch/cyberduck/core/manta/MantaProtocol.java
index 9091264e8e6..fc039529abc 100644
--- a/manta/src/main/java/ch/cyberduck/core/manta/MantaProtocol.java
+++ b/manta/src/main/java/ch/cyberduck/core/manta/MantaProtocol.java
@@ -16,8 +16,12 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class MantaProtocol extends AbstractProtocol {
@Override
diff --git a/nextcloud/src/main/java/ch/cyberduck/core/nextcloud/NextcloudProtocol.java b/nextcloud/src/main/java/ch/cyberduck/core/nextcloud/NextcloudProtocol.java
index 015f41facd0..ccbbfb9654f 100644
--- a/nextcloud/src/main/java/ch/cyberduck/core/nextcloud/NextcloudProtocol.java
+++ b/nextcloud/src/main/java/ch/cyberduck/core/nextcloud/NextcloudProtocol.java
@@ -17,6 +17,7 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.CredentialsConfigurator;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WindowsIntegratedCredentialsConfigurator;
import ch.cyberduck.core.dav.DAVSSLProtocol;
@@ -24,6 +25,9 @@
import ch.cyberduck.core.synchronization.DefaultComparisonService;
import ch.cyberduck.core.synchronization.ETagComparisonService;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class NextcloudProtocol extends AbstractProtocol {
@Override
diff --git a/nio/src/main/java/ch/cyberduck/core/nio/LocalProtocol.java b/nio/src/main/java/ch/cyberduck/core/nio/LocalProtocol.java
index f5a04a0a368..78217ebd3ab 100644
--- a/nio/src/main/java/ch/cyberduck/core/nio/LocalProtocol.java
+++ b/nio/src/main/java/ch/cyberduck/core/nio/LocalProtocol.java
@@ -18,6 +18,7 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.Factory;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import org.apache.commons.io.IOCase;
@@ -25,6 +26,9 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class LocalProtocol extends AbstractProtocol {
private static String LOCAL_HOSTNAME;
diff --git a/onedrive/src/main/java/ch/cyberduck/core/onedrive/OneDriveProtocol.java b/onedrive/src/main/java/ch/cyberduck/core/onedrive/OneDriveProtocol.java
index c187e41475e..9b42e016b47 100644
--- a/onedrive/src/main/java/ch/cyberduck/core/onedrive/OneDriveProtocol.java
+++ b/onedrive/src/main/java/ch/cyberduck/core/onedrive/OneDriveProtocol.java
@@ -15,6 +15,11 @@
* GNU General Public License for more details.
*/
+import ch.cyberduck.core.Protocol;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class OneDriveProtocol extends GraphProtocol {
@Override
public String getIdentifier() {
diff --git a/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointProtocol.java b/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointProtocol.java
index cceaab34134..5539435a701 100644
--- a/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointProtocol.java
+++ b/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointProtocol.java
@@ -15,6 +15,11 @@
* GNU General Public License for more details.
*/
+import ch.cyberduck.core.Protocol;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SharepointProtocol extends GraphProtocol {
@Override
public String getIdentifier() {
diff --git a/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointSiteProtocol.java b/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointSiteProtocol.java
index e86f04f0bef..8aefb5080de 100644
--- a/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointSiteProtocol.java
+++ b/onedrive/src/main/java/ch/cyberduck/core/onedrive/SharepointSiteProtocol.java
@@ -15,6 +15,11 @@
* GNU General Public License for more details.
*/
+import ch.cyberduck.core.Protocol;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SharepointSiteProtocol extends GraphProtocol {
@Override
public String getIdentifier() {
diff --git a/openstack/src/main/java/ch/cyberduck/core/openstack/SwiftProtocol.java b/openstack/src/main/java/ch/cyberduck/core/openstack/SwiftProtocol.java
index ed2f1d94556..e33e0576c30 100644
--- a/openstack/src/main/java/ch/cyberduck/core/openstack/SwiftProtocol.java
+++ b/openstack/src/main/java/ch/cyberduck/core/openstack/SwiftProtocol.java
@@ -22,6 +22,7 @@
import ch.cyberduck.core.DefaultPathContainerService;
import ch.cyberduck.core.LocaleFactory;
import ch.cyberduck.core.PathContainerService;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.preferences.PreferencesFactory;
import ch.cyberduck.core.synchronization.ChecksumComparisonService;
@@ -31,6 +32,9 @@
import java.util.Comparator;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SwiftProtocol extends AbstractProtocol {
@Override
public String getName() {
diff --git a/osx/src/main/java/ch/cyberduck/ui/cocoa/MainApplication.java b/osx/src/main/java/ch/cyberduck/ui/cocoa/MainApplication.java
index 00a82ca980e..4c377adb3f2 100644
--- a/osx/src/main/java/ch/cyberduck/ui/cocoa/MainApplication.java
+++ b/osx/src/main/java/ch/cyberduck/ui/cocoa/MainApplication.java
@@ -19,44 +19,17 @@
*/
import ch.cyberduck.binding.application.NSApplication;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.ProtocolFactory;
-import ch.cyberduck.core.azure.AzureProtocol;
-import ch.cyberduck.core.b2.B2Protocol;
-import ch.cyberduck.core.box.BoxProtocol;
-import ch.cyberduck.core.brick.BrickProtocol;
-import ch.cyberduck.core.ctera.CteraProtocol;
-import ch.cyberduck.core.dav.DAVProtocol;
-import ch.cyberduck.core.dav.DAVSSLProtocol;
-import ch.cyberduck.core.deepbox.DeepboxProtocol;
-import ch.cyberduck.core.dropbox.DropboxProtocol;
-import ch.cyberduck.core.eue.EueProtocol;
-import ch.cyberduck.core.ftp.FTPProtocol;
-import ch.cyberduck.core.ftp.FTPTLSProtocol;
-import ch.cyberduck.core.googledrive.DriveProtocol;
-import ch.cyberduck.core.googlestorage.GoogleStorageProtocol;
-import ch.cyberduck.core.hubic.HubicProtocol;
-import ch.cyberduck.core.irods.IRODSProtocol;
import ch.cyberduck.core.logging.LoggerPrintStream;
-import ch.cyberduck.core.manta.MantaProtocol;
-import ch.cyberduck.core.nextcloud.NextcloudProtocol;
-import ch.cyberduck.core.nio.LocalProtocol;
-import ch.cyberduck.core.onedrive.OneDriveProtocol;
-import ch.cyberduck.core.onedrive.SharepointProtocol;
-import ch.cyberduck.core.onedrive.SharepointSiteProtocol;
-import ch.cyberduck.core.openstack.SwiftProtocol;
-import ch.cyberduck.core.owncloud.OwncloudProtocol;
import ch.cyberduck.core.preferences.Preferences;
import ch.cyberduck.core.preferences.PreferencesFactory;
-import ch.cyberduck.core.s3.S3Protocol;
-import ch.cyberduck.core.sds.SDSProtocol;
-import ch.cyberduck.core.sftp.SFTPProtocol;
-import ch.cyberduck.core.smb.SMBProtocol;
-import ch.cyberduck.core.spectra.SpectraProtocol;
-import ch.cyberduck.core.storegate.StoregateProtocol;
import ch.cyberduck.core.threading.ActionOperationBatcher;
import ch.cyberduck.core.threading.AutoreleaseActionOperationBatcher;
import ch.cyberduck.ui.cocoa.controller.MainController;
+import java.util.ServiceLoader;
+
public final class MainApplication {
static {
@@ -83,38 +56,9 @@ public static void main(String... arguments) {
PreferencesFactory.set(preferences);
final ProtocolFactory protocols = ProtocolFactory.get();
- protocols.register(
- new FTPProtocol(),
- new FTPTLSProtocol(),
- new SFTPProtocol(),
- new DAVProtocol(),
- new DAVSSLProtocol(),
- new SMBProtocol(),
- new SwiftProtocol(),
- new S3Protocol(),
- new GoogleStorageProtocol(),
- new AzureProtocol(),
- new IRODSProtocol(),
- new SpectraProtocol(),
- new B2Protocol(),
- new DropboxProtocol(),
- new DriveProtocol(),
- new HubicProtocol(),
- new OneDriveProtocol(),
- new SharepointProtocol(),
- new SharepointSiteProtocol(),
- new LocalProtocol(),
- new MantaProtocol(),
- new SDSProtocol(),
- new StoregateProtocol(),
- new BrickProtocol(),
- new NextcloudProtocol(),
- new OwncloudProtocol(),
- new CteraProtocol(),
- new BoxProtocol(),
- new EueProtocol(),
- new DeepboxProtocol()
- );
+ for(Protocol p : ServiceLoader.load(Protocol.class)) {
+ protocols.register(p);
+ }
protocols.load();
final MainController c = new MainController();
// Must implement NSApplicationDelegate protocol
diff --git a/owncloud/src/main/java/ch/cyberduck/core/owncloud/OwncloudProtocol.java b/owncloud/src/main/java/ch/cyberduck/core/owncloud/OwncloudProtocol.java
index 0702d4661db..aaa029a00cd 100644
--- a/owncloud/src/main/java/ch/cyberduck/core/owncloud/OwncloudProtocol.java
+++ b/owncloud/src/main/java/ch/cyberduck/core/owncloud/OwncloudProtocol.java
@@ -17,6 +17,7 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.CredentialsConfigurator;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WindowsIntegratedCredentialsConfigurator;
import ch.cyberduck.core.dav.DAVSSLProtocol;
@@ -24,6 +25,9 @@
import ch.cyberduck.core.synchronization.DefaultComparisonService;
import ch.cyberduck.core.synchronization.ETagComparisonService;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class OwncloudProtocol extends AbstractProtocol {
@Override
diff --git a/pom.xml b/pom.xml
index c60665c0c6a..f0bb100891c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -440,6 +440,13 @@
${maven.compiler.target}
${maven.compiler.target}
+
+
+ com.google.auto.service
+ auto-service
+ 1.1.1
+
+
diff --git a/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java b/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java
index 73073ca7e81..962eaa57c40 100644
--- a/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java
+++ b/s3/src/main/java/ch/cyberduck/core/s3/S3Protocol.java
@@ -42,7 +42,9 @@
import com.amazonaws.auth.AWSCredentialsProviderChain;
import com.amazonaws.auth.EnvironmentVariableCredentialsProvider;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
+import com.google.auto.service.AutoService;
+@AutoService(Protocol.class)
public class S3Protocol extends AbstractProtocol {
private static final Logger log = LogManager.getLogger(S3Protocol.class);
diff --git a/smb/src/main/java/ch/cyberduck/core/smb/SMBProtocol.java b/smb/src/main/java/ch/cyberduck/core/smb/SMBProtocol.java
index 9c61e9bcc82..289c40f083b 100644
--- a/smb/src/main/java/ch/cyberduck/core/smb/SMBProtocol.java
+++ b/smb/src/main/java/ch/cyberduck/core/smb/SMBProtocol.java
@@ -18,12 +18,16 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.CredentialsConfigurator;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WindowsIntegratedCredentialsConfigurator;
import ch.cyberduck.core.preferences.PreferencesFactory;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SMBProtocol extends AbstractProtocol {
@Override
diff --git a/spectra/src/main/java/ch/cyberduck/core/spectra/SpectraProtocol.java b/spectra/src/main/java/ch/cyberduck/core/spectra/SpectraProtocol.java
index e02be860ea8..df7682cf20c 100644
--- a/spectra/src/main/java/ch/cyberduck/core/spectra/SpectraProtocol.java
+++ b/spectra/src/main/java/ch/cyberduck/core/spectra/SpectraProtocol.java
@@ -18,9 +18,13 @@
import ch.cyberduck.core.DirectoryDelimiterPathContainerService;
import ch.cyberduck.core.LocaleFactory;
import ch.cyberduck.core.PathContainerService;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.s3.S3Protocol;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SpectraProtocol extends AbstractProtocol {
@Override
public String getName() {
diff --git a/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPProtocol.java b/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPProtocol.java
index fc8ae455ff7..b178995151f 100644
--- a/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPProtocol.java
+++ b/ssh/src/main/java/ch/cyberduck/core/sftp/SFTPProtocol.java
@@ -22,6 +22,7 @@
import ch.cyberduck.core.HostnameConfigurator;
import ch.cyberduck.core.JumphostConfigurator;
import ch.cyberduck.core.LocaleFactory;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.sftp.openssh.OpenSSHCredentialsConfigurator;
import ch.cyberduck.core.sftp.openssh.OpenSSHHostnameConfigurator;
@@ -29,6 +30,9 @@
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class SFTPProtocol extends AbstractProtocol {
private final CredentialsConfigurator credentials = new OpenSSHCredentialsConfigurator();
diff --git a/storegate/src/main/java/ch/cyberduck/core/storegate/StoregateProtocol.java b/storegate/src/main/java/ch/cyberduck/core/storegate/StoregateProtocol.java
index 5360cbe99e8..64d67f506bd 100644
--- a/storegate/src/main/java/ch/cyberduck/core/storegate/StoregateProtocol.java
+++ b/storegate/src/main/java/ch/cyberduck/core/storegate/StoregateProtocol.java
@@ -16,8 +16,12 @@
*/
import ch.cyberduck.core.AbstractProtocol;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class StoregateProtocol extends AbstractProtocol {
@Override
public String getIdentifier() {
diff --git a/webdav/src/main/java/ch/cyberduck/core/dav/DAVProtocol.java b/webdav/src/main/java/ch/cyberduck/core/dav/DAVProtocol.java
index e310189fa90..d90f0b08a9c 100644
--- a/webdav/src/main/java/ch/cyberduck/core/dav/DAVProtocol.java
+++ b/webdav/src/main/java/ch/cyberduck/core/dav/DAVProtocol.java
@@ -17,11 +17,15 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.CredentialsConfigurator;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WindowsIntegratedCredentialsConfigurator;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class DAVProtocol extends AbstractProtocol {
@Override
public String getName() {
diff --git a/webdav/src/main/java/ch/cyberduck/core/dav/DAVSSLProtocol.java b/webdav/src/main/java/ch/cyberduck/core/dav/DAVSSLProtocol.java
index d3cd7c8cd9e..01bc0cf6c82 100644
--- a/webdav/src/main/java/ch/cyberduck/core/dav/DAVSSLProtocol.java
+++ b/webdav/src/main/java/ch/cyberduck/core/dav/DAVSSLProtocol.java
@@ -19,11 +19,15 @@
import ch.cyberduck.core.AbstractProtocol;
import ch.cyberduck.core.CredentialsConfigurator;
+import ch.cyberduck.core.Protocol;
import ch.cyberduck.core.Scheme;
import ch.cyberduck.core.WindowsIntegratedCredentialsConfigurator;
import org.apache.commons.lang3.StringUtils;
+import com.google.auto.service.AutoService;
+
+@AutoService(Protocol.class)
public class DAVSSLProtocol extends AbstractProtocol {
@Override
public String getName() {
diff --git a/windows/src/main/csharp/ch/cyberduck/ui/controller/MainController.cs b/windows/src/main/csharp/ch/cyberduck/ui/controller/MainController.cs
index a1a5060ebf2..abeba5993b7 100755
--- a/windows/src/main/csharp/ch/cyberduck/ui/controller/MainController.cs
+++ b/windows/src/main/csharp/ch/cyberduck/ui/controller/MainController.cs
@@ -18,42 +18,17 @@
using ch.cyberduck.core;
using ch.cyberduck.core.aquaticprime;
-using ch.cyberduck.core.azure;
-using ch.cyberduck.core.b2;
using ch.cyberduck.core.bonjour;
-using ch.cyberduck.core.box;
-using ch.cyberduck.core.brick;
using ch.cyberduck.core.ctera;
-using ch.cyberduck.core.dav;
-using ch.cyberduck.core.deepbox;
-using ch.cyberduck.core.dropbox;
-using ch.cyberduck.core.eue;
using ch.cyberduck.core.exception;
-using ch.cyberduck.core.ftp;
-using ch.cyberduck.core.googledrive;
-using ch.cyberduck.core.googlestorage;
-using ch.cyberduck.core.hubic;
using ch.cyberduck.core.importer;
-using ch.cyberduck.core.irods;
using ch.cyberduck.core.local;
-using ch.cyberduck.core.manta;
-using ch.cyberduck.core.nextcloud;
-using ch.cyberduck.core.nio;
using ch.cyberduck.core.notification;
using ch.cyberduck.core.oauth;
-using ch.cyberduck.core.onedrive;
-using ch.cyberduck.core.openstack;
-using ch.cyberduck.core.owncloud;
using ch.cyberduck.core.pool;
using ch.cyberduck.core.preferences;
using ch.cyberduck.core.profiles;
-using ch.cyberduck.core.s3;
-using ch.cyberduck.core.sds;
using ch.cyberduck.core.serializer;
-using ch.cyberduck.core.sftp;
-using ch.cyberduck.core.smb;
-using ch.cyberduck.core.spectra;
-using ch.cyberduck.core.storegate;
using ch.cyberduck.core.threading;
using ch.cyberduck.core.transfer;
using ch.cyberduck.core.updater;
@@ -90,6 +65,7 @@
using static Windows.Win32.PInvoke;
using Application = ch.cyberduck.core.local.Application;
using UnhandledExceptionEventArgs = System.UnhandledExceptionEventArgs;
+using ServiceLoader = java.util.ServiceLoader;
namespace Ch.Cyberduck.Ui.Controller
{
@@ -150,12 +126,10 @@ public MainController(ProtocolFactory protocolFactory, BaseController controller
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
}
- protocolFactory.register(new FTPProtocol(), new FTPTLSProtocol(), new SFTPProtocol(), new DAVProtocol(), new SMBProtocol(),
- new DAVSSLProtocol(), new SwiftProtocol(), new S3Protocol(), new GoogleStorageProtocol(),
- new AzureProtocol(), new IRODSProtocol(), new SpectraProtocol(), new B2Protocol(), new DriveProtocol(),
- new DropboxProtocol(), new HubicProtocol(), new LocalProtocol(), new OneDriveProtocol(), new SharepointProtocol(), new SharepointSiteProtocol(),
- new MantaProtocol(), new SDSProtocol(), new StoregateProtocol(), new BrickProtocol(), new NextcloudProtocol(), new OwncloudProtocol(), new CteraProtocol(), new BoxProtocol(), new EueProtocol(),
- new DeepboxProtocol());
+ foreach (Protocol p in ServiceLoader.load(typeof(Protocol)))
+ {
+ protocolFactory.register(p);
+ }
protocolFactory.load();
SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());