SPARK-2399: use Spark.main() directly without the launcher.Startup

This commit is contained in:
Sergey Ponomarev
2026-04-18 23:42:41 +03:00
parent 4d3da704b2
commit e05e8b0d96
12 changed files with 20 additions and 193 deletions

View File

@ -7,7 +7,7 @@ Root is a Maven multi-module project:
- `emoticons` contains the smiles packs (zip artifacts).
- `distribution` has the InstallJ installer/distribution packaging configuration.
Main entry point is `org.jivesoftware.launcher.Startup` defined in `core/pom.xml` manifest.
Main entry point is `org.jivesoftware.Spark` defined in `core/pom.xml` manifest.
### Internationalization
New localized strings should be added to `src/main/resources/i18n/spark_i18n.properties`.

View File

@ -46,7 +46,7 @@
<configuration>
<archive>
<manifest>
<mainClass>org.jivesoftware.launcher.Startup</mainClass>
<mainClass>org.jivesoftware.Spark</mainClass>
</manifest>
</archive>
</configuration>
@ -75,7 +75,7 @@
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<configuration>
<mainClass>org.jivesoftware.launcher.Startup</mainClass>
<mainClass>org.jivesoftware.Spark</mainClass>
</configuration>
</plugin>
<plugin>

View File

@ -8,14 +8,14 @@ if %PROCESSOR_ARCHITECTURE%==x86 (
:run
if "%1" == "-debug" goto debug
if "%1" == "-noconsole" goto noconsole
java -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%; -Djava.library.path="../lib/windows%SPARK64%/" org.jivesoftware.launcher.Startup
java -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%; -Djava.library.path="../lib/windows%SPARK64%/" org.jivesoftware.Spark
goto end
:noconsole
javaw -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%; -Djava.library.path="../lib/windows%SPARK64%/" org.jivesoftware.launcher.Startup
javaw -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%; -Djava.library.path="../lib/windows%SPARK64%/" org.jivesoftware.Spark
goto end
:debug
start "Spark" "%JAVA_HOME%\bin\java" -Ddebugger=true -Ddebug.mode=true -XX:+HeapDumpOnOutOfMemoryError -Xint -server -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%/; org.jivesoftware.launcher.Startup
start "Spark" "%JAVA_HOME%\bin\java" -Ddebugger=true -Ddebug.mode=true -XX:+HeapDumpOnOutOfMemoryError -Xint -server -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -Dappdir=.. -cp ../lib/*;../resources;../lib/windows%SPARK64%/; org.jivesoftware.Spark
goto end
:end

View File

@ -20,7 +20,7 @@ esac;
echo "using classpath: ${classpath}";
mainclass="org.jivesoftware.launcher.Startup";
mainclass="org.jivesoftware.Spark";
if [ "${1}" = "-debug" ]; then
java -Ddebugger=true \

View File

@ -104,8 +104,8 @@
</figure>
<p>
The 'spark-core' module contains a class named <code>Startup</code> (in the <code>org.jivesoftware.launcher</code>
package) that can be used to start Spark. Find the class in the Eclipse Package Explorer, and open its context
The 'spark-core' module contains a class named <code>org.jivesoftware.Spark</code>
that can be used to start Spark. Find the class in the Eclipse Package Explorer, and open its context
menu (right-click on the file). In that menu, use the 'Run as Java Application' option. Eclipse wil start
to build Spark from the source code, after which Spark itself is started. If everything goes well, you will
see the Spark login screen within a matter of seconds!

View File

@ -112,8 +112,8 @@
</figure>
<p>
The 'spark-core' module contains a class named <code>Startup</code> (in the <code>org.jivesoftware.launcher</code>
package) that can be used to start Spark. Find the class in the Project Explorer, and open its context
The 'spark-core' module contains a class named <code>org.jivesoftware.Spark</code>
that can be used to start Spark. Find the class in the Project Explorer, and open its context
menu (right-click on the file). In that menu, use the 'Run Startup.main()' option. IntelliJ wil start
to build Spark from the source code, after which Spark itself is started. If everything goes well, you will
see the Spark login screen within a matter of seconds!

View File

@ -107,8 +107,8 @@
</figure>
<p>
The 'spark-core' module contains a class named <code>Startup</code> (in the <code>org.jivesoftware.launcher</code>
package) that can be used to start Spark. Find the class in the Project Explorer, open that class you will notice two hyperlinks above
The 'spark-core' module contains a class named <code>org.jivesoftware.Spark</code>
that can be used to start Spark. Find the class in the Project Explorer, open that class you will notice two hyperlinks above
the main method, like in the picture above. You can click on <code>Run</code> and the code will be compiled and executed. VS Code will start
to build Spark from the source code, after which Spark itself is started. If everything goes well, you will
see the Spark login screen within a matter of seconds!

View File

@ -16,7 +16,6 @@
package org.jivesoftware;
import org.jivesoftware.launcher.Startup;
import org.jivesoftware.resource.Default;
import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
@ -308,7 +307,7 @@ public final class MainWindow extends ChatFrame implements ActionListener {
private File getLibDirectory() {
File jarFile;
try{
jarFile = new File(Startup.class.getProtectionDomain().getCodeSource().getLocation().toURI());
jarFile = new File(Spark.class.getProtectionDomain().getCodeSource().getLocation().toURI());
} catch(Exception e) {
Log.error("Cannot get jar file containing the startup class", e);
return null;
@ -389,7 +388,7 @@ public final class MainWindow extends ChatFrame implements ActionListener {
String javaBin = System.getProperty("java.home") + File.separatorChar + "bin" + File.separatorChar + "java";
try {
String[] toExec = new String[] {
javaBin, "-cp", getClasspath(), "org.jivesoftware.launcher.Startup"};
javaBin, "-cp", getClasspath(), "org.jivesoftware.Spark"};
Runtime.getRuntime().exec(toExec);
} catch (Exception e) {
Log.error("Error trying to restart application with java", e);

View File

@ -44,6 +44,7 @@ import static org.apache.commons.lang3.SystemUtils.*;
/**
* The Spark Main Application.
* In many cases, you will need to know the structure of the Spark installation, such as the directory structures, what
* type of system Spark is running on, and also the arguments which were passed into Spark on startup. The <code>Spark</code>
* class provides some simple static calls to retrieve this information.
@ -59,14 +60,6 @@ public final class Spark {
private static File USER_DIRECTORY;
private static File XTRA_DIRECTORY;
/**
* Private constructor that invokes the LoginDialog and
* the Spark Main Application.
*/
public Spark() {
}
private static synchronized File initializeDirectory(File directoryHome, String directoryName) {
File targetDir = new File(directoryHome, directoryName).getAbsoluteFile();
if (!targetDir.exists()) {
@ -118,7 +111,8 @@ public final class Spark {
/**
* Configures environment; starts application; invokes login
*/
public void startup() {
public static void main(String[] args) {
setArguments(args);
Properties sysProps = System.getProperties();
initializeFolders(sysProps);
SparkCompatibility.transferConfig(USER_SPARK_HOME);
@ -352,7 +346,7 @@ public final class Spark {
/**
* Loads the language set by the user. If no language is set, then the default implementation will be used.
*/
private void loadLanguage() {
private static void loadLanguage() {
final LocalPreferences preferences = SettingsManager.getLocalPreferences();
final String setLanguage = preferences.getLanguage();
if (ModelUtil.hasLength(setLanguage)) {

View File

@ -1,69 +0,0 @@
/**
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* 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 org.jivesoftware.launcher;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* A simple classloader to extend the classpath to
* include all jars in a lib directory.<p>
* <p/>
* The new classpath includes all <tt>*.jar</tt> and <tt>*.zip</tt>
* archives (zip is commonly used in packaging JDBC drivers). The extended
* classpath is used for both the initial startup, as well as loading
* plug-in support jars.
*
* @author Derek DeMoro
*/
class JiveClassLoader extends URLClassLoader {
/**
* Constructs the classloader.
*
* @param parent the parent class loader (or null for none).
* @param libDir the directory to load jar files from.
* @throws java.net.MalformedURLException if the libDir path is not valid.
*/
JiveClassLoader(ClassLoader parent, File libDir) throws MalformedURLException {
super(new URL[]{libDir.toURI().toURL()}, parent);
File[] jars = libDir.listFiles( ( dir, name ) -> {
boolean accept = false;
String smallName = name.toLowerCase();
if (smallName.endsWith(".jar")) {
accept = true;
}
else if (smallName.endsWith(".zip")) {
accept = true;
}
return accept;
} );
// Do nothing if no jar or zip files were found
if (jars == null) {
return;
}
for (File jar : jars) {
if (jar.isFile()) {
addURL(jar.toURI().toURL());
}
}
}
}

View File

@ -1,97 +0,0 @@
/**
* Copyright (C) 2004-2011 Jive Software. All rights reserved.
*
* 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 org.jivesoftware.launcher;
import java.io.File;
import java.lang.reflect.Method;
/**
*/
public class Startup {
/**
* Default to this location if one has not been specified
*/
private static final String DEFAULT_LIB_DIR = "../lib";
public static void main(String[] args) {
new Startup().start(args);
}
/**
* Starts the server by loading and instantiating the bootstrap
* container. Once the start method is called, the server is
* started and the server starter should not be used again.
*
* @param args the arguments passed into this initial instance of Spark.
*/
private void start(String[] args) {
// Setup the classpath using JiveClassLoader
try {
// Load up the bootstrap container
final ClassLoader parent = findParentClassLoader();
File libDir;
final String workingDirectory = System.getProperty("appdir");
if (workingDirectory == null) {
libDir = new File(DEFAULT_LIB_DIR);
}
else {
libDir = new File(new File(workingDirectory), "lib");
}
File pluginDir = new File(libDir.getParentFile(), "plugins");
// Load them into the classloader
final ClassLoader loader = new JiveClassLoader(parent, libDir);
Thread.currentThread().setContextClassLoader(loader);
// Get class
Class<?> sparkClass = loader.loadClass("org.jivesoftware.Spark");
Object instanceOfSpark = sparkClass.newInstance();
// Handle arguments
if (args.length > 0) {
Method setArgument = sparkClass.getMethod("setArguments", String[].class);
setArgument.invoke(instanceOfSpark, (Object) args);
}
Method startupMethod = sparkClass.getMethod("startup");
startupMethod.invoke(instanceOfSpark);
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Locates the best class loader based on context (see class description).
*
* @return The best parent classloader to use
*/
private ClassLoader findParentClassLoader() {
ClassLoader parent = Thread.currentThread().getContextClassLoader();
if (parent == null) {
parent = this.getClass().getClassLoader();
if (parent == null) {
parent = ClassLoader.getSystemClassLoader();
}
}
return parent;
}
}

View File

@ -38,7 +38,7 @@
<executable name="Spark" iconSet="true" iconFile="images/spark.ico" executableDir="." redirectStderr="false" executableMode="gui" singleInstance="true" serviceDescription="communicator" checkConsoleParameter="true">
<versionInfo include="true" fileDescription="${compiler:sys.shortName}" legalCopyright="${compiler:sys.publisher}" internalName="${compiler:sys.shortName}" />
</executable>
<java mainClass="org.jivesoftware.launcher.Startup" vmParameters="&quot;-Dappdir=${launcher:sys.launcherDirectory}&quot;" preferredVM="client">
<java mainClass="org.jivesoftware.Spark" vmParameters="&quot;-Dappdir=${launcher:sys.launcherDirectory}&quot;" preferredVM="client">
<classPath>
<scanDirectory location="lib" />
<directory location="resources" failOnError="false" />