This howto guide covers the knowledge needed to track down problems whilst developing applications on NetKernel. It covers techniques and tools. It assumes you have a basic knowledge of NetKernel development including creating modules and the specific technologies you are using within your application.

Typically you’ll know you have a problem when either you get standard NetKernel “Internal Server Error” page, or you application doesn’t respond as expected.

Internal Server Error
You’ll see an Internal Server Error when an application throws an exception which is not caught by any intermediate requestor and which propagates all the way back to the transport in which the request was initiated. An Internal Server Error will pinpoint quite precisely the origin of a problem and it is worth spending time to dig down into it. In HTTP applications, the link near the bottom of the exception page will expand a full view of the exception stacktrace.



NetKernel stack traces differ from Java stack traces. A NetKernel stack trace consists of a stack of stacks. Each frame in the outer stack represents a point within the execution context down through all executed sub-requests where an exception was trapped, captured and re-thrown by the kernel or NKF. The NetKernel stack trace therefore shows the complete child-parent exception propagation.

Each frame contains the following information:
   
Id   A unique id which indicates the ID of the exception. This is analogous to the exception Class of the Java world.

Message   A more verbose text description associated with the exception which may contain specific parameterised information.

Request   The NetKernel request or unique data from the request which caused the exception

Callstack   A Java callstack for the point where the exception was thrown or trapped. By default this stack trace is limited to the deepest 4 method calls. For more detailed information, the depth of Java stacktrace can be set in the Control Panel->Configure Global Kernel Parameters

When inspecting a NetKernel stacktrace: Starting at the top frame and working down each frame contains a deeper and deeper request hierarchy until you get the underlying cause of the exception. Because the whole stack is available with all intermediate requests you can see the full call sequence and context around each request.

URI Resolution Failure
URI Resolution Failures are a special class of exception thrown by NetKernel when a request cannot be resolved to an accessor. For this type of exception, the deepest exception frame contains a diagnostic trace of the failed request resolution process. By comparing this trace with your module and its imports you’ll be able to spot whether the  error is caused by a module misconfiguration or a badly constructed request. Here''s an example:

Request: http://localhost:1060/not-found

Searching for jetty://localhost:1060/not-found   (This is the URI being searched for.)
Starting Module urn:org:ten60:netkernel:tpt:http   (This is the module where the search started.)
Matched on Mapping (jetty|servlet-bridge):.* skipping next 18 mappings   (SKIP rules are optimisations)
Matched on Mapping .* SUPER   (SUPER rules defer evaluation to the parent scope)
Entering Parent Module urn:org:ten60:netkernel:fulcrum:backend   (So we continue search in the backend fulcrum)
Rewriting Request to ffcpl:/not-found   (The URI is rewritten)
Checked Unmatched Mapping (many) rewrite   (Other rewrite rules don’t match)
Checked Unmatched Mapping ffcpl:/(etc|pub|fulcrum)/.* THIS   (Several matches to static resources don’t match)
Checked Unmatched Mapping ffcpl:/entrypoints.xml THIS   
Checked Unmatched Mapping ffcpl:/favicon.ico THIS   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:tpt:http   (URI can’t be resolved within any of these imports)
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:cache:standard   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:introspect   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:doc:netkernel   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:doc:books   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:mod:developer   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:lib:xlib   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:entrypoint   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:install   
Checked Unmatched Mapping (many) to import urn:org:ten60:util:image   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:xrl   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:app:xbin   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:debugger   
Checked Unmatched Mapping (many) to import urn:org:ten60:netkernel:ext:xunit   
No Match Found for jetty://localhost:1060/not-found   (Nothing left to check to request fails.)

Problems with regular expression matching are a common cause of resolution failures. See the Regex Cookbook for help on refining and testing regular expressions.

You may sometimes see No Transreptor Found.  This errors indicates that the module context and any imports do not provide a registered Transreptor for converting from the existing resource representation to the one desired in the request.  Since Transreptors are not located by URI this error does not produce a resolution trace.  You can resolve this error by looking at the request hierarchy and finding the accessor that returned the response that cannot be transrepted.  Look at the module containing the accessor and work your way up the call stack module hierarchy to determine where you think the transreptor should have been registered.  In some cases it is simply not valid to expect a transreption to be possible (eg VoidAspect to StringAspect).  In other cases it may be that a the transreption is not one of the common patterns supported by the system. In this case you can either create an accessor or script to transform the returned resource and explicitly call this service as part of your application. Alternatively you can create and register an application specific transreptor.

Unrecognised Fragment Identifier indicates that your URI contains a fragmentation identifier ''#'' but no registered fragmentor can be found that matches the fragment identifier and the mimetype of the resource that is contained in the response.. Fragmentation is not a common processing mode and so these errors are unlikely to occur.  Solving them is similar to tracing problems with transreption.

It’s just not working!
Sometimes your application just isn’t behaving as expected. Where do you start?

Debug Output
Putting debug statements in your code still works! This is an excellent way to quickly check your assumptions about what is executing and its values. In DPML you can use the log accessor
http://docs.1060.org/docs/3.0.0/book/developerreference/doc_ura_log.html. In Java and the scripting languages you can use System.out or the language''s syntactic equivalent. The downside of this approach is that you must change the code and sometimes the problem it isn’t your code.

Request Trace
The Request Trace tool available in the Developer Tools lets you inject a test request into an arbitrary point in your system. This tool allows you to probe the address space of a single module and/or a complete modular application.  The issued request is traced and produces a report identical to that generated for a  URI Resolution Failure even when a request is successfully resolved. This can be useful when you find a request being resolved to an unexpected location because of a bad regular expression or unexpected module import.

One gotcha here is to understand how the HTTP transport infrastructure changes request URIs. You can’t just inject http://localhost:8080/myapp/ into the frontend fulcrum and expect it to be resolved into your application since the combination of the HTTP transport, the fulcrum and the HTTP bridge is designed to work with ''real'' externally generated HTTP requests not artificially constructed trace requests.  In order to trace this specific example, you should instead inject the request ffcpl:/myapp/ .  Optionally you can also specify active URI arguments such as HTTP parameters (+param@....), cookies (+cookie@...) or other fields specified by your HTTP bridge configuration.

NetKernel Debugger
The request trace is limited to probing the address space and you cannot setup a complex scenario where execution is dependent upon the context of a request or pass-by-value arguments. The debugger provides the capability to stop live requests and introspect the suspended execution state. This is very useful in getting an in-depth view of a request that is routing correctly but not producing the resource that was expected.

The debugger allows you to specify breakpoints with regular expressions on the URI’s of requests. Matching requests are stopped and held so that you may view their state. You can view the callstack of the request, resources passed by reference or value and the value and metadata of the response.

The debugger can also be useful if you don’t know the exact internal operation of the system but you want to find out how and why something happens. For example seeing how XSLT is invoked or when a particular resource is accessed.

Two considerations before using the debugger: 1) turn off the deadlock detector in global kernel parameters and 2) ensure you are the only person accessing the system.

Class Trace
If you experience classloading issues such as ClassNotFoundException, NoClassDefFoundError, ClassCastException then it is likely that the your application module is not correctly configured to provide or export low-level Java classes.

The Class Trace tool lets you trace classloading from within the context of any module.  It can be used to check that the expected class path environment created by module imports is that which you expected.  In addition it is a very useful tool to check that the version of a Class that is being loaded in your module is provided from the correct library in the case where more than one version of a Java library is coexisting in the system at the same time.

More details on how classloading works in NetKernel are provided here
http://docs.1060.org/docs/3.0.0/book/extensionsguide/doc_guide_classpath.html

Java Debugging
Since NetKernel is running on a JVM you can still use Java breakpoints and your IDE debugger to stop and examine Java code execution in any part of the system.  It is most common to use Java debugging within custom developed Java Accessors.

Summary
NetKernel is different.  It is a dynamically linked, loosely coupled operating environment.  Since the system is dynamic, debugging often involves dynamic probing techniques. We hope this guide successfully arms you with the knowledge that will help you track down problems faster and more accurately. Remember that community support is always available via the 1060 Forum.