]> source.dussan.org Git - gitblit.git/commitdiff
For Java 9+ define the classpath instead of using a Launcher.
authorFlorian Zschocke <zschocke@gmx.de>
Thu, 7 Nov 2019 19:00:17 +0000 (20:00 +0100)
committerFlorian Zschocke <florian.zschocke@devolo.de>
Thu, 7 Nov 2019 22:45:07 +0000 (23:45 +0100)
The (moxie and other) Launcher do not work with Java 9 and later anymore.
It used to dynamically extend the classpath, misusing an internal
interface of the `URLClassLoader`. This is no longer possible since Java 9,
which closed that path and does not offer any way to dynamically extend
the classpath during runtime.

So the choice is between providing one large Jar with everything in it,
providing a Jar that has the Jars in `ext` listed explicitly in its
manifest, and specifying the classpath on the command line where
the `ext` directory can be added and all contained jar files will
be put on the classpath.

The motivation for the Launcher class was to be able to simply drop
new jar files into a directory and they will be picked up at the
application start, without having to specify a classpath. We opt
for solution three here. This way jar files can still be dropped
into the ext directory, albeit the directory needs to be added to
the classpath on the command line. Unfortunately using a wildcard
is not possible in the manifest file. We change the calls in the
script files accordingly. This seems like a good compromise,
since no one will run the application manually typing the whole
commandline anyway.

This also does away with the splash screen, by the way. Again,
doesn't seem like a big loss, as I don't think it was ever shown
for the Authority.

Personally, I am not convinced that it is the best way, because
I don't really think that the use case of dropping whatever jar
files into the `ext` directory is a valid one that happened a lot.

This does not yet fix the client programs, which still use a
Launcher. Maybe for them a all-in-one Jar is a better solution.

Fixes #1262
Fixes #1294

14 files changed:
build.xml
src/main/distrib/linux/authority.sh
src/main/distrib/linux/gitblit-stop.sh
src/main/distrib/linux/gitblit.sh
src/main/distrib/win/authority.cmd
src/main/distrib/win/gitblit-stop.cmd
src/main/distrib/win/gitblit.cmd
src/main/distrib/win/installService.cmd
src/main/java/com/gitblit/GitBlitServer.java
src/main/java/com/gitblit/Launcher.java [deleted file]
src/main/java/com/gitblit/MigrateTickets.java
src/main/java/com/gitblit/ReindexTickets.java
src/main/java/com/gitblit/authority/Launcher.java [deleted file]
src/site/setup_go.mkd

index 8787623bc8c2dec444f0d486d2c959c8f50bf749..c8bace507c69acf84da4b4c2c9ba63e2ac4ad215 100644 (file)
--- a/build.xml
+++ b/build.xml
                <!-- Build jar -->\r
                <mx:jar destfile="${go.release.dir}/gitblit.jar" includeresources="true">\r
                        <mainclass name="com.gitblit.GitBlitServer" />\r
-                       <launcher paths="ext" />\r
                </mx:jar>\r
 \r
                <!-- Generate the docs for the GO build -->\r
index ce5c23772c925a47d352825f668e5e4177ec2bd8..740f51a8df2ff64033180cf68c23dbc744d13767 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-java -cp gitblit.jar com.gitblit.authority.Launcher --baseFolder data
+java -cp gitblit.jar:ext/* com.gitblit.authority.GitblitAuthority --baseFolder data
index 2fef2034e5bf8e9fbaca9e3be1e407bb6c8a47a5..2a7746445b04f4c9af17ee5495cb9f9f0bb8738e 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-java -jar gitblit.jar --baseFolder data --stop
+java -cp "gitblit.jar:ext/*" com.gitblit.GitBlitServer --baseFolder data --stop
index 7d631e72981b9723bc2ca6a01a3b64cee1950f89..2a52e24ed3e7606acdad322a7e1d78c91dac1ef1 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-java -jar gitblit.jar --baseFolder data
+java -cp "gitblit.jar:ext/*" com.gitblit.GitBlitServer --baseFolder data
index f9a18640de3692fb234f469d83ae7d0f3542aa42..3a27c8a97aa05dfb07dbad3a80ebbba1f7ad6eb9 100644 (file)
@@ -1 +1 @@
-@java -cp gitblit.jar com.gitblit.authority.Launcher --baseFolder data %*\r
+@java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.authority.GitblitAuthority --baseFolder data %*\r
index 34f0f4beca5503d245aeaba58cbc2f546a1ed208..b6bebd8a38ef79daf1f1d7d5627edd8e23a3bac1 100644 (file)
@@ -1 +1 @@
-@java -jar gitblit.jar --stop --baseFolder data %*\r
+@java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.GitBlitServer --stop --baseFolder data %*\r
index 1a6d7e0905fd1b162fcb620fed83e3adccd47dfd..6cd193dd6c8b57d76a9d651eeea680aa9b930fac 100644 (file)
@@ -1 +1 @@
-@java -jar gitblit.jar --baseFolder data %*\r
+@java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.GitBlitServer --baseFolder data %*\r
index a684ab21e54b6f136cd1a05733dce60552b2455e..ef2ba2d0ee579032d34cfe4c9d6027b47b904d4a 100644 (file)
@@ -23,16 +23,16 @@ SET ARCH=amd64
                 --StdOutput=auto ^\r
                 --StdError=auto ^\r
                 --StartPath="%CD%" ^\r
-                --StartClass=org.moxie.MxLauncher ^\r
+                --StartClass=com.gitblit.GitBlitServer ^\r
                 --StartMethod=main ^\r
                 --StartParams="--storePassword;gitblit;--baseFolder;%CD%\data" ^\r
                 --StartMode=jvm ^\r
                 --StopPath="%CD%" ^\r
-                --StopClass=org.moxie.MxLauncher ^\r
+                --StopClass=com.gitblit.GitBlitServer ^\r
                 --StopMethod=main ^\r
                 --StopParams="--stop;--baseFolder;%CD%\data" ^\r
                 --StopMode=jvm ^\r
-                --Classpath="%CD%\gitblit.jar" ^\r
+                --Classpath="%CD%\gitblit.jar;%CD%\ext\*" ^\r
                 --Jvm=auto ^\r
                 --JvmMx=1024\r
                 
\ No newline at end of file
index e006e2c8fd3646db168498dc2d00998588a3150a..06000f531769501b333619c0afd26804f1df3e65 100644 (file)
@@ -143,7 +143,7 @@ public class GitBlitServer {
                if (parser != null) {
                        parser.printUsage(System.out);
                        System.out
-                                       .println("\nExample:\n  java -server -Xmx1024M -jar gitblit.jar --repositoriesFolder c:\\git --httpPort 80 --httpsPort 443");
+                                       .println("\nExample:\n  java -server -Xmx1024M -cp gitblit.jar:ext/* com.gitblit.GitBlitServer  --repositoriesFolder /srv/git --httpPort 80 --httpsPort 443");
                }
                System.exit(0);
        }
diff --git a/src/main/java/com/gitblit/Launcher.java b/src/main/java/com/gitblit/Launcher.java
deleted file mode 100644 (file)
index 68a9dbf..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2011 gitblit.com.
- *
- * Licensed 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.
- */
-package com.gitblit;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.ProtectionDomain;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Launch helper class that adds all jars found in the local "lib" & "ext"
- * folders and then calls the application main. Using this technique we do not
- * have to specify a classpath and we can dynamically add jars to the
- * distribution.
- *
- * @author James Moger
- *
- */
-public class Launcher {
-
-       public static final boolean DEBUG = false;
-
-       /**
-        * Parameters of the method to add an URL to the System classes.
-        */
-       private static final Class<?>[] PARAMETERS = new Class[] { URL.class };
-
-       public static void main(String[] args) {
-               if (DEBUG) {
-                       System.out.println("jcp=" + System.getProperty("java.class.path"));
-                       ProtectionDomain protectionDomain = Launcher.class.getProtectionDomain();
-                       System.out.println("launcher="
-                                       + protectionDomain.getCodeSource().getLocation().toExternalForm());
-               }
-
-               // Load the JARs in the lib and ext folder
-               String[] folders = new String[] { "lib", "ext" };
-               List<File> jars = new ArrayList<File>();
-               for (String folder : folders) {
-                       if (folder == null) {
-                               continue;
-                       }
-                       File libFolder = new File(folder);
-                       if (!libFolder.exists()) {
-                               continue;
-                       }
-                       List<File> found = findJars(libFolder.getAbsoluteFile());
-                       jars.addAll(found);
-               }
-               // sort the jars by name and then reverse the order so the newer version
-               // of the library gets loaded in the event that this is an upgrade
-               Collections.sort(jars);
-               Collections.reverse(jars);
-
-               if (jars.size() == 0) {
-                       for (String folder : folders) {
-                               File libFolder = new File(folder);
-                               // this is a test of adding a comment
-                               // more really interesting things
-                               System.err.println("Failed to find any JARs in " + libFolder.getPath());
-                       }
-                       System.exit(-1);
-               } else {
-                       for (File jar : jars) {
-                               try {
-                                       jar.canRead();
-                                       addJarFile(jar);
-                               } catch (Throwable t) {
-                                       t.printStackTrace();
-                               }
-                       }
-               }
-
-               // Start Server
-               GitBlitServer.main(args);
-       }
-
-       public static List<File> findJars(File folder) {
-               List<File> jars = new ArrayList<File>();
-               if (folder.exists()) {
-                       File[] libs = folder.listFiles(new FileFilter() {
-                               @Override
-                               public boolean accept(File file) {
-                                       return !file.isDirectory() && file.getName().toLowerCase().endsWith(".jar");
-                               }
-                       });
-                       if (libs != null && libs.length > 0) {
-                               jars.addAll(Arrays.asList(libs));
-                               if (DEBUG) {
-                                       for (File jar : jars) {
-                                               System.out.println("found " + jar);
-                                       }
-                               }
-                       }
-               }
-
-               return jars;
-       }
-
-       /**
-        * Adds a file to the classpath
-        *
-        * @param f
-        *            the file to be added
-        * @throws IOException
-        */
-       public static void addJarFile(File f) throws IOException {
-               if (f.getName().indexOf("-sources") > -1 || f.getName().indexOf("-javadoc") > -1) {
-                       // don't add source or javadoc jars to runtime classpath
-                       return;
-               }
-               URL u = f.toURI().toURL();
-               if (DEBUG) {
-                       System.out.println("load=" + u.toExternalForm());
-               }
-               URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
-               Class<?> sysclass = URLClassLoader.class;
-               try {
-                       Method method = sysclass.getDeclaredMethod("addURL", PARAMETERS);
-                       method.setAccessible(true);
-                       method.invoke(sysloader, new Object[] { u });
-               } catch (Throwable t) {
-                       throw new IOException(MessageFormat.format(
-                                       "Error, could not add {0} to system classloader", f.getPath()), t);
-               }
-       }
-}
index b08228efac1b9ed588f56aa1a146761514f3dcd0..52287c45f66a9c73dfd358821aaf58ea710304c3 100644 (file)
@@ -116,7 +116,7 @@ public class MigrateTickets {
                if (parser != null) {
                        parser.printUsage(System.out);
                        System.out
-                                       .println("\nExample:\n  java -gitblit.jar com.gitblit.MigrateTickets com.gitblit.tickets.RedisTicketService --baseFolder c:\\gitblit-data");
+                                       .println("\nExample:\n  java -cp gitblit.jar;\"%CD%/ext/*\" com.gitblit.MigrateTickets com.gitblit.tickets.RedisTicketService --baseFolder c:\\gitblit-data");
                }
                System.exit(0);
        }
index 858436afb850ffff586c871c3dc5ba6c70516718..12936db0ab30ec6e1eea3d9f4dec3ac72d68b1fa 100644 (file)
@@ -111,7 +111,7 @@ public class ReindexTickets {
                if (parser != null) {
                        parser.printUsage(System.out);
                        System.out
-                                       .println("\nExample:\n  java -gitblit.jar com.gitblit.ReindexTickets --baseFolder c:\\gitblit-data");
+                                       .println("\nExample:\n  java -cp gitblit.jar;\"%CD%/ext/*\" com.gitblit.ReindexTickets --baseFolder c:\\gitblit-data");
                }
                System.exit(0);
        }
diff --git a/src/main/java/com/gitblit/authority/Launcher.java b/src/main/java/com/gitblit/authority/Launcher.java
deleted file mode 100644 (file)
index bffeb68..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*\r
- * Copyright 2012 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.authority;\r
-\r
-import java.awt.Color;\r
-import java.awt.EventQueue;\r
-import java.awt.FontMetrics;\r
-import java.awt.Graphics2D;\r
-import java.awt.SplashScreen;\r
-import java.io.File;\r
-import java.io.FileFilter;\r
-import java.io.IOException;\r
-import java.lang.reflect.Method;\r
-import java.net.URL;\r
-import java.net.URLClassLoader;\r
-import java.text.MessageFormat;\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import com.gitblit.Constants;\r
-import com.gitblit.client.Translation;\r
-\r
-/**\r
- * Downloads dependencies and launches Gitblit Authority.\r
- *\r
- * @author James Moger\r
- *\r
- */\r
-public class Launcher {\r
-\r
-       public static final boolean DEBUG = false;\r
-\r
-       /**\r
-        * Parameters of the method to add an URL to the System classes.\r
-        */\r
-       private static final Class<?>[] PARAMETERS = new Class[] { URL.class };\r
-\r
-\r
-       public static void main(String[] args) {\r
-               final SplashScreen splash = SplashScreen.getSplashScreen();\r
-\r
-               File libFolder = new File("ext");\r
-               List<File> jars = findJars(libFolder.getAbsoluteFile());\r
-\r
-               // sort the jars by name and then reverse the order so the newer version\r
-               // of the library gets loaded in the event that this is an upgrade\r
-               Collections.sort(jars);\r
-               Collections.reverse(jars);\r
-               for (File jar : jars) {\r
-                       try {\r
-                               updateSplash(splash, Translation.get("gb.loading") + " " + jar.getName() + "...");\r
-                               addJarFile(jar);\r
-                       } catch (IOException e) {\r
-\r
-                       }\r
-               }\r
-\r
-               updateSplash(splash, Translation.get("gb.starting") + " Gitblit Authority...");\r
-               GitblitAuthority.main(args);\r
-       }\r
-\r
-       private static void updateSplash(final SplashScreen splash, final String string) {\r
-               if (splash == null) {\r
-                       return;\r
-               }\r
-               try {\r
-                       EventQueue.invokeAndWait(new Runnable() {\r
-                               @Override\r
-                               public void run() {\r
-                                       Graphics2D g = splash.createGraphics();\r
-                                       if (g != null) {\r
-                                               // Splash is 320x120\r
-                                               FontMetrics fm = g.getFontMetrics();\r
-\r
-                                               // paint startup status\r
-                                               g.setColor(Color.darkGray);\r
-                                               int h = fm.getHeight() + fm.getMaxDescent();\r
-                                               int x = 5;\r
-                                               int y = 115;\r
-                                               int w = 320 - 2 * x;\r
-                                               g.fillRect(x, y - h, w, h);\r
-                                               g.setColor(Color.lightGray);\r
-                                               g.drawRect(x, y - h, w, h);\r
-                                               g.setColor(Color.WHITE);\r
-                                               int xw = fm.stringWidth(string);\r
-                                               g.drawString(string, x + ((w - xw) / 2), y - 5);\r
-\r
-                                               // paint version\r
-                                               String ver = "v" + Constants.getVersion();\r
-                                               int vw = g.getFontMetrics().stringWidth(ver);\r
-                                               g.drawString(ver, 320 - vw - 5, 34);\r
-                                               g.dispose();\r
-                                               splash.update();\r
-                                       }\r
-                               }\r
-                       });\r
-               } catch (Throwable t) {\r
-                       t.printStackTrace();\r
-               }\r
-       }\r
-\r
-       public static List<File> findJars(File folder) {\r
-               List<File> jars = new ArrayList<File>();\r
-               if (folder.exists()) {\r
-                       File[] libs = folder.listFiles(new FileFilter() {\r
-                               @Override\r
-                               public boolean accept(File file) {\r
-                                       return !file.isDirectory() && file.getName().toLowerCase().endsWith(".jar");\r
-                               }\r
-                       });\r
-                       if (libs != null && libs.length > 0) {\r
-                               jars.addAll(Arrays.asList(libs));\r
-                               if (DEBUG) {\r
-                                       for (File jar : jars) {\r
-                                               System.out.println("found " + jar);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-\r
-               return jars;\r
-       }\r
-\r
-       /**\r
-        * Adds a file to the classpath\r
-        *\r
-        * @param f\r
-        *            the file to be added\r
-        * @throws IOException\r
-        */\r
-       public static void addJarFile(File f) throws IOException {\r
-               if (f.getName().indexOf("-sources") > -1 || f.getName().indexOf("-javadoc") > -1) {\r
-                       // don't add source or javadoc jars to runtime classpath\r
-                       return;\r
-               }\r
-               URL u = f.toURI().toURL();\r
-               if (DEBUG) {\r
-                       System.out.println("load=" + u.toExternalForm());\r
-               }\r
-               URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();\r
-               Class<?> sysclass = URLClassLoader.class;\r
-               try {\r
-                       Method method = sysclass.getDeclaredMethod("addURL", PARAMETERS);\r
-                       method.setAccessible(true);\r
-                       method.invoke(sysloader, new Object[] { u });\r
-               } catch (Throwable t) {\r
-                       throw new IOException(MessageFormat.format(\r
-                                       "Error, could not add {0} to system classloader", f.getPath()), t);\r
-               }\r
-       }\r
-}\r
index c46e04ba680eb9a2bbc78390ada81fc5c217afe4..20b4ba4833469b07b4a2b66e1a69ef2ee1ea37f7 100644 (file)
@@ -8,14 +8,16 @@ Open `data/gitblit.properties` in your favorite text editor and make sure to rev
     - *server.storePassword* (do not enter *#* characters)\r
     **https** is strongly recommended because passwords are insecurely transmitted form your browser/git client using Basic authentication!\r
     - *git.packedGitLimit* (set larger than the size of your largest repository)\r
-3. Execute `authority.cmd` or `java -cp gitblit.jar com.gitblit.authority.Launcher --baseFolder data` from a command-line\r
-**NOTE:** The Authority is a Swing GUI application.  Use of this tool is not required as Gitblit GO will startup and create SSL certificates itself, BUT use of this tool allows you to control the identification metadata used in the generated self-signed certificates.  Skipping this step will result in certificates with default metadata.\r
+3. Windows: Execute `authority.cmd` or `java -cp "gitblit.jar;%CD%\ext\*" com.gitblit.authority.GitblitAuthority --baseFolder data` from a command-line.  \r
+   Linux/OSX: Execute `authority.sh` or `java -cp "gitblit.jar:ext/*" com.gitblit.authority.GitblitAuthority --baseFolder data` from a command-line.  \r
+   **NOTE:** The Authority is a Swing GUI application.  Use of this tool is not required as Gitblit GO will startup and create SSL certificates itself, BUT use of this tool allows you to control the identification metadata used in the generated self-signed certificates.  Skipping this step will result in certificates with default metadata.\r
     1. fill out the fields in the *new certificate defaults* dialog\r
        2. enter the store password used in *server.storePassword* when prompted.  This generates an SSL certificate for **localhost**.\r
        3. you may want to generate an SSL certificate for the hostname or ip address hostnames you are serving from\r
        **NOTE:** You can only have **one** SSL certificate specified for a port.\r
-       5. exit the authority app\r
-4. Execute `gitblit.cmd` or `java -jar gitblit.jar --baseFolder data` from a command-line\r
+       4. exit the authority app\r
+4. Windows: Execute `gitblit.cmd` or `java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.GitBlitServer --baseFolder data` from a command-line\r
+   Linux/OSX: Execute `gitblit.sh` or `java -cp gitblit.jar;ext/* com.gitblit.GitBlitServer --baseFolder data` from a command-line\r
 5. Open your browser to <http://localhost:8080> or <https://localhost:8443> depending on your chosen configuration.\r
 6. Enter the default administrator credentials: **admin / admin** and click the *Login* button    \r
     **NOTE:** Make sure to change the administrator username and/or password!! \r
@@ -49,7 +51,8 @@ If you want to serve your repositories to another machine over https then you wi
 \r
 **NOTE:** The Gitblit Authority is a GUI tool and will require X11 forwarding on headless UNIX boxes.\r
 \r
-1. `authority.cmd` or `java -jar authority.jar --baseFolder data`\r
+1. Windows: `authority.cmd` or `java -cp "gitblit.jar;%CD%\ext\*" com.gitblit.authority.GitblitAuthority --baseFolder data`  \r
+   Linux/OSX: `authority.sh` or `java -cp "gitblit.jar:ext/*" com.gitblit.authority.GitblitAuthority --baseFolder data`\r
 2. Click the *new ssl certificate* button (red rosette in the toolbar in upper left of window)\r
 3. Enter the hostname or ip address\r
 4. Make sure the checkbox *serve https with this certificate* is checked\r
@@ -88,7 +91,8 @@ Alternatively, Gitblit GO is designed to facilitate use of client certificate au
 \r
 When you generate a new client certificate, a zip file bundle is created which includes a P12 keystore for browsers and a PEM keystore for Git.  Both of these are password-protected.  Additionally, a personalized README file is generated with setup instructions for popular browsers and Git.  The README is generated from `data\certs\instructions.tmpl` and can be modified to suit your needs.\r
 \r
-1. `authority.cmd` or `java -jar authority.jar --baseFolder data`\r
+1. Windows: `authority.cmd` or `java -cp "gitblit.jar;%CD%\ext\*" com.gitblit.authority.GitblitAuthority --baseFolder data`  \r
+   Linux/OSX: `authority.sh` or `java -cp "gitblit.jar:ext/*" com.gitblit.authority.GitblitAuthority --baseFolder data`\r
 2. Select the user for which to generate the certificate\r
 3. Click the *new certificate* button and enter the expiration date of the certificate.  You must also enter a password for the generated keystore.  This password is *not* the same as the user's login password.  This password is used to protect the privatekey and public certificate you will generate for the selected user.  You must also enter a password hint for the user.\r
 4. If your mail server settings are properly configured you will have a *send email* checkbox which you can use to immediately send the generated certificate bundle to the user.\r
@@ -139,13 +143,13 @@ Command-Line parameters override the values in `gitblit.properties` at runtime.
     \r
 **Example**\r
 \r
-    java -jar gitblit.jar --userService c:/myrealm.config --storePassword something --baseFolder c:/data\r
+    java  -cp gitblit.jar;"%CD%\ext\*" com.gitblit.GitBlitServer --userService c:/myrealm.config --storePassword something --baseFolder c:/data\r
 \r
 #### Overriding Gitblit GO's Log4j Configuration\r
 \r
 You can override Gitblit GO's default Log4j configuration with a command-line parameter to the JVM.\r
 \r
-    java -Dlog4j.configuration=file:///home/james/log4j.properties -jar gitblit.jar <optional_gitblit_args>\r
+    java -Dlog4j.configuration=file:///home/james/log4j.properties -cp gitblit.jar:"ext/*" com.gitblit.GitBlitServer <optional_gitblit_args>\r
 \r
 You can not use override the default log4j configuration *AND* specify the `--dailyLogFile` parameter.  For reference, here is [Gitblit's default Log4j configuration](https://github.com/gitblit/gitblit/blob/master/src/log4j.properties).  It includes some file appenders that are disabled by default. \r
 \r