or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdindex.mdjava-agent.mdmulti-classloader.mdprogrammatic-weaving.md

programmatic-weaving.mddocs/

0

# Programmatic Weaving

1

2

The AspectJ Weaver provides programmatic APIs for embedding aspect weaving capabilities directly into applications. This allows developers to weave classes on-demand or integrate weaving into custom class loading mechanisms.

3

4

## Core Weaving Classes

5

6

### WeavingAdaptor

7

8

Main adaptor for embedding AspectJ weaving capabilities.

9

10

```java { .api }

11

public class WeavingAdaptor {

12

public WeavingAdaptor(WeavingClassLoader loader);

13

public WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs);

14

public void addURL(URL url);

15

public byte[] weaveClass(String name, byte[] bytes) throws IOException;

16

public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException;

17

public IMessageHolder getMessageHolder();

18

public String getContextId();

19

}

20

```

21

22

#### Constructors

23

24

```java { .api }

25

public WeavingAdaptor(WeavingClassLoader loader)

26

```

27

28

Creates a weaving adaptor with a weaving class loader.

29

30

**Parameters:**

31

- `loader` - Class loader implementing WeavingClassLoader interface

32

33

```java { .api }

34

public WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs)

35

```

36

37

Creates a weaving adaptor with explicit URLs and class handler.

38

39

**Parameters:**

40

- `handler` - Handler for generated classes during weaving

41

- `classURLs` - URLs containing classes to be woven

42

- `aspectURLs` - URLs containing aspect definitions

43

44

#### Methods

45

46

```java { .api }

47

public void addURL(URL url)

48

```

49

50

Adds a URL to the weaving classpath.

51

52

**Parameters:**

53

- `url` - URL to add to classpath

54

55

```java { .api }

56

public byte[] weaveClass(String name, byte[] bytes) throws IOException

57

```

58

59

Weaves a class using the configured aspects.

60

61

**Parameters:**

62

- `name` - Fully qualified class name (e.g., "com.example.MyClass")

63

- `bytes` - Original class bytes

64

65

**Returns:** Woven class bytes or original bytes if no weaving applied

66

67

**Throws:** `IOException` if weaving fails

68

69

```java { .api }

70

public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException

71

```

72

73

Weaves a class with optional forced weaving.

74

75

**Parameters:**

76

- `name` - Fully qualified class name

77

- `bytes` - Original class bytes

78

- `mustWeave` - If true, forces weaving even if no aspects match

79

80

**Returns:** Woven class bytes

81

82

**Throws:** `IOException` if weaving fails

83

84

```java { .api }

85

public IMessageHolder getMessageHolder()

86

```

87

88

Returns the message holder for weaving messages and warnings.

89

90

**Returns:** IMessageHolder instance containing weaving messages

91

92

```java { .api }

93

public String getContextId()

94

```

95

96

Returns the context identifier for this weaving adaptor.

97

98

**Returns:** String identifier for the weaving context

99

100

### ClassLoaderWeavingAdaptor

101

102

Extended weaving adaptor with classloader-specific functionality.

103

104

```java { .api }

105

public class ClassLoaderWeavingAdaptor extends WeavingAdaptor {

106

// Additional classloader-specific methods

107

}

108

```

109

110

## Core Preprocessor Interface

111

112

### ClassPreProcessor

113

114

Generic preprocessor interface for separating AspectJ weaving from JVMTI interfaces.

115

116

```java { .api }

117

public interface ClassPreProcessor {

118

void initialize();

119

byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,

120

ProtectionDomain protectionDomain);

121

void prepareForRedefinition(ClassLoader loader, String className);

122

}

123

```

124

125

#### initialize

126

127

Initializes the preprocessor.

128

129

```java { .api }

130

void initialize()

131

```

132

133

#### preProcess

134

135

Preprocesses class bytes, applying weaving transformations.

136

137

```java { .api }

138

byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,

139

ProtectionDomain protectionDomain)

140

```

141

142

**Parameters:**

143

- `className` - Name of class being processed

144

- `bytes` - Original class bytes

145

- `classLoader` - ClassLoader defining the class

146

- `protectionDomain` - Security protection domain

147

148

**Returns:** Processed class bytes

149

150

#### prepareForRedefinition

151

152

Prepares for class redefinition during hotswap scenarios.

153

154

```java { .api }

155

void prepareForRedefinition(ClassLoader loader, String className)

156

```

157

158

**Parameters:**

159

- `loader` - ClassLoader containing the class

160

- `className` - Name of class being redefined

161

162

### Aj

163

164

Main preprocessor implementation adapting between the preprocessor interface and AspectJ weaver.

165

166

```java { .api }

167

public class Aj implements ClassPreProcessor {

168

public Aj();

169

public Aj(IWeavingContext context);

170

public void initialize();

171

public byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader,

172

ProtectionDomain protectionDomain);

173

}

174

```

175

176

#### Constructors

177

178

```java { .api }

179

public Aj()

180

```

181

182

Creates an Aj preprocessor with default weaving context.

183

184

```java { .api }

185

public Aj(IWeavingContext context)

186

```

187

188

Creates an Aj preprocessor with custom weaving context.

189

190

**Parameters:**

191

- `context` - Custom weaving context for multi-classloader environments

192

193

## Usage Examples

194

195

### Basic Programmatic Weaving

196

197

```java

198

import org.aspectj.weaver.tools.WeavingAdaptor;

199

import java.io.FileInputStream;

200

import java.io.IOException;

201

202

public class BasicWeavingExample {

203

public static void main(String[] args) throws IOException {

204

// Create weaving adaptor

205

WeavingAdaptor adaptor = new WeavingAdaptor(

206

null, // GeneratedClassHandler

207

new URL[]{new URL("file:///path/to/classes/")}, // Class URLs

208

new URL[]{new URL("file:///path/to/aspects/")} // Aspect URLs

209

);

210

211

// Read original class bytes

212

byte[] originalBytes = readClassBytes("com.example.MyClass");

213

214

// Weave the class

215

byte[] wovenBytes = adaptor.weaveClass("com.example.MyClass", originalBytes);

216

217

// Use the woven bytes (e.g., save to file or define class)

218

saveWovenClass("com.example.MyClass", wovenBytes);

219

220

// Check for weaving messages

221

IMessageHolder messages = adaptor.getMessageHolder();

222

if (messages.hasAnyMessage(IMessage.ERROR)) {

223

System.err.println("Weaving errors occurred");

224

}

225

}

226

227

private static byte[] readClassBytes(String className) throws IOException {

228

// Implementation to read class bytes from file system

229

String path = className.replace('.', '/') + ".class";

230

return Files.readAllBytes(Paths.get(path));

231

}

232

233

private static void saveWovenClass(String className, byte[] bytes) throws IOException {

234

// Implementation to save woven bytes

235

String path = "woven/" + className.replace('.', '/') + ".class";

236

Files.write(Paths.get(path), bytes);

237

}

238

}

239

```

240

241

### Custom Class Loading with Weaving

242

243

```java

244

import org.aspectj.weaver.tools.WeavingAdaptor;

245

246

public class WeavingClassLoader extends URLClassLoader {

247

private final WeavingAdaptor weavingAdaptor;

248

249

public WeavingClassLoader(URL[] urls, ClassLoader parent) {

250

super(urls, parent);

251

this.weavingAdaptor = new WeavingAdaptor(this);

252

}

253

254

@Override

255

protected Class<?> findClass(String name) throws ClassNotFoundException {

256

try {

257

// Get original class bytes

258

byte[] originalBytes = getClassBytes(name);

259

260

// Weave the class

261

byte[] wovenBytes = weavingAdaptor.weaveClass(name, originalBytes);

262

263

// Define the woven class

264

return defineClass(name, wovenBytes, 0, wovenBytes.length);

265

266

} catch (IOException e) {

267

throw new ClassNotFoundException("Failed to weave class: " + name, e);

268

}

269

}

270

271

private byte[] getClassBytes(String name) throws IOException {

272

String resourceName = name.replace('.', '/') + ".class";

273

InputStream is = getResourceAsStream(resourceName);

274

if (is == null) {

275

throw new IOException("Class not found: " + name);

276

}

277

return is.readAllBytes();

278

}

279

}

280

```

281

282

### Preprocessor Integration

283

284

```java

285

import org.aspectj.weaver.loadtime.Aj;

286

import org.aspectj.weaver.loadtime.ClassPreProcessor;

287

288

public class CustomPreprocessorExample {

289

private final ClassPreProcessor processor;

290

291

public CustomPreprocessorExample() {

292

this.processor = new Aj();

293

processor.initialize();

294

}

295

296

public byte[] processClass(String className, byte[] originalBytes,

297

ClassLoader loader) {

298

return processor.preProcess(className, originalBytes, loader, null);

299

}

300

301

public void handleClassRedefinition(ClassLoader loader, String className) {

302

processor.prepareForRedefinition(loader, className);

303

}

304

}

305

```

306

307

### Error Handling and Diagnostics

308

309

```java

310

import org.aspectj.bridge.IMessage;

311

import org.aspectj.bridge.IMessageHolder;

312

313

public class WeavingDiagnostics {

314

public static void checkWeavingResults(WeavingAdaptor adaptor) {

315

IMessageHolder messages = adaptor.getMessageHolder();

316

317

// Check for errors

318

if (messages.hasAnyMessage(IMessage.ERROR)) {

319

System.err.println("Weaving errors:");

320

for (IMessage message : messages.getMessages(IMessage.ERROR, true)) {

321

System.err.println(" " + message.getMessage());

322

}

323

}

324

325

// Check for warnings

326

if (messages.hasAnyMessage(IMessage.WARNING)) {

327

System.out.println("Weaving warnings:");

328

for (IMessage message : messages.getMessages(IMessage.WARNING, true)) {

329

System.out.println(" " + message.getMessage());

330

}

331

}

332

333

// Check for info messages

334

if (messages.hasAnyMessage(IMessage.INFO)) {

335

System.out.println("Weaving info:");

336

for (IMessage message : messages.getMessages(IMessage.INFO, true)) {

337

System.out.println(" " + message.getMessage());

338

}

339

}

340

}

341

}

342

```

343

344

## Configuration Options

345

346

### System Properties

347

348

- **`WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE`**: Enable verbose weaving output

349

- **`WeavingAdaptor.SHOW_WEAVE_INFO_PROPERTY`**: Show detailed weave information

350

- **`WeavingAdaptor.TRACE_MESSAGES_PROPERTY`**: Enable message tracing

351

352

### Programmatic Configuration

353

354

```java

355

// Enable verbose output

356

System.setProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE, "true");

357

358

// Create adaptor with verbose settings

359

WeavingAdaptor adaptor = new WeavingAdaptor(classLoader);

360

```

361

362

## Performance Considerations

363

364

1. **Reuse WeavingAdaptor**: Create once and reuse for multiple classes

365

2. **Batch Processing**: Process multiple classes in a single session

366

3. **Caching**: Use WeavedClassCache for repeated weaving operations

367

4. **Memory Management**: Monitor memory usage during large weaving operations

368

369

## Troubleshooting

370

371

### Common Issues

372

373

1. **ClassNotFoundException**: Ensure all required classes and aspects are on the classpath

374

2. **IOException during weaving**: Check class format and aspect compatibility

375

3. **Performance degradation**: Consider enabling caching for repeated operations

376

377

### Debug Output

378

379

```java

380

// Enable debug output

381

System.setProperty("org.aspectj.weaver.showWeaveInfo", "true");

382

System.setProperty("aj.weaving.verbose", "true");

383

```