>
1. Getting started
2. Calling methods
3. Working with .NET Objects
4. Fields and Properties
5. Methods Arguments
6. Nested Types
7. Enums
8. Arrays and Collections
9. Embeding UI controls
10. Referencing libraries
11. Off-line activation
12. Events and Delegates
13. Disposing and Garabage Collection
14. .NET Configuration Files (AppConfig, WebConfig)
15. Exceptions, Debugging and Testing
16. Strongly-Typed Wrappers
    17. Advanced Activation and Licensing
    18 Other usage scenarios

      How to debug .NET code called from Java

      Both for .NET and Java, one of the most important features provided by an IDE is the ability to track code
      execution at runtime. Either when looking for bugs in the dynamic portion of code or verifying correctness of
      a complex algorithm – debugging brings unqestionable improvement into development process.
      In case of the Javonet users dealing with the debugging task, its importance doubles as relating to both
      supported domains: .NET and Java. Let’s see how easily this can be achieved and applied against any
      managed assembly.

      Workspace

      For the purpose of this example, I’ll be using the following .NET class representing a simple Person entity,
      having two properties Firstname and Lastname, and being able to return a DisplayName, being a trivial
      concatenation of the former:

      
        using System;
      
        namespace com.javonet.tutorial.debugging
        {
            public class Person
            {
        
                public String Firstname { get; set; }
                public String Lastname { get; set; }
        
                public String DisplayName()
                {
                    return Firstname + " " + Lastname;
                }
        
            }
        }
      
      
      

      The Java code that will interoperate with our Person class is as follows:

      package com.javonet.tutorial.debugging;
      
      import com.javonet.Javonet;
      import com.javonet.JavonetException;
      import com.javonet.JavonetFramework;
      import com.javonet.api.NObject;
      
      import static com.javonet.tutorial.debugging.Constants.EMAIL;
      import static com.javonet.tutorial.debugging.Constants.LICENSE_KEY;
      import static com.javonet.tutorial.debugging.Constants.DLL_FILE_PATH;
      
        public class Main {
          
          public static void main(String[] args) throws JavonetException {
            
            Javonet.activate(EMAIL, LICENSE_KEY, JavonetFramework.v45);
            Javonet.addReference(DLL_FILE_PATH);
            
            NObject person = Javonet.New("Person");
            person.set("Firstname", "Marcin");
            person.set("Lastname", "Pokora-Janda");
            
            String displayName = person.invoke("DisplayName");
            
            System.out.println(displayName);
          }
        }
      
      
      

      Let’s dig a little around what happens in the code:

      Line 16 – activates Javonet framework using provided credentials and JavonetFramework argument,
      successfull execution of this step loads CLR within Java process, allowing our .NET debugger to be
      attached

      Line 17 – instructs Javonet to load classes referenced in the DLL library file under given path into the CLR,
      this makes our Person class accessible

      Line 19-21 – these lines instantiate a new Person class object and set its properties to relevant values

      Line 23 – invokes Person object’s DisplayName method and stores its return value in local String
      variable

      Line 24 – prints resultant DisplayName value from .NET code to standard output of Java process

      Debugging Procedure

      Since debugging happens at runtime, we’ll start by launching our Java code. As already mentioned, it’s
      important to activate Javonet before attempting to place any breakpoint on Java side of our solution, as this
      will start CLR within our process. Let’s put a breakpoint right after the activate method, as presented
      below.

      Now let’s switch to our Visual Studio and attach a debugger to the newly started Java process with CLR. In order to do that, go to Debug > Attach to Process, and select appropriate javaw.exe process. Notice that its Type value should indicate that it’s hosting managed code using .NET version matching the one we’ve specified in Javonet activate method using JavonetFramework argument.

      We’re almost ready to start debugging. Let’s put a breakpoint in the body of Person’s class DisplayName method. Notice that the breakpoint circle symbol is hollow inside, since the debugging symbols have not been loaded into CLR yet

      On Java side, let’s move one step forward by putting a breakpoint on line 19. Calling addReference method loads our DLL library which should result in Person class becoming available for debugging in Visual Studio.

      As you can see, the circle symbol is now completely filled. At this point our breakpoint will get hit once the DisplayName method is invoked on Java side.

      In Eclipse, let’s proceed with code execution until line 23 is reached. Passing this point will result in hitting breakpoint in Visual Studio.

      As you can see, we can now use .NET debugger for all our intended activities, like variables’ inspection, runtime values modification etc.

      Once our work with debugging Person class is done and normal code execution is resumed, it’ll be transferred back to Java, as it is shown with the breakpoint in line 25.

      As the program finishes, we’ll get a returned display name value of our Person object instance.

      Debugging Without .NET Source Project

      Presented debugging method is available also in situations when we do not have access to library source code, provided that the related debugging symbols .pdb file for analysed program or library is available on the Javonet classpath at runtime. We would also need to know full namespace, class name and target method, where to put a breakpoint.

      Rerun Java code from Eclipse, breaking its execution at line 17 to launch a new Java CLR-enabled process.
      In Visual Studio make sure you’ve closed solution for our previous example. As done before, attach debugger to respective managed javaw.exe process.

      Our next step would be to insert new breakpoint. As we do not have the source code available, we’ll need to specify its location manually. In order to do that we can go either to the breakpoint window New > Break at function, go to Debug > New Breakpoint > Break at function or use the Ctrl + B shortcut. Any of these paths will result in opening new window where we’re asked to put the location of our breakpoint by specifying fully qualified method name.

      Once we are happy with our input, Visual Studio might notify us about not being able to find the specified location, which is understandable due to lack of source code. After accepting this notification we should be presented with a breakpoint entry similar to the one in the following picture. The circle will be hollow again, since we’ve not loaded our .NET library via Javonet API yet.

      If we proceed with Java code execution past line 17, the breakpoint symbol will again get filled, similarily to how it behaved in previous example. Also, the breakpoint location now contains fully qualified signature of the targeted method.


      At this point, we are ready to debug our .NET application, therefore let’s proceed with Java code execution. Running line 23 will hit our specified breakpoint, returning control to Visual Studio, where we’ll be presented with a source code generated based on the supplied debugging symbols file.

      Summary

      In this article we’ve learnt how to properly attach Visual Studio debugger to Java proces hosting CLR managed code run by Javonet. The approach has been presented for two scenarios, distinguished by the availability of source code, proving easy access to all of the features offered by Visual Studio debugger that can be used during development of Java application using .NET libraries, drivers or SDKs with Javonet.