Skip to content

Commit

Permalink
fix syntax highlight
Browse files Browse the repository at this point in the history
Based on a script I have written I added syntax highlighting, the script is not perfect and I have to manually inspect each one.
  • Loading branch information
velissarious committed Jun 18, 2021
1 parent 040dff7 commit 026056b
Show file tree
Hide file tree
Showing 94 changed files with 5,080 additions and 4,431 deletions.
26 changes: 15 additions & 11 deletions _pages/contribute/project-ideas.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ Quite a few algorithms are available as proof-of-concept [MATLAB](/scripting/mat

MATLAB bundles a Java runtime (and in fact, all of [MATLAB](/scripting/matlab)'s GUI is implemented in Java!) and allows the user to instantiate Java classes and call methods on them:

import java.io.File;
f = File('/usr/local/Fiji.app/');
f.exists()
```java
import java.io.File;
f = File('/usr/local/Fiji.app/');
f.exists()
```

Happily, there is a [MATLAB](/scripting/matlab) clone written in Java: [JMathLib](https://directory.fsf.org/wiki/JMathLib). While it is apparently not a speed demon, it should be useful to add JMathLib as a new scripting language to ImageJ, and integrate it into Fiji so that [MATLAB](/scripting/matlab) scripts can be executed just like all other ImageJ scripts, too.

Expand Down Expand Up @@ -202,14 +204,16 @@ It would be nice to have the opposite direction working, to call R from Fiji. As

To overcome the typical problem of loading native libraries via System.loadLibrary() needing special platform-dependent settings, we should do something like this:

// prohibit JRI to call System.exit(1);
System.setProperty("jri.ignore.ule", "yes");
if (!Rengine.jriLoaded) {
// not found on the library path
System.load("/absolute/path/to/the/library");
Rengine.jriLoaded = true;
}
Rengine re = new Rengine();
```java
// prohibit JRI to call System.exit(1);
System.setProperty("jri.ignore.ule", "yes");
if (!Rengine.jriLoaded) {
// not found on the library path
System.load("/absolute/path/to/the/library");
Rengine.jriLoaded = true;
}
Rengine re = new Rengine();
```

## Teach the Fiji Updater to accept other sites in addition to [fiji.sc](/contribute/funding)

Expand Down
23 changes: 12 additions & 11 deletions _pages/develop/cpp-tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ title: Tips for C++ developers
section: Extend:Development:Guides
---




# Introduction

Many developers are more familiar with C++ than Java when starting to develop code for Fiji. There are a few common pitfalls when coding in Java, being used to C++, and this page tries to help you avoid them.
Expand All @@ -22,7 +19,9 @@ In Java, the compiler only produces bytecode that will be interpreted and/or Jus

Java's generics are implemented using erasure, which means that generics help catching bugs due to compile-time checks, but the compiled classes will actually have forgotten about the generic parameters. In particular, you cannot use the generic parameter to instantiate classes, i.e. this does not work:

`public<T> T create() { return new T(); } // does _not_ work`
```c
public<T> T create() { return new T(); } // does _not_ work
```
The upside of this limitation is that you will never get as cryptic multi-page long error messages as with C++.
Expand All @@ -37,9 +36,9 @@ const char *string = "Hello, World!";
some_func(string + 7);
```

This is not possible in Java. Instead, you have to use String's *substring()* method.
This is not possible in Java. Instead, you have to use String's `substring()` method.

In the same spirit, it is not possible to *realloc()* memory. If you need a larger buffer, you have to allocate it, possibly copying existing data into it using the method *System.arraycopy()*.
In the same spirit, it is not possible to `realloc()` memory. If you need a larger buffer, you have to allocate it, possibly copying existing data into it using the method `System.arraycopy()`.

## There is no need for `this->`

Expand All @@ -59,7 +58,9 @@ There is no operator overloading in Java, so the operator *==* refers to equalit

When declaring a variable like this:

`ImagePlus image;`
```java
ImagePlus image;
```

Java does not initialize the variable automatically. Remember, objects are passed by reference, so *image* is just an uninitialized reference to an *ImagePlus* at this stage.

Expand Down Expand Up @@ -107,18 +108,18 @@ for (String string : array)

## Not taking advantage of Java's standard libraries

Coming from C++, developers often tend to implement everything themselves, even if the algorithm was already implemented. For example, *java.util.Collections* and *java.util.Arrays* contain methods to sort, shuffle, filter or binary search collections and arrays respectively.
Coming from C++, developers often tend to implement everything themselves, even if the algorithm was already implemented. For example, `java.util.Collections` and `java.util.Arrays` contain methods to sort, shuffle, filter or binary search collections and arrays respectively.

Likewise, Java comes with useful classes implementing neat things such as priority queues (since Java 1.5).

## 'final' does not mean 'const'

In C++, when an array is declared <i>const</i>, none of its entries can be edited in any way. But in java, when a variable that points to an array is declared <i>final</i> only that variable cannot be assigned. Any entries of the array (or collection, or whatever container) are editable, and the entry slots themselves may be reassigned.
In C++, when an array is declared `const`, none of its entries can be edited in any way. But in java, when a variable that points to an array is declared `final` only that variable cannot be assigned. Any entries of the array (or collection, or whatever container) are editable, and the entry slots themselves may be reassigned.

# Conventions

## Class and function names

In C++, the common style is to use underscores for both class and function names, e.g. *gaussian\_blur* (except if you are developing on Windows, where the class names are frequently prefixed by a capital *C* and CamelCased).
In C++, the common style is to use underscores for both class and function names, e.g. `gaussian_blur` (except if you are developing on Windows, where the class names are frequently prefixed by a capital *C* and CamelCased).

In Java, the convention is to use CamelCase instead of underscores, and to start class names with a capital letter, but fields and method names lowercase, e.g. *ImagePlus* and *newImage()*.
In Java, the convention is to use CamelCase instead of underscores, and to start class names with a capital letter, but fields and method names lowercase, e.g. `ImagePlus` and `newImage()`.
132 changes: 84 additions & 48 deletions _pages/develop/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ To debug problems with ImageJ, it is often helpful to launch it in debug mode. S

# Debugging plugins in an IDE (Netbeans, IntelliJ, Eclipse, etc)

To debug a plugin in an IDE, you most likely need to provide a *main()* method. To make things easier, we provide helper methods in *fiji-lib* in the class *fiji.Debug* to run plugins, and to load images and run filter plugins:
To debug a plugin in an IDE, you most likely need to provide a `main()` method. To make things easier, we provide helper methods in `fiji-lib` in the class `fiji.Debug` to run plugins, and to load images and run filter plugins:

```java
import fiji.Debug;
Expand All @@ -32,45 +32,55 @@ If your plugin is not a filter plugin, i.e. if it does not require an image to r

## Attaching to ImageJ instances

Sometimes, we need to debug things directly in ImageJ, for example because there might be issues with the plugin discovery (ImageJ wants to find the plugins in *<ImageJ>/plugins/*, and often we want to bundle them as *.jar* files, both of which are incompatible with Eclipse debugging). JDWP (*Java Debug Wire Protocol*) to the rescue!
Sometimes, we need to debug things directly in ImageJ, for example because there might be issues with the plugin discovery (ImageJ wants to find the plugins in `<ImageJ>/plugins/`, and often we want to bundle them as *.jar* files, both of which are incompatible with Eclipse debugging). JDWP (*Java Debug Wire Protocol*) to the rescue!

After starting the Java Virtual Machine in a special mode, debuggers (such as Eclipse's built-in one) can attach to it. To start ImageJ in said mode, you need to pass the *--debugger=<port>* option:
After starting the Java Virtual Machine in a special mode, debuggers (such as Eclipse's built-in one) can attach to it. To start ImageJ in said mode, you need to pass the `--debugger=<port>` option:

ImageJ.app/ImageJ-linux64 --debugger=8000
```shell
ImageJ.app/ImageJ-linux64 --debugger=8000
```

In Eclipse (or whatever {% include wikipedia title='JDWP' text='JDWP'%}-enabled debugger) select the correct project so that the source code can be found, mark the break-points where you want execution to halt (e.g. to inspect variables' values), and after clicking on *Run&gt;Debug Configurations...* right-click on the *Remote Java Application* item in the left-hand side list and select *New*. Now you only need to make sure that the port matches the value that you specified (in the example above, *8000*, Eclipse's default port number).

If you require more control over the ImageJ side -- such as picking a semi-random port if port 8000 is already in use -- you can also use the *-agentlib:jdwp=...* Java option directly (*--debugger=<port>* is just a shortcut for convenience):
If you require more control over the ImageJ side -- such as picking a semi-random port if port 8000 is already in use -- you can also use the `-agentlib:jdwp=...` Java option directly (*--debugger=<port>* is just a shortcut for convenience):

ImageJ.app/ImageJ-linux64 -agentlib:jdwp=server=y,suspend=y,transport=dt_socket,address=localhost:8000 --
```
ImageJ.app/ImageJ-linux64 -agentlib:jdwp=server=y,suspend=y,transport=dt_socket,address=localhost:8000 --
```
(the *--* marker separates the Java options -- if any -- from the ImageJ options). Once started that way, ImageJ will wait for the debugger to be attached, after printing a message such as:

> Listening for transport dt\_socket at address: 46317
**Note**: calling *imagej -agentlib:jdwp=help --* will print nice usage information with documentation of other JDWP options.
**Note**: calling `imagej -agentlib:jdwp=help --` will print nice usage information with documentation of other JDWP options.

## Attach ImageJ to a waiting Eclipse

Instead of making ImageJ [the debugging server](#attaching-to-imagej-instances), when debugging startup events and headless operations it is easier to make ImageJ the client and Eclipse (or equivalent) the server.

In this case you start the debugging session first, e.g. in Eclipse debug configurations you specify "Standard (Socket Listen)" as the connection type. Then, simply start ImageJ without the "server=y" flag to connect and debug:

ImageJ.app/ImageJ-linux64 -agentlib:jdwp=suspend=y,transport=dt_socket,address=localhost:8000 --
```shell
ImageJ.app/ImageJ-linux64 -agentlib:jdwp=suspend=y,transport=dt_socket,address=localhost:8000 --
```

# Monitoring system calls

## Linux

On Linux, you should call ImageJ using the [strace command](http://www.linuxmanpages.com/man1/strace.1.php):

strace -Ffo syscall.log ./imagej <args>
```shell
strace -Ffo syscall.log ./imagej <args>
```

## macOS

Use the *dtruss* wrapper around [dtrace](http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/dtrace.1.html) to monitor system calls:

dtruss ./imagej <args>
```shell
dtruss ./imagej <args>
```

## Windows

Expand All @@ -82,13 +92,17 @@ To monitor all kinds of aspects of processes on Windows, use [Sysinternal's Proc

Set the *LD\_DEBUG* environment variable before launching ImageJ:

LD_DEBUG=1 ./imagej <args>
```shell
LD_DEBUG=1 ./imagej <args>
```

## macOS

Set the *DYLD\_PRINT\_APIS* environment variable before launching ImageJ:

DYLD_PRINT_APIS=1 ./imagej <args>
```shell
DYLD_PRINT_APIS=1 ./imagej <args>
```

## Windows

Expand All @@ -102,8 +116,9 @@ When the Java VM hangs, the reason might be a dead-lock. Try taking a [stack tra
jps

from the command line to print a list of running Java processes. If you're not sure which PID is ImageJ's, you can close ImageJ, run `jps`, open ImageJ and run `jps` again. Whichever PID is present in the second run but not the first is ImageJ's. Then, to acquire a stack trace, just run:

jstack <ImageJ's PID>
```shell
jstack <ImageJ's PID>
```
2. For GUI-based debugging, can also attach to the ImageJ PID using the `jvisualvm` program that you can find in `java/`<platform>`/`<jdk>`/bin/`. Here you can simply press a big *Thread Dump* button to view the stack trace.
macOS users, please note that Apple decided that the VisualVM tool should no longer be shipped with the Java Development Kit; you will have to download it [from here](http://visualvm.java.net/download.html).
Expand All @@ -125,7 +140,9 @@ Typically when you debug a program that crashes, you start it in a debugger, to

But there is a very easy method to use gdb to inspect serious errors such as segmentation faults or trap signals nevertheless:

./imagej -XX:OnError="gdb - %p" --
```shell
./imagej -XX:OnError="gdb - %p" --
```

## Using lldb

Expand All @@ -135,21 +152,23 @@ On newer macOS versions, gdb has been replaced with lldb. For those familiar wit

The Java virtual machine (JVM) frequently leaves files of the format *hs\_err\_pid<number>.log* in the current working directory after a crash. Such a file starts with a preamble similar to this:

#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f3dc887dd8b, pid=12116, tid=139899447723792
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode linux-amd64 )
# Problematic frame:
# C [libc.so.6+0x86d8b] memcpy+0x15b
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
```shell
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f3dc887dd8b, pid=12116, tid=139899447723792
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) 64-Bit Server VM (16.3-b01 mixed mode linux-amd64 )
# Problematic frame:
# C [libc.so.6+0x86d8b] memcpy+0x15b
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
```

followed by thread dumps and other useful information including the command-line arguments passed to the JVM.

Expand All @@ -159,17 +178,23 @@ The most important part is the line after the line *\# Problematic frame:* becau

If the specific exception you're receiving (or you suspect) is an OutOfMemoryError, there are JVM flags that can be enabled when running ImageJ to help pinpoint the problem:
./imagej -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/desired/path/
```shell
./imagej -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/desired/path/
```
The first option:
-XX:+HeapDumpOnOutOfMemoryError
```shell
-XX:+HeapDumpOnOutOfMemoryError
```
tells the JVM to create a heap dump (.hprof file) if an OutOfMemoryError is thrown. This is basically a snapshot of the JVM state when memory ran out.
The second option:
-XX:HeapDumpPath=/desired/path/
```shell
-XX:HeapDumpPath=/desired/path/
```
is not required, but convenient for controlling where the resulting .hprof file is written. Note that these heap dumps are named by PID, and thus are not easily human distinguishable.
Expand All @@ -184,19 +209,18 @@ This requires two separate processes, ImageJ itself and the debugger. You can do
Shell 1
In the first shell, start ImageJ with special parameters to open a port (8000 in this case) to which jdb can connect afterwards:
<!-- -->

./imagej -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y --

```shell
./imagej -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y --
```
(Tested with Java 1.5.0, ymmv)
Shell 2
In the second shell, tell jdb to attach to that port:
<!-- -->

jdb -attach 8000
```shell
jdb -attach 8000
```
## This is an ultra quick start to jdb, the default Java debugger
Expand Down Expand Up @@ -318,13 +342,17 @@ On Linux, the output will be written to the file *.xsession-errors* in the home
On macOS, you need to remember that any application is just a directory with a special layout. So you can call ImageJ like this from the *Terminal* (which you will find in the Finder by clicking on *Go&gt;Utilities*. Example command line:
cd /Applications/ImageJ.app/Contents/MacOS/
cp ImageJ-macosx debug
./debug
```shell
cd /Applications/ImageJ.app/Contents/MacOS/
cp ImageJ-macosx debug
./debug
```
## Show Java3D debug messages
./imagej -Dj3d.debug=true --
```shell
./imagej -Dj3d.debug=true --
```
(Of course, you need to substitute the *./imagej* executable name with the appropriate name for your platform.)
Expand All @@ -340,7 +368,9 @@ Further, some setups require enough RAM to be reserved, so you might need to pas

You can control quite a few things in Java 3D through setting Java properties. Remember, you can set properties using a command line like this:

./imagej -D<property-name>=<property-value> --
```shell
./imagej -D<property-name>=<property-value> --
```

where you substitute *<property-name>* and *<property-values>* appropriately. You can have more than one such option, but make sure that they are appearing before the *--* on the command line, otherwise ImageJ will mistake them for ImageJ options.

Expand Down Expand Up @@ -855,17 +885,23 @@ For users running Linux and MacOSX computers (or on Windows, [Cygwin](http://www
The user should execute this command:
ssh -R 2222:127.0.0.1:22 -t $ACCOUNT@$SSHSERVER screen
```shell
ssh -R 2222:127.0.0.1:22 -t $ACCOUNT@$SSHSERVER screen
```
Once connected, the command
ssh -p 2222 $LOCALACCOUNT@127.0.0.1
```shell
ssh -p 2222 $LOCALACCOUNT@127.0.0.1
```
will open a connection back to the local machine.
The developer should then execute this command:
ssh -t $ACCOUNT@$SSHSERVER 'screen -x'
```shell
ssh -t $ACCOUNT@$SSHSERVER 'screen -x'
```
Since this provides a shared [GNU screen](http://savannah.gnu.org/projects/screen/) session, both the user and the developer can execute commands and see the output. It is even quite common to use the terminal window as sort of a private chat room by typing out what you have to say, ending the line with a {% include key keys='Ctrl|C' %} (lest it get executed as a command).
Expand Down
Loading

0 comments on commit 026056b

Please sign in to comment.