Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .cursor/rules/cloudinary.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: Cloudinary cloudinary_java — agent guide
alwaysApply: true
---

Read and follow `AGENTS.md` in the repository root. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
5 changes: 5 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Cloudinary cloudinary_java — instructions for AI coding agents

Read `AGENTS.md` in the repository root and follow it. It is the single
authoritative guide for this package: build/test commands, conventions,
gotchas, and when to use this SDK versus a sibling Cloudinary package.
81 changes: 81 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# AGENTS.md — cloudinary_java

## What this package is (one line)
Official Cloudinary server-side SDK for the JVM: upload assets, build transformation/delivery URLs, and call the Admin API from Java backends. The published artifact is `cloudinary-http5` (group `com.cloudinary`), built on Apache HttpClient 5.

## When to use this / when NOT to use this
- **Use this when:** your code runs on a **server or in the JVM** (Spring Boot, servlets, batch jobs, CLI tools) and needs signed uploads, signed delivery URLs, server-side URL/tag generation, or Admin API calls — i.e. anywhere the `api_secret` must stay private.
- **Do NOT use this when:** the code runs on an **Android device** (use [`cloudinary_android`](https://github.com/cloudinary/cloudinary_android) — it doesn't expect the secret on-device); or you want an idiomatic, coroutine-friendly **Kotlin** client (use [`cloudinary_kotlin`](https://github.com/cloudinary/cloudinary_kotlin)); or you need the no-code/agent path (use the Cloudinary MCP server).
- **Sibling packages / modules in this repo:** `cloudinary-core` (provider-agnostic core: URL/transformation builders, signing, params — no HTTP) → `cloudinary-http5` (HTTP transport on HttpClient 5, the artifact you depend on) → `cloudinary-taglib` (JSP tags). `cloudinary-test-common` holds shared test code only. The legacy `cloudinary-http45` artifact (HttpClient 4.5) belongs to the **1.x line only** — do not use it for 2.x.

## Setup
**Maven** (`pom.xml`):
```xml
<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http5</artifactId>
<version>2.4.0</version>
</dependency>
```
**Gradle** (`build.gradle`):
```groovy
implementation 'com.cloudinary:cloudinary-http5:2.4.0'
```

Required configuration / credentials — set via env var (or system property), constructor, or per-call config:
```bash
export CLOUDINARY_URL=cloudinary://<api_key>:<api_secret>@<cloud_name>
```

## Minimal runnable example
```java
import com.cloudinary.Cloudinary;
import com.cloudinary.Transformation;
import com.cloudinary.utils.ObjectUtils;

Cloudinary cloudinary = new Cloudinary(); // reads CLOUDINARY_URL

// Upload a local file (needs api_key + api_secret)
cloudinary.uploader().upload("my_picture.jpg", ObjectUtils.emptyMap());

// Build a transformation/delivery URL (cloud_name only)
String url = cloudinary.url()
.transformation(new Transformation().width(100).height(150).crop("fill"))
.generate("sample.jpg");
```

## Build / test commands (run these after editing)
This is a **multi-module Gradle** build; use the wrapper (`./gradlew`, or `gradlew.bat` on Windows). Requires **JDK 8+** (`sourceCompatibility`/`targetCompatibility = 1.8`).

```bash
./gradlew build # compile + assemble all modules
./gradlew :cloudinary-core:test # unit tests for the core module
./gradlew :cloudinary-http5:test # tests for the HTTP module
```
Integration tests hit a live Cloudinary cloud and need credentials. CI runs them per module via the `ciTest` task (excludes the `TimeoutTest` category) with `CLOUDINARY_URL` passed as a system property:
```bash
./gradlew -DCLOUDINARY_URL=$CLOUDINARY_URL ciTest -p cloudinary-http5 -i
```
The CI workflow first runs `./gradlew createTestSubAccount -PmoduleName=<core|http5|taglib>` to provision a throwaway test cloud (writes `tools/cloudinary_url.txt`); skip this for offline/unit work. There is no separate lint or formatter task in the Gradle build.

## Conventions & gotchas
- **Layered modules:** put provider-agnostic logic (URL building, signing, param handling) in `cloudinary-core`; only HTTP transport concerns belong in `cloudinary-http5`. Don't push core logic into the HTTP module.
- **Java 8 source level** — no Java 9+ language features or APIs in any module.
- **Secrets stay server-side:** signed uploads, signed delivery URLs, and Admin API calls require `api_secret`. Never ship it to a browser or Android bundle — that's the entire reason this server SDK exists.
- **Artifact coordinate:** the current artifact is `cloudinary-http5`. `cloudinary-http45` is the legacy HttpClient-4.5 coordinate for 1.x — update the coordinate when upgrading from 1.x.
- **Version support:** 2.0.0+ requires Java 8+; 1.1.0–1.39.0 supported Java 6+.

## Canonical docs (leave the repo for depth)
- Java SDK guide: https://cloudinary.com/documentation/java_integration
- Image/video manipulation: https://cloudinary.com/documentation/java_image_manipulation
- Transformation & API reference: https://cloudinary.com/documentation/cloudinary_references
- Maven Central artifact: https://central.sonatype.com/artifact/com.cloudinary/cloudinary-http5
- MCP server (agent/no-code path): https://github.com/cloudinary/mcp-servers

## Agent / MCP note
If the capability you need is also exposed via the Cloudinary MCP servers, prefer the MCP tool for autonomous task execution and use this SDK for code generation. See cloudinary/mcp-servers.

## Commit / PR conventions
- Open issues/PRs against https://github.com/cloudinary/cloudinary_java. (There is no `CONTRIBUTING.md` in this repo.)
- All matrix CI jobs (modules `core`, `http5`, `taglib` on JDK 8) must pass before merge.
- Add a `CHANGELOG.md` entry for user-facing changes.
33 changes: 33 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@AGENTS.md

# CLAUDE.md — cloudinary_java

## Claude Code-specific notes

**Primary reference:** `AGENTS.md` (imported above) covers setup, build commands, conventions, and gotchas. Read it before touching any file.

## What this repo is

`cloudinary_java` is the official server-side Cloudinary SDK for the JVM. The published artifact is `cloudinary-http5` (group `com.cloudinary`), built on Apache HttpClient 5. Use it from Java backends — Spring Boot, servlets, batch jobs — where the `api_secret` must stay private.

## Key constraints / gotchas

- **Multi-module Gradle build.** Depend on `cloudinary-http5`; it pulls in `cloudinary-core` transitively. Do not depend on `cloudinary-core` directly for HTTP work.
- **Artifact coordinate changed at 2.x.** The legacy `cloudinary-http45` coordinate belongs to the 1.x line only — there is no `cloudinary-http45:2.x`. Change the `artifactId` to `cloudinary-http5` when upgrading from 1.x.
- **Java 8 source level.** No Java 9+ language features or APIs anywhere in the codebase (`sourceCompatibility = targetCompatibility = 1.8`).
- **`api_secret` is server-only.** Never ship it to a browser or Android bundle. Use the signed-upload pattern (server signs, browser posts directly to Cloudinary) to keep the secret off the client.
- **Not for Android.** Use [`cloudinary_android`](https://github.com/cloudinary/cloudinary_android). Not for idiomatic Kotlin: use [`cloudinary_kotlin`](https://github.com/cloudinary/cloudinary_kotlin).
- **Integration tests need a live cloud.** CI provisions a throwaway sub-account via `./gradlew createTestSubAccount`. For offline/unit work, skip that step — unit tests in `cloudinary-core` and `cloudinary-http5` run without credentials.

## Verified build commands

```bash
./gradlew build # compile + assemble all modules
./gradlew :cloudinary-core:test # unit tests, no credentials needed
./gradlew :cloudinary-http5:test # HTTP module unit tests

# Full integration suite (needs CLOUDINARY_URL):
./gradlew -DCLOUDINARY_URL=$CLOUDINARY_URL ciTest -p cloudinary-http5 -i
```

Use `gradlew.bat` instead of `./gradlew` on Windows. There is no separate lint or formatter task in the Gradle build.
Loading