Eclipse error: Access restriction: The type ‘xyz’ is not API

Eclipse has some pretty bizarre error messages that really don’t tell you exactly what the error is or how to fix it. This weekend I saw this one for example:

Access restriction: The type 'xyz' is not API (restriction on required library ...)

A quick Google told me what this actually means is that I have a line of code using a JDK API that is not in the currently selected runtime for the current project, but does exist in other available runtimes.

For example, when setting up a project with a Maven pom.xml, if you don’t explicitly specify what JVM version you want for the project, you get Java 5 by default.

There’s a couple of different ways to change the JVM version using Maven, but the approach I prefer is by adding properties (because it’s more concise than configuring the Maven compiler plugin):

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

Alternatively if you’re not using Maven, just change the JRE System Library in the project settings on the Java Build Path/Libraries tab (remove the one that’s currently there and add the version that does have the APIs that you’re using, most likely a later version).

Maven packaging notes

maven-dependency-plugin: Copy dependent jars into a /lib/ dir to be bundled with the package goal (note that you can’t have jars within jars and have them accessible on the classpath, so this just helps package the jars with your distribution):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>

            <configuration>
            <outputDirectory>target/classes/lib</outputDirectory>
            <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>

        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>sources</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <verbose>true</verbose>
        <detail>true</detail>
        <outputDirectory>.</outputDirectory>
    </configuration>
</plugin>

 

 

Deploying a Maven-based web project from Eclipse

Here’s the problem: you start with a Web project in Eclipse, created via one of the Wizards. At some point you convert it to a Maven project, but when you deploy the project from Eclipse, your web content in /src/main/webapp is not deployed, because Eclipse is not aware of the Maven folder structure.

I’ve done this multiple times in the past and usually work out a way to build a ear/war and manually deploy it to my server or via a script instead, because I can’t work out how to get a converted project to deploy in Eclipse 🙂

The magic to get this to work is to add the maven-war-plugin to your Maven pom.xml file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
</plugin>

 

Adding jars to your OpenShift remote Maven repo

If your OpenShift app has dependencies on other Jars that are not publicly available in the usual maven repos (for example, other Jars from your own projects), you can push them to your remote Maven repo used when your app builds remotely.

Commit the jar in the root of your OpenShift project.

Edit .openshift/action_hooks/pre_build and add the following, updating Jar name etc:

mvn install:install-file --debug -Dfile=../../YourProjectName/runtime/repo/YourJarName.jar
  -DgeneratePom=true -DartifactId=YourArtifactName -Dversion=0.0.1-SNAPSHOT
  -DgroupId=your.group.id -Dpackaging=jar

Commit your changes and push to OpenShift – the jar will get installed to your remote repo, and now you can add a Maven dependency against it in your project’s pom.xml.