adding a new command to gdb while using cdt eclipse - eclipse-plugin

Good day,
I am writing to you because I tried to follow your instructions [here: http://wiki.eclipse.org/CDT/cdt-debug-dsf-gdb-extensibility ] for adding a new command to gdb while using cdt eclipse.
I does not seem to work at all. I put print statements in all of the methods of all the extended classes. Nothing gets printed, which indicates that none of these methods are called. Following is my code. What am I missing?
(i didn't get to the point of actually implementing the new services factory since i there
plugin.xml:
<plugin>
<extension
point="org.eclipse.debug.core.launchDelegates">
<launchDelegate
delegate="tracerdubug.MyTracerLaunchDelegate"
id="TracerDubug.MyTracerLaunchDelegate"
modes="debug, run">
</launchDelegate>
</extension>
</plugin>
TracerRunControl:
public class TracerRunControl extends GDBRunControl_7_0 {
public TracerRunControl(DsfSession session) {
super(session);
System.out.println("TracerRunControl");
}
}
//################################################################
public class MyTracerLaunchDelegate extends GdbLaunchDelegate implements ILaunchConfigurationDelegate2{
public MyTracerLaunchDelegate() {
super();
System.out.println("MyTracerLaunchDelegate::ctr()");
}
#Override
public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
System.out.println("MyTracerLaunchDelegate::launch()");
super.launch(config, mode, launch, monitor);
}
#Override
protected IDsfDebugServicesFactory newServiceFactory(String version) {
System.out.println("MyTracerLaunchDelegate");
return new TracerDebugServicesFactory(version);
}
}
//################################################################
public class TracerDebugServicesFactory extends GdbDebugServicesFactory {
public TracerDebugServicesFactory(String version) {
super(version);
// TODO Auto-generated constructor stub
}
#Override
protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) {
GDBControl_7_0 g = new GDBControl_7_0(session,config);
System.out.println("TracerDebugServicesFactory::createCommandControl");
return g;
}
#Override
protected IRunControl createRunControlService(DsfSession session) {
System.out.println("TracerDebugServicesFactory::createProcessesService");
return new TracerRunControl(session);
}
#Override
protected IProcesses createProcessesService(DsfSession session) {
System.out.println("TracerDebugServicesFactory::createProcessesService");
return new GDBProcesses_7_0(session);
}
}
Thanks,
Shai

I had the same problem and got the answer from another forum. You must add more info and more extensions:
<extension
point="org.eclipse.debug.core.launchDelegates">
<launchDelegate
delegate="tracerdubug.MyTracerLaunchDelegate"
delegate="Tracerdubug.MyTracerLaunchDelegate"
delegateDescription="Your description"
id="org.eclipse.cdt.dsf.gdb.launch.localCLaunch"
modes="debug"
name="My GDB Launch Delegate"
sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator"
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"
type="org.eclipse.cdt.launch.applicationLaunchType">
</launchDelegate>
</extension>
<extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
<launchConfigurationTypeImage
icon="icons/img.gif"
configTypeID="Tracerdubug.MyTracerLaunchDelegate"
id="Tracerdubug.TabGroups.launcher.Image">
</launchConfigurationTypeImage>
</extension>
<extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
type="Tracerdubug.MyTracerLaunchDelegate"
class="Tracerdubug.TabGroups.TabGroupTest"
id="Tracerdubug.TabGroups.TabGroupTest">
</launchConfigurationTabGroup>
</extension>
and you need a new class = Tracerdubug.TabGroups.TabGroupTest:
package Tracerdubug.TabGroups;
import org.eclipse.cdt.dsf.gdb.internal.ui.launching.CDebuggerTab;
import org.eclipse.cdt.dsf.gdb.internal.ui.launching.CMainAttachTab;
import org.eclipse.cdt.dsf.gdb.internal.ui.launching.AttachCDebuggerTab;
import org.eclipse.cdt.launch.ui.CArgumentsTab;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.EnvironmentTab;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
public class TabGroupTest extends AbstractLaunchConfigurationTabGroup {
// Create an array of tabs to be displayed in the debug dialog
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
ILaunchConfigurationTab[] tabs =
new ILaunchConfigurationTab[] {,
new CMainAttachTab(),
new CArgumentsTab(),
new EnvironmentTab(),
new SourceLookupTab(),
new CommonTab(),
};
setTabs(tabs);
}
}
You can also create your own tabs, see: http://www.eclipse.org/articles/Article-Launch-Framework/launch.html
My command factory is loaded, I'm now learning how to use an existing service to send the command...

Related

Eclipse Plugin: How can I tell the plugin to open a new Editor every time instead of switching the focus to an existing Editor?

In my Plugin there is an action to open an Editor (extends EditorPart). When I try to open it a second time, its init method isn't called. Instead the focus is shifted to the editor that is already open.
The Editor is associated with a filetype. Here is the excerpt from the plugin.xml:
<extension point="org.eclipse.ui.editors">
<editor
class="de.blub.tool.ide.editors.GRASPEditor"
default="true"
extensions="grasp"
filenames="*.grasp"
icon="icons/newGraspFile.png"
id="de.blub.tool.ide.editors.GRASPEditor"
name="GRASP File Editor">
</editor>
</extension>
I have an Action to open a new Editor. When I try to click that Action twice it reuses the first Editor. I also tried to use an EditorMatcher that implements IEditorMatchingStrategy and always returns false in its matches() method. Even that doesn't change the behavior.
This seems to be a desired/default behavior in eclipse. How can I change that so that the user can initialize a new Editor each time?
Eclipse looks for the equals method of the IEditorInput instance. The Editor somewhere in its code (in my case in the doSave method) uses a setInput method like this:
#Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
// Initialize the editor input
this.input = new MyInputClass(resource);
...
}
#Override
public void doSave(IProgressMonitor monitor) {
...
setInput(input);
}
MyInputClass is the class that extends IEditorInput. The logic for eclipse to reuse an Editor or create a new one is in its equals method. The following example checks the path of an IResource field:
public class MyInputClass implements IEditorInput {
private IResource resource;
public MyInputClass(IResource resource) {
this.resource = resource;
}
public IResource getResource() {
return resource;
}
public void setResource(IResource resource) {
this.resource = resource;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof MyEditorClass) {
MyEditorClass other = (MyEditorClass) obj;
if (getResource().getFullPath().equals(other.getResource().getFullPath())) {
return true;
}
}
return false;
}
}
Of course one can define another logic inside the equals method. Make sure to not create a chaos, which is very well possible, as greg-449 pointed out in a comment.

Creating a custom run configuration using IntelliJ SDK and adding Build task in Before launch section

I'm following the tutorial in Run Configuration section of IntelliJ IDEA SDK.
Following the tutorial, I will get a new configuration panel with an empty "Before launch" section. That section is added by default.
I would like to specify some targets by default, i.e. at least the Build target as done in several plugins (see next picture)
I'm trying to understand how, but I cannot find any example nor documentation on this.
How can I add default build task?
Your run configuration (DemoRunConfiguration in the example) should implement RunProfileWithCompileBeforeLaunchOption. This interface doesn't provide any methods to implement, so this is a kind of mark. build task will be added automatically, no additional steps are required.
How can I add my own task to before launch section?
Your plugin.xml should contain a line with stepsBeforeRunProvider
<stepsBeforeRunProvider implementation="com.MyBeforeRunProvider" id="myBeforeRun"/>
For that you should create "before run provider" with "before run task".
public class BeforeRunProvider extends BeforeRunTaskProvider<MyBeforeRunTask> {
#Override
public Key<MyBeforeRunTask> getId() {
return Key.create("ThisIsId");
}
#Override
public String getName() {
return "Nice name";
}
#Override
public String getDescription(MyBeforeRunTask task) {
return "Description";
}
#Nullable
#Override
public Icon getIcon() {
return AllIcons.Actions.Compile;
}
#Nullable
#Override
public MyBeforeRunTask createTask(#NotNull RunConfiguration runConfiguration) {
return new MyBeforeRunTask(getId());
}
#Override
public boolean executeTask(#NotNull DataContext dataContext, #NotNull RunConfiguration runConfiguration, #NotNull ExecutionEnvironment executionEnvironment, #NotNull MyBeforeRunTask myBeforeRunTask) {
return true;
}
}
And the task:
public class MyBeforeRunTask extends BeforeRunTask<MyBeforeRunTask> {
protected MyBeforeRunTask(#NotNull Key<MyBeforeRunTask> providerId) {
super(providerId);
setEnabled(true);
}
}

Intercept Error constructor with bytebuddy

For some reason I can't work out yet, my agent doesn't intercept java LinkageError instances.
Agent code:
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;
public class MyAgent {
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.type(ElementMatchers.isSubTypeOf(LinkageError.class))
.transform((builder, type, classLoader, module) ->
builder.constructor(ElementMatchers.isDefaultConstructor())
.intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(MyInterceptor.class)))
).installOn(instrumentation);
}
}
Interceptor code:
public class MyInterceptor {
#RuntimeType
public static void intercept(#Origin Constructor<?> constructor) throws Exception {
System.out.println("Intercepted: " + constructor.getName());
}
}
Test code:
public static void main(String[] args) {
new NoClassDefFoundError("should be intercepted!!!").toString();
new Foo("oh").toString();
}
What is puzzling is that replacing ElementMatchers.isSubTypeOf(LinkageError.class) with ElementMatchers.nameContains("Foo") gives the expected result and Foo constructor is intercepted.
The NoClassDefFoundError is loaded by the bootstrap loader. It willnot be able to see your interceptor class which is why it is never triggered.
Try using the Advice class (as a visitor) to add bytecode to matched classes which should resolve this problem.

Usage of IAdapterFactory with popupMenus in eclipse rcp

My requirement was to add a new menu entry to “Compare with” present in one of the 3rd party views.
As this was using “org.eclipse.ui.popupMenus” to add a menu entry to the above contribution. Even I was forced to use the same extension point even though its deprecated.
I was able to add a menu entry to the contribution with the below code
<extension point="org.eclipse.ui.popupMenus">
<objectContribution
adaptable="true"
id="test.id"
objectClass="local.change">
<action
class="compare.commparetool"
enablesFor="1"
id="id"
label="Compare "
menubarPath="compareWith/group1">
</action>
<visibility>
<objectState
name="local.change"
value=".txt">
</objectState>
</visibility>
</extension>
The above configuration is working fine.
Next requirement was to add property tester to hide the menu entries whenever a file selected is other than .txt file.
As we cannot add property tester to object contribution, I have used IAdapterfactory. Below code is not working.
Observation:
I have added many menu entries (“org.eclipse.ui.menus”) in different views in “Compare with” which is not related to this.
But if user clicks on any of these commands, and then try the view in question, it is working as expected as expected.
Below is the code. Am I missing anything. Do I need to register the adapters in some other place also??
<extension point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="local.change"
class="LocalChangeAdapterFactory">
<adapter
type="org.eclipse.ui.IActionFilter">
</adapter>
</factory>
</extension>
public class LocalChangeAdapterFactory implements IAdapterFactory
{
#SuppressWarnings("unchecked")
#Override
public Object getAdapter(final Object adaptableObject, final Class adapterType)
{
if (adapterType == IActionFilter.class)
{
return LocalChangeActionFilter.getInstance();
}
return null;
}
#SuppressWarnings("unchecked")
#Override
public Class[] getAdapterList()
{
return new Class[] { LocalChangeActionFilter.class };
}
}
public class LocalChangeActionFilter implements IActionFilter
{
private static LocalChangeActionFilter INSTANCE = new LocalChangeActionFilter();
private LocalChangeActionFilter()
{
}
#Override
public boolean testAttribute(final Object target, final String name, final String value)
{
String fileName = "";
if(target.getId==1){
return true;
}else{
return false;
}
public static LocalChangeActionFilter getInstance()
{
return INSTANCE;
}
}
The adaptableType attribute of the adapter factory should specify the type of the existing object that you want to adapt to an IActionFilter. So this is probably a resource of file:
adaptableType="org.eclipse.core.resources.IResource">
The getAdapter method of the IActionFactory should return a class matching the adapter attribute, not your implementing class:
public Class[] getAdapterList()
{
return new Class[] { IActionFilter.class };
}
Your testAttribute method if the action filter must test the name parameter matches the value in the objectState:
#Override
public boolean testAttribute(final Object target, final String name, final String value)
{
if (name.equals("local.change"))
{
.... do test
return true;
}
return false;
}

JBoss AS 7 application specific properties file

I have several independent Java EE modules (WAR web applications, and JAR EJB modules) which I deploy on JBoss 7.1.1 AS.
I want to:
Centralize configuration of these modules in one *.properties file.
Make this file available in classpath.
Keep the installation/configuration of this file as simple as possible. Ideally would be just to put it in some JBoss folder like: ${JBOSS_HOME}/standalone/configuration.
Make changes to this file available without restarting the application server.
Is this possible?
I already found this link: How to put an external file in the classpath, which explains that preferable way to do this is to make static JBoss module. But, I have to make dependency to this static module in every application module that I deploy, which is a kind of coupling I'm trying to avoid.
Maybe a simple solution is to read the file from a singleton or static class.
private static final String CONFIG_DIR_PROPERTY = "jboss.server.config.dir";
private static final String PROPERTIES_FILE = "application-xxx.properties";
private static final Properties PROPERTIES = new Properties();
static {
String path = System.getProperty(CONFIG_DIR_PROPERTY) + File.separator + PROPERTIES_FILE;
try {
PROPERTIES.load(new FileInputStream(path));
} catch (MalformedURLException e) {
//TODO
} catch (IOException e) {
//TODO
}
}
Here is a full example using just CDI, taken from this site.
This configuration will also work for JBoss AS7.
Create and populate a properties file inside the WildFly configuration folder
$ echo 'docs.dir=/var/documents' >> .standalone/configuration/application.properties
Add a system property to the WildFly configuration file.
$ ./bin/jboss-cli.sh --connect
[standalone#localhost:9990 /] /system-property=application.properties:add(value=${jboss.server.config.dir}/application.properties)
This will add the following to your server configuration file (standalone.xml or domain.xml):
<system-properties>
<property name="application.properties" value="${jboss.server.config.dir}/application.properties"/>
</system-properties>
Create the singleton session bean that loads and stores the application wide properties
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
#Singleton
public class PropertyFileResolver {
private Logger logger = Logger.getLogger(PropertyFileResolver.class);
private String properties = new HashMap<>();
#PostConstruct
private void init() throws IOException {
//matches the property name as defined in the system-properties element in WildFly
String propertyFile = System.getProperty("application.properties");
File file = new File(propertyFile);
Properties properties = new Properties();
try {
properties.load(new FileInputStream(file));
} catch (IOException e) {
logger.error("Unable to load properties file", e);
}
HashMap hashMap = new HashMap<>(properties);
this.properties.putAll(hashMap);
}
public String getProperty(String key) {
return properties.get(key);
}
}
Create the CDI Qualifier. We will use this annotation on the Java variables we wish to inject into.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR })
public #interface ApplicationProperty {
// no default meaning a value is mandatory
#Nonbinding
String name();
}
Create the producer method; this generates the object to be injected
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
public class ApplicationPropertyProducer {
#Inject
private PropertyFileResolver fileResolver;
#Produces
#ApplicationProperty(name = "")
public String getPropertyAsString(InjectionPoint injectionPoint) {
String propertyName = injectionPoint.getAnnotated().getAnnotation(ApplicationProperty.class).name();
String value = fileResolver.getProperty(propertyName);
if (value == null || propertyName.trim().length() == 0) {
throw new IllegalArgumentException("No property found with name " + value);
}
return value;
}
#Produces
#ApplicationProperty(name="")
public Integer getPropertyAsInteger(InjectionPoint injectionPoint) {
String value = getPropertyAsString(injectionPoint);
return value == null ? null : Integer.valueOf(value);
}
}
Lastly inject the property into one of your CDI beans
import javax.ejb.Stateless;
import javax.inject.Inject;
#Stateless
public class MySimpleEJB {
#Inject
#ApplicationProperty(name = "docs.dir")
private String myProperty;
public String getProperty() {
return myProperty;
}
}