forked from I2P_Developers/i2p.i2p
Moved some logic to C++, which will extract i2p if it's not already,
and then secondly fire up the router in a second java process when extraction is completed. Gonna use "optional" type in C++ to make global variables a bit less painful to use.
This commit is contained in:
@ -6,3 +6,4 @@ However, this is a thin wrapper launching both Mac OS X trayicon and the I2P rou
|
|||||||
|
|
||||||
More code will be merged in, it's just a f* mess which Meeh needs to clean up and move into repo.
|
More code will be merged in, it's just a f* mess which Meeh needs to clean up and move into repo.
|
||||||
|
|
||||||
|
`./fullBuild.sh` triggers Ant jobs and prepare the base.zip, as well as starting the ninja build.
|
||||||
|
@ -8,41 +8,12 @@ lazy val buildAppBundleTask = taskKey[Unit](s"Build an Mac OS X bundle for I2P $
|
|||||||
lazy val buildDeployZipTask = taskKey[String](s"Build an zipfile with base directory for I2P ${i2pVersion}.")
|
lazy val buildDeployZipTask = taskKey[String](s"Build an zipfile with base directory for I2P ${i2pVersion}.")
|
||||||
lazy val bundleBuildPath = new File("./output")
|
lazy val bundleBuildPath = new File("./output")
|
||||||
|
|
||||||
lazy val staticFiles = List(
|
|
||||||
"blocklist.txt",
|
|
||||||
"clients.config",
|
|
||||||
"continents.txt",
|
|
||||||
"countries.txt",
|
|
||||||
"hosts.txt",
|
|
||||||
"geoip.txt",
|
|
||||||
"router.config",
|
|
||||||
"webapps.config"
|
|
||||||
)
|
|
||||||
|
|
||||||
lazy val resDir = new File("./../installer/resources")
|
lazy val resDir = new File("./../installer/resources")
|
||||||
lazy val i2pBuildDir = new File("./../pkg-temp")
|
lazy val i2pBuildDir = new File("./../pkg-temp")
|
||||||
lazy val warsForCopy = new File(i2pBuildDir, "webapps").list.filter { f => f.endsWith(".war") }
|
lazy val warsForCopy = new File(i2pBuildDir, "webapps").list.filter { f => f.endsWith(".war") }
|
||||||
lazy val jarsForCopy = new File(i2pBuildDir, "lib").list.filter { f => f.endsWith(".jar") }
|
lazy val jarsForCopy = new File(i2pBuildDir, "lib").list.filter { f => f.endsWith(".jar") }
|
||||||
|
|
||||||
// TODO: Meeh: To be removed - logic is moved to obj-cpp
|
|
||||||
def defaultOSXLauncherShellScript(javaOpts: Seq[String] = Seq.empty): Seq[String] = {
|
|
||||||
val javaOptsString = javaOpts.map(_ + " ").mkString
|
|
||||||
Seq(
|
|
||||||
"#!/usr/bin/env sh",
|
|
||||||
s"""
|
|
||||||
|echo "I2P - Mac OS X Launcher starting up"
|
|
||||||
|export I2P=$$HOME/Library/I2P
|
|
||||||
|for jar in `ls $${I2P}/lib/*.jar`; do
|
|
||||||
| if [ ! -z $$CP ]; then
|
|
||||||
| CP=$${CP}:$${jar};
|
|
||||||
| else
|
|
||||||
| CP=$${jar}
|
|
||||||
| fi
|
|
||||||
|done
|
|
||||||
|export CLASSPATH=$$CP
|
|
||||||
|exec java -jar $javaOptsString$$JAVA_OPTS "$$0" "$$@"""".stripMargin,
|
|
||||||
"")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pointing the resources directory to the "installer" directory
|
// Pointing the resources directory to the "installer" directory
|
||||||
resourceDirectory in Compile := baseDirectory.value / ".." / ".." / "installer" / "resources"
|
resourceDirectory in Compile := baseDirectory.value / ".." / ".." / "installer" / "resources"
|
||||||
@ -55,22 +26,10 @@ unmanagedClasspath in Compile ++= Seq(
|
|||||||
baseDirectory.value / ".." / ".." / "pkg-temp" / "lib" / "*.jar"
|
baseDirectory.value / ".." / ".." / "pkg-temp" / "lib" / "*.jar"
|
||||||
)
|
)
|
||||||
|
|
||||||
assemblyOption in assembly := (assemblyOption in assembly).value.copy(
|
assemblyOption in assembly := (assemblyOption in assembly).value.copy(includeScala = false, includeDependency = false)
|
||||||
prependShellScript = Some(defaultOSXLauncherShellScript(
|
|
||||||
Seq(
|
|
||||||
"-Xmx512M",
|
|
||||||
"-Xms128m",
|
|
||||||
"-Dwrapper.logfile=/tmp/router.log",
|
|
||||||
"-Dwrapper.logfile.loglevel=DEBUG",
|
|
||||||
"-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
|
|
||||||
"-Dwrapper.console.loglevel=DEBUG",
|
|
||||||
"-Di2p.dir.base=$I2P",
|
|
||||||
"-Djava.library.path=$I2P"
|
|
||||||
)))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
assemblyJarName in assembly := s"OSXLauncher"
|
assemblyJarName in assembly := s"launcher.jar"
|
||||||
|
|
||||||
assemblyExcludedJars in assembly := {
|
assemblyExcludedJars in assembly := {
|
||||||
val cp = (fullClasspath in assembly).value
|
val cp = (fullClasspath in assembly).value
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
#include <subprocess.hpp>
|
#include <subprocess.hpp>
|
||||||
|
#include <future>
|
||||||
|
|
||||||
using namespace subprocess;
|
using namespace subprocess;
|
||||||
|
using namespace std::experimental;
|
||||||
|
|
||||||
JavaRunner::JavaRunner(std::string javaBin, const fp_proc_t& execFn, const fp_t& cb)
|
JavaRunner::JavaRunner(std::string javaBin, const fp_proc_t& execFn, const fp_t& cb)
|
||||||
: javaBinaryPath(javaBin), executingFn(execFn), exitCallbackFn(cb)
|
: javaBinaryPath(javaBin), executingFn(execFn), exitCallbackFn(cb)
|
||||||
@ -11,7 +13,7 @@ JavaRunner::JavaRunner(std::string javaBin, const fp_proc_t& execFn, const fp_t&
|
|||||||
javaProcess = std::shared_ptr<Popen>(new Popen({javaBin.c_str(), "-version"}, defer_spawn{true}));
|
javaProcess = std::shared_ptr<Popen>(new Popen({javaBin.c_str(), "-version"}, defer_spawn{true}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaRunner::execute()
|
optional<std::future<int> > JavaRunner::execute()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
|
auto executingFn = dispatch_block_create(DISPATCH_BLOCK_INHERIT_QOS_CLASS, ^{
|
||||||
@ -24,7 +26,9 @@ void JavaRunner::execute()
|
|||||||
|
|
||||||
printf("Finished executingFn - Runs callbackFn\n");
|
printf("Finished executingFn - Runs callbackFn\n");
|
||||||
this->exitCallbackFn();
|
this->exitCallbackFn();
|
||||||
|
return std::async(std::launch::async, []{ return 0; });
|
||||||
} catch (std::exception* ex) {
|
} catch (std::exception* ex) {
|
||||||
printf("ERROR: %s\n", ex->what());
|
printf("ERROR: %s\n", ex->what());
|
||||||
|
return nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,14 @@
|
|||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include <subprocess.hpp>
|
#include <subprocess.hpp>
|
||||||
|
#include <optional.hpp>
|
||||||
|
|
||||||
using namespace subprocess;
|
using namespace subprocess;
|
||||||
|
using namespace std::experimental;
|
||||||
|
|
||||||
class JavaRunner;
|
class JavaRunner;
|
||||||
|
|
||||||
@ -23,9 +27,9 @@ typedef std::function<void(void)> fp_t;
|
|||||||
typedef std::function<void(JavaRunner *ptr)> fp_proc_t;
|
typedef std::function<void(JavaRunner *ptr)> fp_proc_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* class JavaRunner
|
* class JavaRunner
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
class JavaRunner
|
class JavaRunner
|
||||||
{
|
{
|
||||||
@ -34,7 +38,31 @@ public:
|
|||||||
JavaRunner(std::string javaBin, const fp_proc_t& executingFn, const fp_t& cb);
|
JavaRunner(std::string javaBin, const fp_proc_t& executingFn, const fp_t& cb);
|
||||||
~JavaRunner() = default;
|
~JavaRunner() = default;
|
||||||
|
|
||||||
void execute();
|
const std::list<std::string> defaultStartupFlags {
|
||||||
|
"-Xmx512M",
|
||||||
|
"-Xms128m",
|
||||||
|
"-Djava.awt.headless=true",
|
||||||
|
"-Dwrapper.logfile=/tmp/router.log",
|
||||||
|
"-Dwrapper.logfile.loglevel=DEBUG",
|
||||||
|
"-Dwrapper.java.pidfile=/tmp/routerjvm.pid",
|
||||||
|
"-Dwrapper.console.loglevel=DEBUG",
|
||||||
|
"-Di2p.dir.base=$BASEPATH",
|
||||||
|
"-Djava.library.path=$BASEPATH",
|
||||||
|
"$JAVA_OPTS",
|
||||||
|
"net.i2p.launchers.SimpleOSXLauncher"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::list<std::string> defaultFlagsForExtractorJob {
|
||||||
|
"-Xmx512M",
|
||||||
|
"-Xms128m",
|
||||||
|
"-Djava.awt.headless=true",
|
||||||
|
"-Di2p.dir.base=$BASEPATH",
|
||||||
|
"-Di2p.dir.zip=$ZIPPATH",
|
||||||
|
"net.i2p.launchers.BaseExtractor",
|
||||||
|
"extract"
|
||||||
|
};
|
||||||
|
|
||||||
|
optional<std::future<int> > execute();
|
||||||
std::shared_ptr<Popen> javaProcess;
|
std::shared_ptr<Popen> javaProcess;
|
||||||
std::string javaBinaryPath;
|
std::string javaBinaryPath;
|
||||||
private:
|
private:
|
||||||
|
@ -22,8 +22,11 @@ rule ar
|
|||||||
rule cleanup
|
rule cleanup
|
||||||
command = rm -fr *.o clauncher I2PLauncher.app
|
command = rm -fr *.o clauncher I2PLauncher.app
|
||||||
|
|
||||||
|
# TODO: There must exists a cleaner way to solve this.
|
||||||
rule bundledir
|
rule bundledir
|
||||||
command = mkdir -p I2PLauncher.app/Contents/{MacOS,Resources,Frameworks} && cp Info.plist I2PLauncher.app/Contents/Info.plist
|
command = mkdir -p I2PLauncher.app/Contents/{MacOS,Resources,Frameworks} $
|
||||||
|
&& cp Info.plist I2PLauncher.app/Contents/Info.plist $
|
||||||
|
&& cp base.zip I2PLauncher.app/Contents/Resources/base.zip
|
||||||
|
|
||||||
rule copytobundledir
|
rule copytobundledir
|
||||||
command = cp clauncher I2PLauncher.app/Contents/MacOS/I2PLauncher
|
command = cp clauncher I2PLauncher.app/Contents/MacOS/I2PLauncher
|
||||||
@ -31,6 +34,9 @@ rule copytobundledir
|
|||||||
rule copyimgtobundle
|
rule copyimgtobundle
|
||||||
command = cp ItoopieTransparent.png I2PLauncher.app/Contents/Resources/ItoopieTransparent.png
|
command = cp ItoopieTransparent.png I2PLauncher.app/Contents/Resources/ItoopieTransparent.png
|
||||||
|
|
||||||
|
rule builddir
|
||||||
|
command = mkdir -p build
|
||||||
|
|
||||||
build main.o: cxx main.mm
|
build main.o: cxx main.mm
|
||||||
build StatusItemButton.o: cxx StatusItemButton.mm
|
build StatusItemButton.o: cxx StatusItemButton.mm
|
||||||
build JavaRunner.o: cxx JavaRunner.cpp
|
build JavaRunner.o: cxx JavaRunner.cpp
|
||||||
@ -43,4 +49,5 @@ build copytobundle: copytobundledir | bundle clauncher
|
|||||||
build clauncher: link main.o StatusItemButton.o JavaRunner.o
|
build clauncher: link main.o StatusItemButton.o JavaRunner.o
|
||||||
|
|
||||||
build appbundle: copyimgtobundle | clauncher bundle copytobundle
|
build appbundle: copyimgtobundle | clauncher bundle copytobundle
|
||||||
#build all: clauncher
|
|
||||||
|
default appbundle
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
package net.i2p.launchers;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As the name suggest, it extracts the base path.
|
||||||
|
*
|
||||||
|
* @author Meeh
|
||||||
|
* @since 0.9.35
|
||||||
|
*/
|
||||||
|
public class BaseExtractor extends EnvCheck {
|
||||||
|
|
||||||
|
private void runExtract(String zipFilename, String destinationPath) {
|
||||||
|
try(ZipFile file = new ZipFile(zipFilename)) {
|
||||||
|
FileSystem fileSystem = FileSystems.getDefault();
|
||||||
|
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||||
|
Files.createDirectory(fileSystem.getPath(destinationPath));
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry entry = entries.nextElement();
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
System.out.println("Creating Directory:" + destinationPath + entry.getName());
|
||||||
|
Files.createDirectories(fileSystem.getPath(destinationPath + entry.getName()));
|
||||||
|
} else {
|
||||||
|
InputStream is = file.getInputStream(entry);
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(is);
|
||||||
|
String uncompressedFileName = destinationPath + entry.getName();
|
||||||
|
Path uncompressedFilePath = fileSystem.getPath(uncompressedFileName);
|
||||||
|
Files.createFile(uncompressedFilePath);
|
||||||
|
FileOutputStream fileOutput = new FileOutputStream(uncompressedFileName);
|
||||||
|
while (bis.available() > 0) fileOutput.write(bis.read());
|
||||||
|
fileOutput.close();
|
||||||
|
System.out.println("Written :" + entry.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseExtractor(String[] args) {
|
||||||
|
super(args);
|
||||||
|
|
||||||
|
if (args.length == 2) {
|
||||||
|
if ("extract".equals(args[0])) {
|
||||||
|
// Start extract
|
||||||
|
|
||||||
|
}this.runExtract(System.getProperty("i2p.base.zip"),this.baseDirPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new BaseExtractor(args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package net.i2p.launchers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Both the extractor class and the launcher class needs to be able to verify
|
||||||
|
* the environment (variables) to work. This is a base class implementing it.
|
||||||
|
*
|
||||||
|
* @author Meeh
|
||||||
|
* @since 0.9.35
|
||||||
|
*/
|
||||||
|
public class EnvCheck {
|
||||||
|
|
||||||
|
protected String baseDirPath = null;
|
||||||
|
|
||||||
|
protected boolean isBaseDirectorySet() {
|
||||||
|
baseDirPath = System.getProperty("i2p.base.dir");
|
||||||
|
if (baseDirPath == null) {
|
||||||
|
baseDirPath = System.getenv("I2PBASE");
|
||||||
|
}
|
||||||
|
return (baseDirPath != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnvCheck(String[] args) {
|
||||||
|
if (!isBaseDirectorySet()) {
|
||||||
|
throw new RuntimeException("Can't detect I2P's base directory!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.i2p.launchers;
|
||||||
|
|
||||||
|
import net.i2p.router.Router;
|
||||||
|
|
||||||
|
public class SimpleOSXLauncher extends EnvCheck {
|
||||||
|
|
||||||
|
protected Router i2pRouter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This is bairly a abstraction layer for the Router.
|
||||||
|
* Why? I suspect we will add some spesific osx launcher code at startup
|
||||||
|
* in the jvm somewhere, and this seem like a nice place to not make a mess everywhere.
|
||||||
|
*
|
||||||
|
* @author Meeh
|
||||||
|
* @since 0.9.35
|
||||||
|
*/
|
||||||
|
public SimpleOSXLauncher(String[] args) {
|
||||||
|
super(args);
|
||||||
|
i2pRouter = new Router();
|
||||||
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new SimpleOSXLauncher(args);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user