Vespa Applications

The example project album-recommendation-java contains a configurable Searcher that inspects and modifies the query tree - with tracing enabled. This is a stateless Vespa application with no data, to demonstrate how to build plugins for the Vespa container. Note that the Searcher is only one of several available component types that can be deployed.

Build

Prerequisite: Install and configure Maven - then build album-recommendation-java:

$ mvn clean install
from the project root. Refer to the bundle plugin for build details.

Configure

A key Vespa feature is code and configuration concistency, deployed using an application package. This ensures that code and configuration is in sync, and loaded atomically when deployed. This is done by generating config classes from config definition files. In Vespa and application code, configuration is hence accessed through generated config classes - read more in the Cloud Configuration System.

The Maven target generate-sources (invoked by mvn install) uses src/main/resources/configdefinitions/metal-names.def to generate target/generated-sources/vespa-configgen-plugin/com/mydomain/example/MetalNamesConfig.java.

After generating config classes, they will resolve in tools like IntelliJ IDEA (If running IntelliJ on a Linux, configure the test environment).

Tests

Examples are found in MetalSearcherTest.java. testAddedOrTerm1 and testAddedOrTerm2 illustrates two ways of doing the same test. The first setting up the minimal search chain for YQL programmatically. The second uses com.yahoo.application.Application, which sets up the application package and simplifies testing. Read more in testing.

An example system test is included in FeedAndSearchSystemTest.java. A system test is an integration test that tests the application API endpoints.

Deploy

To deploy the application to a docker instance like in the quick start, build target/application.zip:

$ mvn install package
Then test the commands at basic-search-java.

Troubleshooting

Cannot find *Config classes

Several projects depend on generated configuration classes. These are created by the generate-sources Maven target. The easiest way to avoid the problem is building the project with Maven from the shell, then importing in Eclipse/IntelliJ. If the project is already imported, first run the generate-sources target either from the IDE or the shell, then mark the pertinent target/generated-sources/vespa-configgen-plugin directories as source directories.

Maven

On error:

  at org.codehaus.plexus.archiver.AbstractArchiver$1.hasNext(AbstractArchiver.java:482)
  at org.codehaus.plexus.archiver.AbstractArchiver$1.hasNext(AbstractArchiver.java:482)
  at org.codehaus.plexus.archiver.AbstractArchiver$1.hasNext(AbstractArchiver.java:482)
  at org.codehaus.plexus.archiver.AbstractArchiver$1.hasNext(AbstractArchiver.java:482)
increase the maven thread stack size by export MAVEN_OPTS=-Xss2m

Running on Linux

IntelliJ does not pick up custom test profiles from pom.xml. If running IntelliJ on a Linux, configure its test environment with a reference to the library path (i.e. $VESPA_ROOT/lib64). The simplest way to do this is to edit the default configuration for JUnit.

Ignored provider

This it is usually a packaging problem:

A provider [the class] registered in SERVER runtime does not implement any provider interfaces
applicable in the SERVER runtime.
Due to constraint configuration problems the provider [the class] will be ignored.
The JAX-RS classes, like the @GET annotation, have been bundled inside the plug-in bundle, causing the container not to recognize them as valid annotations. The fix is using mvn dependency:tree to figure out what dependency has caused JAX-RS to be included, and then add the proper exclusion clause to pom.xml.

No result returned when throwing WebApplicationException

The container has no special handling of javax.ws.rs.WebApplicationException and its subclasses. All Jersey plug-ins must either be exception safe, or supply the proper implementations of javax.ws.rs.ext.ExceptionMapper for all exceptions which are expected to be thrown from the plug-in (and annotate these with @Provider).