Skip to content

Latest commit

 

History

History
101 lines (66 loc) · 4.3 KB

DEV_README.md

File metadata and controls

101 lines (66 loc) · 4.3 KB

Bndtools Development: Tips and Tricks

Adding Error/Warning Markers

Bndtools aims to be a thin wrapper over bnd. This means that it is comparatively rare that bndtools should be creating errors or warnings. In most cases bnd is responsible for generating errors at build time, it's then bndtools job to display them nicely to the user.

Step 1 - Customise the bnd error

Make sure that bnd is generating an appropriate error or warning using bnd's reporting API. By default all build errors are displayed as markers on the bnd.bnd file. This isn't usually the right file, and even when it is there isn't enough information to pick the correct line. To fix this you need to add information to the Location object associated with the error/warning. Importantly you must add a custom details object to the location. This should be your own object type, and not reused by any other error reporting.

e.g.

SetLocation location = analyzer.error("A clever error message");
location.line(1234)
    .method("doStuff")
    .details(new org.bndtools.example.MyCustomizedLocationObject());

Step 2 - Create a BuildErrorHandler

Once bnd is generating extra error information then bndtools can use it to generate appropriate markers. This is achieved through the use of the org.bndtools.build.api.BuildErrorDetailsHandler (it's normally best to extend org.bndtools.build.api.AbstractBuildErrorDetailsHandler). The method responsible for adding markers is generateMarkerData(), which returns a list of MarkerData objects. Each MarkerData will be used to create a Marker in a file. Normally an error should map to a single marker, although sometimes more than one is appropriate (e.g. if the error can be fixed by changing one of several files).

AbstractBuildErrorDetailsHandler provides convenience methods for adding markers to Java source files. Markers must be created with a message (which is typically the message written by bnd). Markers should also have a line number, or a start/end location. The convenience methods set the start/end location for you, but you have to set the message yourself.

e.g.

MyCustomizedLocationObject errorInfo = (MyCustomizedLocationObject) location.details;

IJavaProject javaProject = JavaCore.create(project);

Map<String,Object> attribs = new HashMap<String,Object>();
attribs.put(IMarker.MESSAGE, location.message.trim());

MarkerData md = null;
if (errorInfo.isTypeLevel) {
  md = createTypeMarkerData(javaProject, errorInfo.className, attribs, false);
} else if (errorInfo.isMethodLevel) {
  md = createMethodMarkerData(javaProject, errorInfo.className, errorInfo.methodName, 
          errorInfo.methodSignature, attribs, false);
}

if (md == null) {
  // No other marker could be created, so add a marker to the bnd file
  result.add(new MarkerData(getDefaultResource(project), attribs, false));
}

result.add(md);

return result;

Step 3 - Hook in to the Eclipse plugin registry

Bndtools uses the Eclipse plugin registry to discover BuildErrorDetailsHandler instances. To hook in to this you need to add the following to your plugin.xml

<extension point="bndtools.core.buildErrorDetailsHandlers">
  <handler typeMatch="org.bndtools.example.MyCustomizedLocationObject" 
      class="org.bndtools.example.handler.MyCustomBuildErrorDetailsHandler" />
</extension>

Step 4 - You're done!

Error markers will now appear in the right places. More work can be done to add quick fixes, but it's much harder than adding the markers.

Build against local Bnd-Lib

Since BndTools relies on Bnd, it is sometimes necessary to use a local version of Bnd.

The Repository for Bnd is configured with bnd_repourl in gradle.properties, located at the workspace-root. This file already contains a commented entry to point to a local distribution.

#bnd_repourl=../bnd/dist/bundles

Assuming Bnd is located next to BndTools, just uncomment this line (otherwise adjust the relative path to your Bnd workspace location). Now you can do a local release of Bnd (see documentation on how to release).

Restart Eclipse or change some file in cnf/ext, which will cause the Eclipse workspace to pick-up the changes.