Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » Attach the Java Debugger(A few questions)
Attach the Java Debugger [message #491413] Wed, 14 October 2009 13:18 Go to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello @ all,
I have some problems attaching the java debugger in eclipse.
First of all some information:
We have our own language which is translated into java after compiling. So what I want is a little plugin which runs that generated java code.

For example I right-click on the file XY.ourlanguage -> Run As -> Our Language Application.

I read the articles about the launching framework and "how to wirte an eclipse debugger". But its not exactly what I need.

What I first need is that after the run as our application click the following things happen (btw java code is generated before):
- load the java/class file which was generated from XY.ourlanguage (perhaps from a different directory)
- check if the java/class file has a main Method
- run this method

What I did is:
- LaunchShortcut + extension point
- LaunchConfigurationType + extension point (not yet finished)

I appreciate if you could help me because I cannot find much tutorials/information about this topic.

Best regards and thanks for every help
Alex
Re: Attach the Java Debugger [message #491587 is a reply to message #491413] Thu, 15 October 2009 07:50 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
You can programatically launch java program using java lauch configuration. You need to set the required parameters for java launch configuration. Here is a sample piece of code which might help.
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
if (manager != null) {
ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationC onstants.ID_JAVA_APPLICATION);
if (type != null) {
ILaunchConfigurationWorkingCopy workingCopy = type.newInstance( null, "name");
workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_CLASSPATH,
"<CLASSPATH>");

workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS,
"<VMARGS>");

workingCopy.setAttribute( IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
"<MAIN_CLASS>");

ILaunch launch2 = workingCopy.launch(mode, monitor);
if (launch2 != null) {
IProcess[] processes = launch2.getProcesses();
// Use the processes if needed
}
}
}

You can also check JavaRuntime class for more details. IJavaLaunchConfigurationConstants has all the constants and information.

--
Ravi.
Re: Attach the Java Debugger [message #491616 is a reply to message #491413] Thu, 15 October 2009 09:28 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello Ravi, first of all great thanks for your answer!!

Okay I tried the code you posted:

try {
ILaunchConfigurationWorkingCopy lWC = configuration.getWorkingCopy();
String projectName = configuration.getAttribute(IJavaLaunchConfigurationConstants .ATTR_PROJECT_NAME,(String) null);

//Hole den Pfad zum Projekt
File lWorkingDir = verifyWorkingDirectory(configuration);
String workingDirName = null;
if (lWorkingDir != null) {
workingDirName = lWorkingDir.getAbsolutePath();
}

//Lege Pfad zu den generierten java und class Dateien fest
String lGenJavaPath = lWorkingDir + System.getProperty("file.separator") + A4LPlugin.GENERATED_JAVA_FOLDER + System.getProperty("file.separator");
String lGenClassPath = lWorkingDir + System.getProperty("file.separator") + A4LPlugin.GENERATED_CLASS_FOLDER + System.getProperty("file.separator");

//Lege Main Class Datei inklusive Pfad fest:
String lMainClass = lGenClassPath + "Hello";

//Liste von classpaths fuer die VM
List lClassPathList = new ArrayList<String>();
lClassPathList.add(lGenClassPath);

ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
if (manager != null) {
ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationC onstants.ID_JAVA_APPLICATION);

if (type != null) {
ILaunchConfigurationWorkingCopy workingCopy = type.newInstance( null, "a4llaunch");

workingCopy.setAttribute(IJavaLaunchConfigurationConstants.A TTR_CLASSPATH, lClassPathList);

workingCopy.setAttribute(IJavaLaunchConfigurationConstants.A TTR_MAIN_TYPE_NAME, lMainClass);

workingCopy.doSave();

List lTest = new ArrayList();
workingCopy.getAttribute(IJavaLaunchConfigurationConstants.A TTR_CLASSPATH, lTest);

ILaunch launch2 = workingCopy.launch(mode, monitor);
if (launch2 != null) {
IProcess[] processes = launch2.getProcesses();
// Use the processes if needed
}
}
}
} catch(Exception lEx) {
lEx.printStackTrace();
}

But the problem is that I always get the following exception:
java.lang.NoClassDefFoundError: D:\...\Debugging\runtime-EclipseApplication(1)\A4LLauncherTe st\bin\Hello
Caused by: java.lang.ClassNotFoundException: D:\...\Debugging\runtime-EclipseApplication(1)\A4LLauncherTe st\bin\Hello
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)

And eclipse says "Could not find main class:
D:\...\Debugging\runtime-EclipseApplication(1)\A4LLauncherTe st\bin\Hello

I think it is a classpath problem isn't it?

Thanks for your help Smile

Best Regards,
Alex

[Updated on: Thu, 15 October 2009 09:56]

Report message to a moderator

Re: Attach the Java Debugger [message #491627 is a reply to message #491616] Thu, 15 October 2009 09:55 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
The class path is a list of mementos not plain strings of absolute path. Memento is a XML which contains the type of class path and actual path. The following code should fix it
//List of mementos
List<String> classPaths = new ArrayList<String>();
IIRuntimeClasspathEntry entry = JavaRuntime .newRuntimeClasspathEntry(classPathEntry.toString());
classPaths.add(entry.getMemento())

Re: Attach the Java Debugger [message #491635 is a reply to message #491413] Thu, 15 October 2009 10:32 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello Ravi,
thanks again for your answer!
Now it works, big thanks for the moment Wink
Best regards, Alex

[Updated on: Thu, 15 October 2009 12:19]

Report message to a moderator

Re: Attach the Java Debugger [message #492361 is a reply to message #491413] Tue, 20 October 2009 08:32 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello,
I have still one problem left but first some information:
We are generating java code out of our own 4GL.
To debug our code we want to use JSR045, Darin Wright told me that eclipse supports it.
Now we have our own language editor with CodeAssist, SyntaxHighlighting, we can toggleBreakpoints e.c. .

To debug our code we create a SMAP file and add it to the generated .class file (SourceDebugExtension)

Via console (jdb) we can now debug our 4GL code.

Via eclipse it doesn't work

Launching the application still works fine, but debugging doesn't work att all. It seems that the breakpoints we toggled are still ignored...

Here a little code how we attach the java-launcher. Perhaps I forgot something or the way I'am doing is quiet wrong:
....
//cretae configuration
ILaunchConfiguration lLaunchConfig = createConfiguration(lSelectedFile);


//Launch config
try {
lLaunchConfig.launch(mode, null);
} catch (CoreException e) {
e.printStackTrace();
}
.....

private ILaunchConfiguration createConfiguration(IFile pFile) {
ILaunchConfiguration config = null;
ILaunchConfigurationWorkingCopy wc = null;
//Get classpath and class file name for our 4Gl file
String lClassPath = Utils.getJavaOutputFolderForProject(pFile.getProject());
String lClassName = pFile.getName().replace(".a4l", "");
try {
//Make the classpath list of mementos
List<String> lClassPathList = new ArrayList<String>();
lClassPathList.add(Utils.createClassPathEntryForPath(lClassP ath).getMemento());

//create working copy to edit
ILaunchConfigurationType configType = getAJConfigurationType();
wc = configType.newInstance(null, pFile.getName());

//set launch attributes
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_ TYPE_NAME, lClassName);
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASS PATH, lClassPathList);
wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAU LT_CLASSPATH, false);
config = wc.doSave();
} catch (CoreException exception) {
exception.printStackTrace();
}
return config;
}

Perhaps I have to implement some SourceLookup interfaces?


I would appreciate any help, because information at this topic is stll rare.

Thanks and best regards
Alex

[Updated on: Tue, 20 October 2009 08:32]

Report message to a moderator

Re: Attach the Java Debugger [message #492428 is a reply to message #492361] Tue, 20 October 2009 12:26 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
I am not expert in debug area, but i would suggest you try and add your project to the source tab of java launch configuration from the UI manually and see it if works. If so, you can do the same by setting the correct property for the source lookup. ATTR_SOURCE_PATH or other appropriate variable in IJavaLaunchConfigurationConstants. I haven't tried this. Just an idea

--
Ravi
Re: Attach the Java Debugger [message #492622 is a reply to message #491413] Wed, 21 October 2009 07:00 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello Ravi, first thanks for your answer again Smile

Okay, the problem were registering the line breakpoint.
If I create the following breakpoint:
IJavaStratumLineBreakpoint lStratumBreakpoint = JDIDebugModel.createStratumBreakpoint(resource, "a4l" , lBreakpointName, null, null, lLineNumber+1, lStartChar, lEndChar, lHitCount, true, null);
The debugger ignores it (Doesn't matter if I replace the two null values to the sourcePath and Class name for example "Hello")
But if I set the LaunchConfig attribute ATTR_DEFAULT_SOURCE_PATH to false the breakpoint is NOT ignored
If I create JavaBreakpoint instead the DefaultSourcePath attribute doesn't matter, the breakpoint is never ignored
JDIDebugModel.createLineBreakpoint(resource,"Hello",lLineNumber+1,-1,-1,0,true,null);

But the problem is that in both cases the source file cannot be found.
I think I have to add the Path of our 4GL file which is translated into Java to the LaunchConfiguration by the Property ATTR_SOURCE_PATH like you said...
But how do I create a Source-Path-Memento of a String?
For a ClassPathEntry I can user JavaRuntime.newStringVariableClasspathEntry(lGenClassPath) but I don't know how to get a SourcePathMemento...?

EDIT:
I think I know what the problem is:
In the clas DirectorySorceContainer the method:
public Object[] findSourceElements(String name) throws CoreException {
ArrayList sources = new ArrayList();
File directory = getDirectory();
File file = new File(directory, name);
if (file.exists() && file.isFile()) {
sources.add(new LocalFileStorage(file));
}

//check sub-folders
if ((isFindDuplicates() && fSubfolders) || (sources.isEmpty() && fSubfolders)) {
ISourceContainer[] containers = getSourceContainers();
for (int i=0; i < containers.length; i++) {
Object[] objects = containers[i].findSourceElements(name);
if (objects == null || objects.length == 0) {
continue;
}
if (isFindDuplicates()) {
for(int j=0; j < objects.length; j++)
sources.add(objects[j]);
} else {
sources.add(objects[0]);
break;
}
}
}

if(sources.isEmpty())
return EMPTY;
return sources.toArray();
}

has the wrong parameters.
name is:
D:\...\Debugging\runtime-EclipseApplication(1)\Test\src\Hell o.a4l
and directory is
D:\...\Debugging\runtime-EclipseApplication(1)\Test\src

So File file = new File(directory, name); returns a file referencing whether a directory nor a file.

Atm I don't know how to solve it...
Big thanks for help!
Best regards, Alex

[Updated on: Wed, 21 October 2009 12:26]

Report message to a moderator

Re: Attach the Java Debugger [message #492714 is a reply to message #491413] Wed, 21 October 2009 13:47 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello again,
I solved the porblem and want to tell you what happened:
In the SMAP file added to the class (SourceDebugExtension) the sourceFilePath was:
D:\...\Test\src\Hello.a4l

Now If I added the directory D:\...\Test\src\ to the sourceLookupPath the problem is that the VM seems to interpret the stratum sourcePath as stratum name.
The DirectorySourceContainer method:
public Object[] findSourceElements(String name) throws CoreException {
ArrayList sources = new ArrayList();
File directory = getDirectory();
File file = new File(directory, name);
if (file.exists() && file.isFile()) {
sources.add(new LocalFileStorage(file));
}

//check sub-folders
if ((isFindDuplicates() && fSubfolders) || (sources.isEmpty() && fSubfolders)) {
ISourceContainer[] containers = getSourceContainers();
for (int i=0; i < containers.length; i++) {
Object[] objects = containers[i].findSourceElements(name);
if (objects == null || objects.length == 0) {
continue;
}
if (isFindDuplicates()) {
for(int j=0; j < objects.length; j++)
sources.add(objects[j]);
} else {
sources.add(objects[0]);
break;
}
}
}

if(sources.isEmpty())
return EMPTY;
return sources.toArray();
}

returned always EMPTY because of:
File directory = getDirectory(); // D:\...\Test\src
File file = new File(directory, name); \\ because of the stratum name the result path was D:\...\Test\src\D:\...\Test\src\Hello.a4l

I got the directory twice!
To solve it I either should delete the path from the SMAP file or make relative paths.
For example SMAP Test\src\Hello.a4l
And LaunchConfigSourcePath D:\...\workspace

Some problems are left:
1 No variables are shown in the Debug-View.
2 Eclipse opens a new file. If e.g. Hello.a4l is opened and I Debug As My Application the SourceLookup does not recognize that Hello.a4l is still opened. In the properties the first opened file-path is the workspace relative path Test\src\Hello.a4l. The second file path is the whole path D:\...\Test\src\Hello.a4l

I do not really know how to solve these problems. Unfortunately there is barely information about debugging with JSR045 in Eclipse.
So I would appreciate any help again Smile

Thanks and best regards
Alex
Re: Attach the Java Debugger [message #492791 is a reply to message #492622] Wed, 21 October 2009 17:39 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
Alexander Mack wrote on Wed, 21 October 2009 03:00


But the problem is that in both cases the source file cannot be found.
I think I have to add the Path of our 4GL file which is translated into Java to the LaunchConfiguration by the Property ATTR_SOURCE_PATH like you said...
But how do I create a Source-Path-Memento of a String?
For a ClassPathEntry I can user
JavaRuntime.newStringVariableClasspathEntry(lGenClass




You can use the same API in JavaRuntime but set it for ATTR_SOURCE_PATH
Re: Attach the Java Debugger [message #492793 is a reply to message #492714] Wed, 21 October 2009 17:44 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
Giving relative is not a good idea i guess. From what you mentioned eclipse opened the file considering that it is external file (non-workspace) file and that is the reason you have two editors opening the same file opened at the same time.

Fixing the source path lookup seems to be the better approach

--
Ravi
Re: Attach the Java Debugger [message #492864 is a reply to message #491413] Thu, 22 October 2009 07:17 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
EDIT:
Problem solved Smile
To show local variables jdb and eclipse need a class file with a local Variable extension. javac -g XY.java will create such a table.
Adding the SMAP file via SDE to the compiled class file and launching it with JSR045 will automatically show the local variables then.

Big thanks for all your help Ravi for the moment Very Happy

Hello Ravi, thanks again Smile
Okay the problem was that the path to the source files has to be relative to the workspace path.
E.g. Test\src is enough. I always thought that the absolute path should be used for the SourcePathMemento...
Now eclipse recognizes that the file is still opened and doesn't open a second one...

One problem is left: variables:
In the debug view the variables are empty. Is it possible to show them?
In our 4GL we have simple types like int, float, e.c and objects. The object "structure" is coded in java, too. Is a mapping possible for both variable types? If so, where should I start?

Great thanks for your help Ravi!
Best regards
Alex

[Updated on: Thu, 22 October 2009 08:46]

Report message to a moderator

Re: Attach the Java Debugger [message #493621 is a reply to message #491413] Tue, 27 October 2009 09:33 Go to previous messageGo to next message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Hello Ravi & others again Smile
One question I still have left at the moment.
If I debug the launchConfiguration evereything works fine. But after finishing debugging only the java launch is terminated, not my own launch (which creates the java launch in the launchDelegate.launch method).
This will cause that after a view debug sessions of the same launchConfig the debug view of the threads and processes is brimming with my launch type.
The fact that "Remove all terminated" does not work for my launches shows me that I have to terminate them programmatially?!
So how do I do that.
Wating for the launch being able to terminate like
while(!myLaunch.canTerminate()) {
..
}
will cause an endless loop.

Thanks for any help,
best regards,
Alex

[Updated on: Tue, 27 October 2009 14:13]

Report message to a moderator

Re: Attach the Java Debugger [message #493707 is a reply to message #493621] Tue, 27 October 2009 16:12 Go to previous messageGo to next message
Ravi  is currently offline Ravi Friend
Messages: 27
Registered: July 2009
Junior Member
Add a listener to DebugPlugin and listen to Terminate events.
Java does send terminate event when the java process is terminated. (Donno, if it also sends when the java process is killed instead of usual termination. You have to test this out).
Re: Attach the Java Debugger [message #493845 is a reply to message #491413] Wed, 28 October 2009 09:37 Go to previous message
Alexander Mack is currently offline Alexander MackFriend
Messages: 100
Registered: July 2009
Senior Member
Ah okay thanks, I did it a little different...
I just added the process of the JavaLaunch to OurLanguageLaunch Objekt.
So if the javaLaunch process terminates, our LaunchProcess terminates, too.

The next step is to add BuildPath options. Is it possible to get the java Build Path dialog and use it for our purposes?
Because the language is translated into java, we exactly need the same dialog with its options.

Further it's curious that myLaunchConfiguration and the javaLaunchConfiguratio which is created by the first differ a little bit. Although I save the changes on the working copies of both, it seems that something doesn't work. E.g. I add a new source path (lRelativeProjectSourcePath):
//create runtime classpath entry
IRuntimeClasspathEntry lSourceLookup = JavaRuntime.newStringVariableClasspathEntry(lRelativeProject SourcePath);

//create list of source path mementos for the JVM
launch.getSourceLocator();

List<String> lSourceList = null;

//Now Add the user entries
if(lA4LConfigWorkingCopy.hasAttribute(IJavaLaunchConfigurati onConstants.ATTR_SOURCE_PATH)) {
lSourceList = lA4LConfigWorkingCopy.getAttribute(IJavaLaunchConfigurationC onstants.ATTR_SOURCE_PATH, (List) null);
} else {
lSourceList = new ArrayList<String>();
}

//Add our standard A4L Source Path
lSourceList.add(lSourceLookup.getMemento());

//add the java standard sources
for(IRuntimeClasspathEntry lCurrentDefaultEntry : lDefaultEntries) {
if(!lSourceList.contains(lCurrentDefaultEntry.getMemento())) {
lSourceList.add(lCurrentDefaultEntry.getMemento());
}
}

//set attributes to JavaLaunchConfiguration
lJavaConfigWorkingCopy.setAttribute(IJavaLaunchConfiguration Constants.ATTR_SOURCE_PATH, lSourceList);
lJavaConfigWorkingCopy.setAttribute(IJavaLaunchConfiguration Constants.ATTR_DEFAULT_SOURCE_PATH, false);
lJavaConfigWorkingCopy.setAttribute(IJavaLaunchConfiguration Constants.ATTR_DEFAULT_CLASSPATH, false);

//set attributes to A4LLaunchConfiguration wrokingCopy
lA4LConfigWorkingCopy.setAttribute(IJavaLaunchConfigurationC onstants.ATTR_SOURCE_PATH, lSourceList);
lA4LConfigWorkingCopy.setAttribute(IJavaLaunchConfigurationC onstants.ATTR_DEFAULT_SOURCE_PATH, false);
lA4LConfigWorkingCopy.setAttribute(IJavaLaunchConfigurationC onstants.ATTR_DEFAULT_CLASSPATH, false);

Now looking at the created JavaLaunchConfiguration SourceLookupTab, the Default folder contains my added lRelativeProjectSourcePath.
But looking at myLaunchConfiguration SourceLookupTab (which is the java one), the Default folder does NOT contain my added lRelativeProjectSourcePath.

Another problem is, that I cannot add a source attachment path to a classpath Entry:

//create runtime classpath entry for standard lib files an sources
String lStandardLibRootFolder = A4LWizard.getDefault().getPreferenceStore().getString(A4LWiz ard.KEY_FOR_STANDARDLIBRARY_LOCATION_PREFERENCE);
String lStandardLibSources = lStandardLibRootFolder + System.getProperty("file.separator") + "src";
String lStandardLibClasses = lStandardLibRootFolder + System.getProperty("file.separator") + "bin";

IRuntimeClasspathEntry lStandardLib = JavaRuntime.newStringVariableClasspathEntry(lStandardLibClas ses);
lStandardLib.setClasspathProperty(IRuntimeClasspathEntry.USE R_CLASSES);
lStandardLib.setSourceAttachmentRootPath(Path.EMPTY);
lStandardLib.setSourceAttachmentPath(new Path(lStandardLibSources));


Looking at
IRuntimeClasspathEntry[] lEntries = JavaRuntime.computeUnresolvedRuntimeClasspath(lA4LConfigWork ingCopy);
shows me that the sourceAttachmentPath and RootPath is null althoug I added it...?!

Best regards and great thank for your help again ravi.
Alex

[Updated on: Wed, 28 October 2009 14:47]

Report message to a moderator

Previous Topic:Writing into other Plug-in Preferences?
Next Topic:Hyperlink in Javadoc
Goto Forum:
  


Current Time: Fri Mar 29 07:53:07 GMT 2024

Powered by FUDForum. Page generated in 0.02982 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top