Development Guide

You’re welcome to create patches with bugfixes or additional features. Fork the sonews repository on Codeberg and submit a pull request.

Some debugging hints: if the server blocks and does not longer respond you probably found a deadlock. Do not kill the process with “kill -9 <pid>” but send a SIGQUIT signal with “kill -3 <pid>” and the Java VM will output a stracktrace of all threads. This output is the most valuable information to fix the deadlock.

Writing extensions

Since sonews/1.1 or higher it is possible to easily extend sonews with new functionality using the plugin API.

Command plugin

To introduce additional NNTP commands, implement the org.sonews.command.Command interface. Here is an example HelloCommand that simply returns “Hello” to the client:

public class HelloCommand implements Command
{

  @Override
  public String[] getSupportedCommandStrings()
  {
    return "HELLO";
  }

  @Override
  public boolean hasFinished()
  {
    return true;
  }

  @Override
  public String impliedCapability()
  {
    return null;
  }

  @Override
  public boolean isStateful()
  {
    return false;
  }

  @Override
  public void processLine(NNTPConnection conn, final String line, byte[] raw)
    throws IOException
  {
    conn.println("100 Hello Client");
  }

}

Compile this example against sonews.jar and tell sonews to load the plugin at startup:

java -cp .:sonews.jar org.sonews.Main -p 9119 -plugin-command mypkg.HelloCommand

Then you can try the new command:

$ telnet localhost 9119
200 sonews/1.1.0 localhost - posting ok
hello
100 Hello Client

The API documentation contains more information about the sonews classes and their usage.

Backend storage plugin

It is possible to use a completely different backend storage for sonews than a relational database. TODO: This feature is not completely available in sonews/2.0

Most important classes reside in package org.sonews.storage. To use a custom storage backend in sonews you must implement a StorageProvider by implementing the org.sonews.storage.StorageProvider interface.

The StorageProvider must return an instance of the specific org.sonews.storage.Storage implementation.