or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotation-based-definition.mdaspect-management.mdindex.mdjoin-point-introspection.mdreflection-api.mdruntime-utilities.mdsignature-system.md

join-point-introspection.mddocs/

0

# Join Point Introspection

1

2

Core runtime interfaces that provide reflective access to join points - the specific points in program execution where aspects can be applied. Join points represent method calls, method executions, field access, constructor calls, exception handlers, and other program execution events. The introspection API provides access to execution context, arguments, target objects, source location, and signature information.

3

4

## Capabilities

5

6

### JoinPoint Interface

7

8

The fundamental interface providing reflective access to both the state available at a join point and static information about it. Available in advice using the special form `thisJoinPoint`.

9

10

```java { .api }

11

/**

12

* Provides reflective access to both the state available at a join point and

13

* static information about it. This information is available from the body

14

* of advice using the special form thisJoinPoint.

15

*/

16

public interface JoinPoint {

17

/**

18

* Returns the currently executing object. This will always be

19

* the same object as that matched by the this pointcut designator.

20

* Returns null when there is no currently executing object available

21

* (e.g. static context).

22

*/

23

Object getThis();

24

25

/**

26

* Returns the target object. This will always be the same object

27

* as that matched by the target pointcut designator.

28

* Returns null when there is no target object.

29

*/

30

Object getTarget();

31

32

/**

33

* Returns the arguments at this join point

34

*/

35

Object[] getArgs();

36

37

/**

38

* Returns the signature at the join point

39

*/

40

Signature getSignature();

41

42

/**

43

* Returns the source location corresponding to the join point.

44

* If there is no source location available, returns null.

45

* Returns the SourceLocation of the defining class for default constructors.

46

*/

47

SourceLocation getSourceLocation();

48

49

/**

50

* Returns a string representing the kind of join point.

51

* This string is guaranteed to be interned.

52

*/

53

String getKind();

54

55

/**

56

* Returns an object that encapsulates the static parts of this join point

57

*/

58

StaticPart getStaticPart();

59

60

/**

61

* String representation of this join point

62

*/

63

String toString();

64

65

/**

66

* Returns an abbreviated string representation of the join point

67

*/

68

String toShortString();

69

70

/**

71

* Returns an extended string representation of the join point

72

*/

73

String toLongString();

74

}

75

```

76

77

**Usage Examples:**

78

79

```java

80

import org.aspectj.lang.JoinPoint;

81

import org.aspectj.lang.annotation.Aspect;

82

import org.aspectj.lang.annotation.Before;

83

84

@Aspect

85

public class LoggingAspect {

86

87

@Before("execution(* com.example.service.*.*(..))")

88

public void logMethodEntry(JoinPoint joinPoint) {

89

System.out.println("Entering: " + joinPoint.getSignature().getName());

90

System.out.println("Target: " + joinPoint.getTarget());

91

System.out.println("Args: " + Arrays.toString(joinPoint.getArgs()));

92

System.out.println("Kind: " + joinPoint.getKind());

93

System.out.println("Location: " + joinPoint.getSourceLocation());

94

}

95

}

96

```

97

98

### ProceedingJoinPoint Interface

99

100

Extends JoinPoint to expose the `proceed()` method for around advice in @AspectJ aspects. Allows advice to control whether and how the intercepted join point continues execution.

101

102

```java { .api }

103

/**

104

* ProceedingJoinPoint exposes the proceed(..) method in order to support

105

* around advice in @AJ aspects

106

*/

107

public interface ProceedingJoinPoint extends JoinPoint {

108

/**

109

* Proceed with the next advice or target method invocation

110

* @return the result of proceeding

111

* @throws Throwable if the invoked proceed throws anything

112

*/

113

Object proceed() throws Throwable;

114

115

/**

116

* Proceed with the next advice or target method invocation using modified arguments.

117

* The proceed(..) call takes arguments in this order:

118

* 1. If 'this()' was used in the pointcut for binding, it must be passed first

119

* 2. If 'target()' was used in the pointcut for binding, it must be passed next

120

* 3. All the arguments expected at the join point, in the order they are supplied

121

*

122

* @param args the arguments to proceed with

123

* @return the result of proceeding

124

* @throws Throwable if the invoked proceed throws anything

125

*/

126

Object proceed(Object[] args) throws Throwable;

127

}

128

```

129

130

**Usage Examples:**

131

132

```java

133

import org.aspectj.lang.ProceedingJoinPoint;

134

import org.aspectj.lang.annotation.Around;

135

import org.aspectj.lang.annotation.Aspect;

136

137

@Aspect

138

public class TimingAspect {

139

140

@Around("execution(* com.example.service.*.*(..))")

141

public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

142

long startTime = System.currentTimeMillis();

143

144

try {

145

// Proceed with original method execution

146

Object result = joinPoint.proceed();

147

return result;

148

} finally {

149

long executionTime = System.currentTimeMillis() - startTime;

150

System.out.println("Method " + joinPoint.getSignature().getName() +

151

" executed in " + executionTime + " ms");

152

}

153

}

154

155

@Around("execution(* com.example.service.*.*(String, ..)) && args(firstArg, ..)")

156

public Object interceptWithModifiedArgs(ProceedingJoinPoint joinPoint, String firstArg) throws Throwable {

157

Object[] args = joinPoint.getArgs();

158

159

// Modify the first argument

160

args[0] = "Modified: " + firstArg;

161

162

// Proceed with modified arguments

163

return joinPoint.proceed(args);

164

}

165

}

166

```

167

168

### JoinPoint.StaticPart Interface

169

170

Contains only the static information about a join point. Available separately within advice using the special form `thisJoinPointStaticPart`. Use this for better performance when only static information is needed.

171

172

```java { .api }

173

/**

174

* This helper object contains only the static information about a join point.

175

* If you are only interested in the static information about a join point,

176

* you should access it through this type for the best performance.

177

*/

178

public interface StaticPart {

179

/**

180

* Returns the signature at the join point

181

*/

182

Signature getSignature();

183

184

/**

185

* Returns the source location corresponding to the join point.

186

* If there is no source location available, returns null.

187

*/

188

SourceLocation getSourceLocation();

189

190

/**

191

* Returns a string representing the kind of join point.

192

* This String is guaranteed to be interned.

193

*/

194

String getKind();

195

196

/**

197

* Return the id for this JoinPoint.StaticPart. All JoinPoint.StaticPart

198

* instances are assigned an id number upon creation. For each advised type

199

* the id numbers start at 0. The id is guaranteed to remain constant

200

* across repeated executions but may change if the code is recompiled.

201

*/

202

int getId();

203

204

String toString();

205

String toShortString();

206

String toLongString();

207

}

208

```

209

210

**Usage Examples:**

211

212

```java

213

@Aspect

214

public class StaticAnalysisAspect {

215

216

@Before("execution(* com.example..*.*(..))")

217

public void analyzeJoinPoint(JoinPoint.StaticPart staticPart) {

218

System.out.println("Join Point ID: " + staticPart.getId());

219

System.out.println("Kind: " + staticPart.getKind());

220

System.out.println("Signature: " + staticPart.getSignature());

221

System.out.println("Location: " + staticPart.getSourceLocation());

222

}

223

}

224

```

225

226

### Join Point Kinds

227

228

Constants representing the different types of join points that can be intercepted:

229

230

```java { .api }

231

public interface JoinPoint {

232

// Method-related join points

233

String METHOD_EXECUTION = "method-execution";

234

String METHOD_CALL = "method-call";

235

236

// Constructor-related join points

237

String CONSTRUCTOR_EXECUTION = "constructor-execution";

238

String CONSTRUCTOR_CALL = "constructor-call";

239

240

// Field-related join points

241

String FIELD_GET = "field-get";

242

String FIELD_SET = "field-set";

243

244

// Initialization join points

245

String STATICINITIALIZATION = "staticinitialization";

246

String PREINITIALIZATION = "preinitialization";

247

String INITIALIZATION = "initialization";

248

249

// Exception and synchronization join points

250

String EXCEPTION_HANDLER = "exception-handler";

251

String SYNCHRONIZATION_LOCK = "lock";

252

String SYNCHRONIZATION_UNLOCK = "unlock";

253

254

// Advice execution join point

255

String ADVICE_EXECUTION = "adviceexecution";

256

}

257

```

258

259

### EnclosingStaticPart Interface

260

261

Marker interface extending StaticPart for enclosing join point information:

262

263

```java { .api }

264

/**

265

* Marker interface for enclosing static part information

266

*/

267

public interface EnclosingStaticPart extends StaticPart {

268

}

269

```

270

271

## Common Usage Patterns

272

273

### Basic Join Point Logging

274

275

```java

276

@Aspect

277

public class BasicLoggingAspect {

278

279

@Before("execution(* com.example..*.*(..))")

280

public void logEntry(JoinPoint jp) {

281

System.out.println("==> " + jp.toShortString());

282

}

283

284

@AfterReturning(pointcut = "execution(* com.example..*.*(..))", returning = "result")

285

public void logExit(JoinPoint jp, Object result) {

286

System.out.println("<== " + jp.toShortString() + " returned " + result);

287

}

288

}

289

```

290

291

### Performance Monitoring

292

293

```java

294

@Aspect

295

public class PerformanceAspect {

296

297

@Around("execution(* com.example.service.*.*(..))")

298

public Object monitorPerformance(ProceedingJoinPoint pjp) throws Throwable {

299

long start = System.nanoTime();

300

String methodName = pjp.getSignature().toShortString();

301

302

try {

303

Object result = pjp.proceed();

304

long duration = System.nanoTime() - start;

305

System.out.printf("%s completed in %.2f ms%n",

306

methodName, duration / 1_000_000.0);

307

return result;

308

} catch (Exception e) {

309

long duration = System.nanoTime() - start;

310

System.out.printf("%s failed after %.2f ms: %s%n",

311

methodName, duration / 1_000_000.0, e.getMessage());

312

throw e;

313

}

314

}

315

}

316

```

317

318

### Argument Validation and Modification

319

320

```java

321

@Aspect

322

public class ValidationAspect {

323

324

@Around("execution(* com.example.service.*.save*(..)) && args(entity, ..)")

325

public Object validateAndProceed(ProceedingJoinPoint pjp, Object entity) throws Throwable {

326

if (entity == null) {

327

throw new IllegalArgumentException("Entity cannot be null for " +

328

pjp.getSignature().getName());

329

}

330

331

// Log the validation

332

System.out.println("Validating " + entity.getClass().getSimpleName() +

333

" for " + pjp.getSignature().getName());

334

335

return pjp.proceed();

336

}

337

}

338

```