You're viewing **Apigee Edge** documentation.  
[Go to the
**Apigee X** documentation](http://cloud.google.com/apigee/docs/api-platform/develop/how-create-java-callout). info

## What is a Java callout?

Apigee Edge provides a range of policies that address common API management requirements such
as security, data transformation, traffic management, and others.

However, there are some cases where your API requires custom behavior that is not implemented
in a standard policy. In these cases, Apigee provides several options that enable you to script
or code customized API behavior. One approach is to implement the desired behavior in Java.

For the supported versions of Java, see [Supported
software and supported versions](https://docs.apigee.com/release/supported-software).

> [!NOTE]
> **Note:** **Important:** If you are developing Java Callout policies, you need to know which permission policies are in effect in the Edge JVM and how they will affect your code. See [Java
> permission reference](https://docs.apigee.com/api-platform/reference/java-permission-reference). .

## How do I use Java code in a proxy?

A Java callout policy lets you call Java code from within an executing proxy flow. Your Java
code needs to implement certain Edge-specific Java interfaces that allow the code to interact
with the executing proxy. For example, Java methods exist for getting and setting headers, query
parameters, flow variables, and other entities within the current flow context of the proxy.

## When should I use a Java callout?

Let's look at situations where Java callouts are useful, and situations where you should
consider other approaches.

### First, consider
alternative approaches

Before using a Java callout, note that there may be alternative approaches that you can use
instead. For example:

- For lightweight operations, such as HTTP API calls to remote services, consider using the ServiceCallout policy. See [Service Callout policy](https://docs.apigee.com/api-platform/reference/policies/service-callout-policy).
- For relatively simple interactions with message content, such as modifying or extracting HTTP headers, parameters, or message content, you can use JavaScript or Python languages.

### What you can do in Java code

A Java callout supports these basic operations:

- Examining or manipulating request or response messages
- Getting and setting flow variables. You can use Java methods to access Edge flow variables. If you want to access Key Value Map (KVM) information, use a KVM policy, assign KVM values to flow variables, and then you can access the flow variables from within the Java callout.
- Calling external services
- Raising faults
- Manipulating error messages and status codes

### What you cannot do in Java
code

Most system calls are disallowed. You **cannot**:

- Make internal file system reads or writes. This means that you cannot use any of the Java packages to read/write into internal file systems; however, you can make external remote calls.
- Get information about the current process, the process list, or CPU/memory utilization on the machine.
- Access the source code in \`expressions-1.0.0.jar\` and \`message-flow-1.0.0.jar\`.

Although some such calls may work, they are unsupported and liable to be actively disabled at
any time. Avoid making such calls in your code.

Do not use or rely on Java libraries that are included with Apigee Edge. Those libraries are
for Edge product functionality only, and there's no guarantee that a library will be available
from release to release. If you use such libraries, use them in non-production demonstrations
only.

## Hello Java callout

Let's walk through a basic hello world Java callout example. In this example, we create a
simple proxy with a Java callout that returns a "hello world" response. The proxy can return one
of two possible responses:

- If you pass in a "username" header with a "name" value, the proxy returns:  

  ```java
  Hello, <name>!
  ```
- If you omit the header, the proxy just returns:  

  ```java
  "Hello, Guest!"
  ```

### Download the starter project

To make things simple, we have a basic project prepared for you on GitHub in the Apigee
[api-platform-samples](https://github.com/apigee/api-platform-samples) repository.

1. Download or clone [api-platform-samples](https://github.com/apigee/api-platform-samples) to your system.
2. In a terminal or code editor of your choice, go to the `api-platform-samples/doc-samples/java-hello` project.

### Write the Java code

1. Open the Java source file: `java-hello/callout/src/main/java/HelloJava.java`. This file is a skeleton version of the main Java class that we will implement. The imported packages are required for Edge Java Callout code. These classes provide methods that allow you to access the proxy execution context. We'll walk through the steps for compiling and deploying this code shortly.  

   ```java
   package com.apigeesample;

   import com.apigee.flow.execution.ExecutionContext;
   import com.apigee.flow.execution.ExecutionResult;
   import com.apigee.flow.execution.spi.Execution;
   import com.apigee.flow.message.MessageContext;


   public class HelloJava implements Execution {

           public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) {
                   
                   try {

                           // Your code here.
               
               return ExecutionResult.SUCCESS;

                   } catch (Exception e) {
                           return ExecutionResult.ABORT;
                   }
           }

   }
   ```
2. Replace the commented line `// Your code here` with the following code:  

   ```java
   String name = messageContext.getMessage().getHeader("username");

   if (name != null && name.length()>0) {
           messageContext.getMessage().setContent("Hello, " + name + "!");
           messageContext.getMessage().removeHeader("username");
   } else {
           messageContext.getMessage().setContent("Hello, Guest!");
   }
   ```

   > [!NOTE]
   > **Note:** **Note:** The **MessageContext** object lets you access entities inside the flow where the Java Callout policy executes. Let's say the Java Callout policy is attached to the Proxy Endpoint Response flow. The code listed above gets the HTTP Message object for that flow context. The **Message** object, in turn, gives you access to headers, query parameters, body content, and flow variables.

3. Save the file.

### Compile your code with Maven

> [!NOTE]
> **Note:** The POM file and configuration for the Maven compile should work, but are offered in the Git repository as an example only. You may need to make adjustments for your environment. If you make changes to the sample code, you may also need to adjust the Maven configuration.

The project is set up so that you can compile with Maven. If you want to use
`javac`, we'll include an example following the Maven example.

1. Be sure that you have Maven installed:  

   ```java
   mvn -version
   ```
2. Execute the script `java-hello/buildsetup.sh`. This script installs the required JAR dependencies in your local Maven repo.
3. cd to the `java-hello/callout` directory.
4. Execute Maven:  

   ```java
   mvn clean package
   ```

   > [!NOTE]
   > **Note:** If you get a Maven error, be sure that you are in the `java-hello/callout` directory.

5. If you wish, verify that the JAR file `edge-custom-policy-java-hello.jar` was copied to `java-hello/apiproxy/resources/java`. This is the required location for JAR files that you wish to deploy with a proxy.

### Compile with javac (optional)

In the previous section, you generate the required Java JAR file automatically with a
Maven command. Alternatively, if you want to use `javac` to compile the code, you can do
something similar to the following (from the `java-hello` directory). The required
JAR files are provided for you in the `java-hello/lib` directory.

1. cd to `api-platform-samples/doc-samples/java-hello`.
2. Be sure you have javac in your path.  

   ```java
   javac -version
   ```
3. Execute the following javac command:  

   ```java
   javac -d . -classpath ./lib/expressions-1.0.0.jar:./lib/message-flow-1.0.0.jar:. callout/src/main/java/HelloJava.java
   ```
   This creates `com/apigeesample/HelloJava.class`.
4. Create a JAR file containing the compiled class in the `apiproxy/resources/java` directory. This is the required location for JAR files that you wish to deploy with a proxy. You can do this by running the following command in the `java-hello` directory (don't forget the period at the end).  

   ```
   jar cvf apiproxy/resources/java/edge-custom-policy-java-hello.jar -C com .
   ```

### Deploy and call the proxy

A deploy script is provided in the `./java-hello` directory. But before you run it,
you need to do a quick setup.

1. cd to `api-platform-samples/doc-samples/java-hello`
2. If you haven't already done so, open the file `../../setup/setenv.sh` and edit it as indicated with your Apigee account information: your username (the email address associated with your account), your organization name, and the domain you use to make API management calls. For example, for Edge cloud, the domain is `https://api.enterprise.apigee.com`; however, your domain may be different if you're using Edge Private Cloud.
3. Save the `setenv.sh` file.
4. Execute the deploy script:  

   ```java
   ./deploy.sh
   ```
5. If the deploy succeeds, execute the invoke script:  

   ```java
   ./invoke.sh
   ```

   The invoke script calls a cURL command that looks like this:

   ```java
   curl  http://$org-$env.$api_domain/java-hello -H "username:Will"
   ```

   Which returns "Hello, Will!

   You can edit the `invoke.sh` script to change the name, or if you change the
   cURL call to remove the header, then the command returns "Hello, Guest!"

### About the proxy

Let's quickly examine the policies used in this proxy. Pay attention to where the policies are
positioned in the proxy flow and why.

**The Assign message policy**

An Assign message policy is attached to the ProxyEndpoint **request flow**. It
copies the username header from the request and assigns it to the response. This operation allows
the Java Callout policy, which is attached to the response flow, to access the username header
and build a custom response body using the value of that header.

```java
<AssignMessage async="false" continueOnError="false" enabled="true" name="CopyHeader">     
    <DisplayName>CopyHeader</DisplayName>     
    <Copy source="request">         
        <Headers>             
          <Header name="username"/>         
        </Headers>     
    </Copy>     
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>     
    <AssignTo createNew="false" transport="http" type="response"/> 
</AssignMessage>
```

**The Java callout policy**

The Java callout policy is attached to the **response flow** . This is because the
custom Java code makes changes to the response headers and message. The policy's ClassName
element specifies the main class that is executed by the policy. The ResourceURL element is the
name of the JAR file that you built and added to the `resources/java` directory of the
proxy.

```java
<JavaCallout name="hello-java">         
    <ClassName>com.apigeesample.HelloJava</ClassName>         
    <ResourceURL>java://edge-custom-policy-java-hello.jar</ResourceURL> 
</JavaCallout>
```

## What you need to know about Java callout

Important things to note about implementing a Java callout are:

- Imports classes from the `com.apigee.flow.execution` and `com.apigee.flow.message` packages. These packages must be included in the JAR file that is packaged and deployed. You can upload your Java JAR through the Management UI proxy editor, or you can include it in the `/resources/java` directory in API proxies that you develop locally.
- Implements the Execution interface. Any Java code that is executed within an API proxy must implement Execution.
- A Java Callout policy contains no actual code. Instead, a Java Callout policy references a Java 'resource', which you must package in a JAR.
- Package names to avoid: Do not use **io.apigee** or **com.apigee** as package names in Java Callouts. Those are reserved and used by other Apigee modules.
- If your Java Callout relies on additional third-party libraries packaged as independent JAR files, then place those JAR files in the `/resources/java` directory as well to ensure that they are loaded correctly at runtime.
- If there are multiple JARs, simply add them as additional resources. You do not need to modify the policy configuration to refer to additional JAR files. Putting them in `/resources/java` is sufficient.
- For additional information on uploading Java JARs, see [Resource files](https://docs.apigee.com/api-platform/develop/resource-files).