Skip to content

Commit

Permalink
Add a command to export the module database into a file
Browse files Browse the repository at this point in the history
Currently if one has a problematic resolver state it is very hard to
provide a reproducing test case for analysis.

This adds a new command exportFrameworkState that allows to export the
module database (optional with its wiring state) into a file that later
can be loaded for example in a test case to analyze it further.
  • Loading branch information
laeubi committed Feb 5, 2024
1 parent d393f75 commit cb464c9
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.equinox.console.commands.CommandsTracker;
import org.eclipse.equinox.console.commands.DisconnectCommand;
import org.eclipse.equinox.console.commands.EquinoxCommandProvider;
import org.eclipse.equinox.console.commands.ExportStateCommand;
import org.eclipse.equinox.console.commands.HelpCommand;
import org.eclipse.equinox.console.commands.ManCommand;
import org.eclipse.equinox.console.commands.WireCommand;
Expand Down Expand Up @@ -329,6 +330,9 @@ public void start(BundleContext context) throws Exception {
WireCommand wireCommand = new WireCommand(context);
wireCommand.startService();

ExportStateCommand exportResourcesCommand = new ExportStateCommand(context);
exportResourcesCommand.startService();

GOGO.RUNTIME.start(frameworkWiring);
GOGO.SHELL.start(frameworkWiring);
GOGO.COMMAND.start(frameworkWiring);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright (c) 2024 Christoph Läubrich and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.console.commands;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Descriptor;
import org.eclipse.osgi.container.ModuleDatabase;
import org.osgi.framework.BundleContext;

public class ExportStateCommand {

private BundleContext context;

public ExportStateCommand(BundleContext context) {
this.context = context;
}

public void startService() {
Dictionary<String, Object> dict = new Hashtable<>();
dict.put(CommandProcessor.COMMAND_SCOPE, "export");
dict.put(CommandProcessor.COMMAND_FUNCTION, new String[] { "exportFrameworkState" });
context.registerService(ExportStateCommand.class, this, dict);
}

@Descriptor("Exports the current framework state including the wiring information")
public void exportFrameworkState(CommandSession session, String path) throws IOException {
exportFrameworkState(session, path, true);
}

@Descriptor("Exports the current framework state, with or without the wiring information")
public void exportFrameworkState(CommandSession session, String path, boolean persitWirings) throws IOException {
ModuleDatabase database = context.getBundle(0).adapt(ModuleDatabase.class);
PrintStream console = session.getConsole();
if (database != null) {
File file = new File(path);
console.println("Exporting ModuleDatabase to " + file.getAbsolutePath() + "...");
try (DataOutputStream stream = new DataOutputStream(new FileOutputStream(file))) {
database.store(stream, persitWirings);
}
} else {
console.println("Can't determine ModuleDatabase!");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.eclipse.osgi.container.ModuleContainer;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.container.ModuleDatabase;
import org.eclipse.osgi.container.ModuleLoader;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.container.ModuleWire;
Expand Down Expand Up @@ -981,6 +982,9 @@ private <A> A adapt0(Class<A> adapterType) {
if (Module.class.equals(adapterType)) {
return (A) module;
}
if (ModuleDatabase.class.equals(adapterType)) {
return adapterType.cast(equinoxContainer.getStorage().getModuleDatabase());
}
if (ProtectionDomain.class.equals(adapterType)) {
Generation current = (Generation) module.getCurrentRevision().getRevisionInfo();
return (A) current.getDomain();
Expand Down

0 comments on commit cb464c9

Please sign in to comment.