Skip to content

Commit

Permalink
feat(rti): pass JVM options to JAVA based federates (#396)
Browse files Browse the repository at this point in the history
* feat(rti): allow setting JVM args for federates
* fix(rti): add root dir of federate to classpath
* fix(rti): watchdog must be initialized with the current time when started
* clean(rti): work after review
* fix(rti): use correct file separator for remote federate
  • Loading branch information
kschrab authored Aug 7, 2024
1 parent 2a2a5a7 commit 8d8f70d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ public class JavaFederateExecutor implements FederateExecutor {
private final String mainClass;
private final String programArguments;
private final FederateDescriptor handle;
private final List<String> vmArgs;

private ExecutableFederateExecutor delegateExecFederateStarter = null;

public JavaFederateExecutor(FederateDescriptor handle, String mainClass, String programArguments) {
this(handle, mainClass, programArguments, Lists.newArrayList());
}

public JavaFederateExecutor(FederateDescriptor handle, String mainClass, String programArguments, List<String> vmArgs) {
this.mainClass = mainClass;
this.programArguments = programArguments;
this.handle = handle;
this.vmArgs = vmArgs;
}

@Override
Expand All @@ -55,7 +61,7 @@ public Process startLocalFederate(File workingDir) throws FederateStarterExcepti
final String fileSeparator = File.separator;
final String pathSeparator = File.pathSeparator;

final String classPath = createClasspath(workingDir, fileSeparator, pathSeparator);
final String classPath = createClasspath(fileSeparator, pathSeparator);

String currentJrePath = SystemUtils.getJavaHome().getPath();
StringBuilder cmdBuilder = new StringBuilder();
Expand All @@ -71,6 +77,8 @@ public Process startLocalFederate(File workingDir) throws FederateStarterExcepti
args.addAll(Arrays.asList(handle.getJavaFederateParameters().getCustomJavaArgument().split(" ")));
}

args.addAll(vmArgs);

args.add("-cp");
args.add(classPath);
args.add(mainClass);
Expand Down Expand Up @@ -101,11 +109,10 @@ public int startRemoteFederate(CLocalHost host, PrintStream sshStream, InputStre
throw new FederateStarterException("Federate has been already started");
}

final File workingDir = handle.getBinariesDir();
final String sep = File.separator;
final String fileSep = host.operatingSystem == CLocalHost.OperatingSystem.WINDOWS ? ";" : ":";
final String fileSeparator = host.operatingSystem == CLocalHost.OperatingSystem.WINDOWS ? "\\" : "/";
final String pathSeparator = host.operatingSystem == CLocalHost.OperatingSystem.WINDOWS ? ";" : ":";

List<String> args = Lists.newArrayList("-cp", createClasspath(workingDir, sep, fileSep), mainClass);
List<String> args = Lists.newArrayList("-cp", createClasspath(fileSeparator, pathSeparator), mainClass);
args.addAll(Arrays.asList(programArguments.split(" ")));

delegateExecFederateStarter = new ExecutableFederateExecutor(this.handle, "java", args);
Expand All @@ -125,38 +132,16 @@ public void stopRemoteFederate(PrintStream sshStreamOut) throws FederateStarterE
}
}

private String createClasspath(File workingDir, String fileSeparator, String pathSeparator) {
String jarName;
final StringBuilder classPath = new StringBuilder(".");
private String createClasspath(String fileSeparator, String pathSeparator) {
final StringBuilder classPath = new StringBuilder();
classPath.append("."); // access to root directory
classPath.append(pathSeparator).append("./*"); // includes all jars in root directory
classPath.append(pathSeparator).append("lib/*"); // includes all jars in lib directory
for (String classpathEntry : handle.getJavaFederateParameters().getJavaClasspathEntries()) {
classPath.append(pathSeparator);
classPath.append(classpathEntry);
}

// find java jar which should be started
File[] files = workingDir.listFiles();
if (files != null) {
for (File file : files) {
if (file.getName().contains(".jar")) {
jarName = file.getName();
classPath.append(pathSeparator);
classPath.append(jarName);
} else if (file.isDirectory() && file.getName().equals("lib")) { // find libs and add them to the class path
File[] libFiles = file.listFiles();
if (libFiles != null) {
for (File libFile : libFiles) {
if (libFile.getName().contains(".jar")) {
classPath.append(pathSeparator);
classPath.append("lib");
classPath.append(fileSeparator);
classPath.append(libFile.getName());
}
}
}
}
}
}
return classPath.toString();
return classPath.toString().replaceAll("//", fileSeparator);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void updateCurrentTime() {
@SuppressWarnings(value = "DM_EXIT", justification = "That's the purpose of the Watchdog")
@Override
public void run() {
updateCurrentTime();
while (watching) {
try {
Thread.sleep(1000L);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.eclipse.mosaic.rti.api.ComponentProvider;
import org.eclipse.mosaic.rti.api.FederateAmbassador;
import org.eclipse.mosaic.rti.api.FederationManagement;
import org.eclipse.mosaic.rti.api.InteractionManagement;
import org.eclipse.mosaic.rti.api.MosaicVersion;
import org.eclipse.mosaic.rti.api.TimeManagement;
import org.eclipse.mosaic.rti.api.WatchDog;
Expand Down Expand Up @@ -184,12 +183,13 @@ public SimulationResult runSimulation(Path scenarioDirectory, CScenario scenario

initializeSingletons(scenarioConfiguration);

federation = createFederation(simParams);

final List<FederateDescriptor> federates = loadFederates(
scenarioDirectory,
scenarioConfiguration
);

federation = createFederation(simParams, federates);
addFederates(federation, federates);

federation.getTimeManagement().runSimulation();

Expand Down Expand Up @@ -428,11 +428,9 @@ private JavaFederateParameters readJavaFederateParameters(CRuntime.CFederate fed
* Creates a federation based on the given parameters.
*
* @param simulationParams the simulation parameters
* @param federates list of federate descriptors
* @return a fully initialized {@link ComponentProvider} instance ready for simulation
* @throws Exception if something went wrong during initalization of any federate
*/
private ComponentProvider createFederation(final MosaicComponentParameters simulationParams, final List<FederateDescriptor> federates) throws Exception {
private ComponentProvider createFederation(final MosaicComponentParameters simulationParams) {
final ComponentProvider componentProvider = componentProviderFactory.createComponentProvider(simulationParams);

FederationManagement federation = componentProvider.getFederationManagement();
Expand All @@ -449,16 +447,18 @@ private ComponentProvider createFederation(final MosaicComponentParameters simul
log.debug("External watchdog port: " + externalWatchdogPort);
time.startExternalWatchDog(federationId, externalWatchdogPort);
}
return componentProvider;
}

final InteractionManagement inter = componentProvider.getInteractionManagement();

// add federates
/**
* Adds the list of {@link FederateDescriptor}s to the given federation.
*/
private void addFederates(ComponentProvider federation, List<FederateDescriptor> federates) throws Exception {
for (FederateDescriptor descriptor : federates) {
federation.addFederate(descriptor);
inter.subscribeInteractions(descriptor.getId(), descriptor.getInteractions());
time.updateWatchDog();
federation.getFederationManagement().addFederate(descriptor);
federation.getInteractionManagement().subscribeInteractions(descriptor.getId(), descriptor.getInteractions());
federation.getTimeManagement().updateWatchDog();
}
return componentProvider;
}

private void stopFederation(ComponentProvider federation) {
Expand Down

0 comments on commit 8d8f70d

Please sign in to comment.