use of javassist.CtField in project compss by bsc-wdc.
the class ITAppEditor method edit.
/**
* Check the access to fields of objects
*/
@Override
public void edit(FieldAccess fa) throws CannotCompileException {
CtField field = null;
try {
field = fa.getField();
if (Modifier.isStatic(field.getModifiers())) {
return;
}
} catch (NotFoundException e) {
throw new CannotCompileException(e);
}
String fieldName = field.getName();
if (DEBUG) {
LOGGER.debug("Keeping track of access to field " + fieldName + " of class " + field.getDeclaringClass().getName());
}
boolean isWriter = fa.isWriter();
// First check the object containing the field
StringBuilder toInclude = new StringBuilder();
toInclude.append(itORVar).append(NEW_OBJECT_ACCESS).append("$0,").append(isWriter).append(");");
// Execute the access on the internal object
String internalObject = itORVar + GET_INTERNAL_OBJECT + "$0)";
String objectClass = fa.getClassName();
toInclude.append("if (").append(internalObject).append(" != null) {");
if (isWriter) {
// store a new value in the field
toInclude.append("((").append(objectClass).append(')').append(internalObject).append(").").append(fieldName).append(" = $1;");
toInclude.append("} else { " + PROCEED + "$$); }");
// Serialize the (internal) object locally after the access
toInclude.append(itORVar).append(SERIALIZE_LOCALLY + "$0);");
} else {
// read the field value
// read
toInclude.append("$_ = ((").append(objectClass).append(')').append(internalObject).append(").").append(fieldName).append(';');
toInclude.append("} else { " + PROCEED + "$$); }");
}
fa.replace(toInclude.toString());
if (DEBUG) {
LOGGER.debug("Replaced regular field access by " + toInclude.toString());
}
}
use of javassist.CtField in project compss by bsc-wdc.
the class ITAppModifier method modify.
/**
* Modify method
*
* @param appName
* @return
* @throws NotFoundException
* @throws CannotCompileException
* @throws ClassNotFoundException
*/
public Class<?> modify(String appName) throws NotFoundException, CannotCompileException, ClassNotFoundException {
Class<?> annotItf = Class.forName(appName + LoaderConstants.ITF_SUFFIX);
// Methods declared in the annotated interface
Method[] remoteMethods = annotItf.getMethods();
/*
* Use the application editor to include the COMPSs API calls on the application code
*/
CLASS_POOL.importPackage(LoaderConstants.PACKAGE_COMPSS_ROOT);
CLASS_POOL.importPackage(LoaderConstants.PACKAGE_COMPSS_API);
CLASS_POOL.importPackage(LoaderConstants.PACKAGE_COMPSS_API_IMPL);
CLASS_POOL.importPackage(LoaderConstants.PACKAGE_COMPSS_LOADER);
CLASS_POOL.importPackage(LoaderConstants.PACKAGE_COMPSS_LOADER_TOTAL);
CtClass appClass = CLASS_POOL.get(appName);
CtClass itApiClass = CLASS_POOL.get(LoaderConstants.CLASS_COMPSSRUNTIME_API);
CtClass itSRClass = CLASS_POOL.get(LoaderConstants.CLASS_STREAM_REGISTRY);
CtClass itORClass = CLASS_POOL.get(LoaderConstants.CLASS_OBJECT_REGISTRY);
CtClass appIdClass = CLASS_POOL.get(LoaderConstants.CLASS_APP_ID);
String varName = LoaderUtils.randomName(5, LoaderConstants.STR_COMPSS_PREFIX);
String itApiVar = varName + LoaderConstants.STR_COMPSS_API;
String itSRVar = varName + LoaderConstants.STR_COMPSS_STREAM_REGISTRY;
String itORVar = varName + LoaderConstants.STR_COMPSS_OBJECT_REGISTRY;
String itAppIdVar = varName + LoaderConstants.STR_COMPSS_APP_ID;
CtField itApiField = new CtField(itApiClass, itApiVar, appClass);
CtField itSRField = new CtField(itSRClass, itSRVar, appClass);
CtField itORField = new CtField(itORClass, itORVar, appClass);
CtField appIdField = new CtField(appIdClass, itAppIdVar, appClass);
itApiField.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
itSRField.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
itORField.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
appIdField.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
appClass.addField(itApiField);
appClass.addField(itSRField);
appClass.addField(itORField);
appClass.addField(appIdField);
/*
* Create a static constructor to initialize the runtime Create a shutdown hook to stop the runtime before the
* JVM ends
*/
manageStartAndStop(appClass, itApiVar, itSRVar, itORVar);
/*
* Create IT App Editor
*/
// Candidates to be instrumented if they are not
CtMethod[] instrCandidates = appClass.getDeclaredMethods();
// remote
ITAppEditor itAppEditor = new ITAppEditor(remoteMethods, instrCandidates, itApiVar, itSRVar, itORVar, itAppIdVar, appClass);
// itAppEditor.setAppId(itAppIdVar);
// itAppEditor.setAppClass(appClass);
/*
* Create Code Converter
*/
CodeConverter converter = new CodeConverter();
CtClass arrayWatcher = CLASS_POOL.get(LoaderConstants.CLASS_ARRAY_ACCESS_WATCHER);
CodeConverter.DefaultArrayAccessReplacementMethodNames names = new CodeConverter.DefaultArrayAccessReplacementMethodNames();
converter.replaceArrayAccess(arrayWatcher, (CodeConverter.ArrayAccessReplacementMethodNames) names);
/*
* Find the methods declared in the application class that will be instrumented - Main - Constructors - Methods
* that are not in the remote list
*/
if (DEBUG) {
LOGGER.debug("Flags: ToFile: " + WRITE_TO_FILE + " isWS: " + IS_WS_CLASS + " isMainClass: " + IS_MAIN_CLASS);
}
for (CtMethod m : instrCandidates) {
if (LoaderUtils.checkRemote(m, remoteMethods) == null) {
// Not a remote method, we must instrument it
if (DEBUG) {
LOGGER.debug("Instrumenting method " + m.getName());
}
StringBuilder toInsertBefore = new StringBuilder();
StringBuilder toInsertAfter = new StringBuilder();
/*
* Add local variable to method representing the execution id, which will be the current thread id. Used
* for Services, to handle multiple service executions simultaneously with a single runtime For normal
* applications, there will be only one execution id.
*/
m.addLocalVariable(itAppIdVar, appIdClass);
toInsertBefore.append(itAppIdVar).append(" = new Long(Thread.currentThread().getId());");
// TODO remove old code:
// boolean isMainProgram = writeToFile ? LoaderUtils.isOrchestration(m) : LoaderUtils.isMainMethod(m);
boolean isMainProgram = LoaderUtils.isMainMethod(m);
boolean isOrchestration = LoaderUtils.isOrchestration(m);
if (isMainProgram && IS_MAIN_CLASS) {
LOGGER.debug("Inserting calls at the beginning and at the end of main");
if (IS_WS_CLASS) {
//
LOGGER.debug("Inserting calls noMoreTasks at the end of main");
toInsertAfter.insert(0, itApiVar + ".noMoreTasks(" + itAppIdVar + ", true);");
m.insertBefore(toInsertBefore.toString());
// executed only if Orchestration finishes properly
m.insertAfter(toInsertAfter.toString());
} else {
// Main program
LOGGER.debug("Inserting calls noMoreTasks and stopIT at the end of main");
// Set global variable for main as well, will be used in code inserted after to be run no matter
// what
toInsertBefore.append(appName).append('.').append(itAppIdVar).append(" = new Long(Thread.currentThread().getId());");
// toInsertAfter.append("System.exit(0);");
toInsertAfter.insert(0, itApiVar + ".stopIT(true);");
toInsertAfter.insert(0, itApiVar + ".noMoreTasks(" + appName + '.' + itAppIdVar + ", true);");
m.insertBefore(toInsertBefore.toString());
// executed no matter what
m.insertAfter(toInsertAfter.toString(), true);
}
/*
* Instrumenting first the array accesses makes each array access become a call to a black box
* method of class ArrayAccessWatcher, whose parameters include the array. For the second round of
* instrumentation, the synchronization by transition to black box automatically synchronizes the
* arrays accessed. TODO: Change the order of instrumentation, so that we have more control about
* the synchronization, and we can distinguish between a write access and a read access (now it's
* read/write access by default, because it goes into the black box).
*/
m.instrument(converter);
m.instrument(itAppEditor);
} else if (isOrchestration) {
if (IS_WS_CLASS) {
//
LOGGER.debug("Inserting calls noMoreTasks and stopIT at the end of orchestration");
toInsertAfter.insert(0, itApiVar + ".noMoreTasks(" + itAppIdVar + ", true);");
m.insertBefore(toInsertBefore.toString());
// executed only if Orchestration finishes properly
m.insertAfter(toInsertAfter.toString());
} else {
LOGGER.debug("Inserting only before at the beginning of an orchestration");
m.insertBefore(toInsertBefore.toString());
// TODO remove old code m.insertAfter(toInsertAfter.toString());
// executed only if Orchestration finishes properly
}
m.instrument(converter);
m.instrument(itAppEditor);
} else {
LOGGER.debug("Inserting only before");
m.insertBefore(toInsertBefore.toString());
if (IS_WS_CLASS) {
// non-OE operations
if (Modifier.isPrivate(m.getModifiers())) {
m.instrument(converter);
m.instrument(itAppEditor);
}
} else {
// For an application class, instrument all non-remote methods
m.instrument(converter);
m.instrument(itAppEditor);
}
}
}
}
// Instrument constructors
for (CtConstructor c : appClass.getDeclaredConstructors()) {
if (DEBUG) {
LOGGER.debug("Instrumenting constructor " + c.getLongName());
}
c.instrument(converter);
c.instrument(itAppEditor);
}
if (WRITE_TO_FILE) {
// Write the modified class to disk
try {
appClass.writeFile();
} catch (Exception e) {
ErrorManager.fatal("Error writing the instrumented class file");
}
return null;
} else {
/*
* Load the modified class into memory and return it. Generally, once a class is loaded into memory no
* further modifications can be performed on it.
*/
return appClass.toClass();
}
}
use of javassist.CtField in project javaparser by javaparser.
the class JavassistClassDeclaration method solveSymbol.
@Deprecated
public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
for (CtField field : ctClass.getDeclaredFields()) {
if (field.getName().equals(name)) {
return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
}
}
final String superclassFQN = getSuperclassFQN();
SymbolReference<? extends ResolvedValueDeclaration> ref = solveSymbolForFQN(name, typeSolver, superclassFQN);
if (ref.isSolved()) {
return ref;
}
String[] interfaceFQNs = getInterfaceFQNs();
for (String interfaceFQN : interfaceFQNs) {
SymbolReference<? extends ResolvedValueDeclaration> interfaceRef = solveSymbolForFQN(name, typeSolver, interfaceFQN);
if (interfaceRef.isSolved()) {
return interfaceRef;
}
}
return SymbolReference.unsolved(ResolvedValueDeclaration.class);
}
use of javassist.CtField in project motech by motech.
the class EntityMetadataBuilderTest method shouldAddOneToOneRelationshipMetadata.
@Test
public void shouldAddOneToOneRelationshipMetadata() throws NotFoundException, CannotCompileException {
final String relClassName = "org.motechproject.test.MyClass";
final String relFieldName = "myField";
FieldDto oneToOneField = fieldDto("oneToOneName", OneToOneRelationship.class);
oneToOneField.addMetadata(new MetadataDto(RELATED_CLASS, relClassName));
oneToOneField.addMetadata(new MetadataDto(RELATED_FIELD, relFieldName));
FieldMetadata fmd = mock(FieldMetadata.class);
when(fmd.getName()).thenReturn("oneToOneName");
ForeignKeyMetadata fkmd = mock(ForeignKeyMetadata.class);
when(entity.getName()).thenReturn(ENTITY_NAME);
when(entity.getId()).thenReturn(3L);
when(schemaHolder.getFields(entity)).thenReturn(singletonList(oneToOneField));
when(entity.getTableName()).thenReturn(TABLE_NAME);
when(jdoMetadata.newPackageMetadata(PACKAGE)).thenReturn(packageMetadata);
when(packageMetadata.newClassMetadata(ENTITY_NAME)).thenReturn(classMetadata);
when(classMetadata.newFieldMetadata("oneToOneName")).thenReturn(fmd);
when(fmd.newForeignKeyMetadata()).thenReturn(fkmd);
/* We simulate configuration for the bi-directional relationship (the related class has got
a field that links back to the main class) */
CtClass myClass = mock(CtClass.class);
CtClass relatedClass = mock(CtClass.class);
CtField myField = mock(CtField.class);
CtField relatedField = mock(CtField.class);
when(myClass.getName()).thenReturn(relClassName);
when(myClass.getDeclaredFields()).thenReturn(new CtField[] { myField });
when(myField.getType()).thenReturn(relatedClass);
when(myField.getName()).thenReturn(relFieldName);
when(relatedClass.getDeclaredFields()).thenReturn(new CtField[] { relatedField });
when(relatedClass.getName()).thenReturn(CLASS_NAME);
entityMetadataBuilder.addEntityMetadata(jdoMetadata, entity, Sample.class, schemaHolder);
verifyCommonClassMetadata();
verify(fmd).setDefaultFetchGroup(true);
verify(fmd).setPersistenceModifier(PersistenceModifier.PERSISTENT);
verify(fkmd).setName("fk_Sample_oneToOneName_3");
}
use of javassist.CtField in project motech by motech.
the class EntityMetadataBuilderTest method shouldAddBaseEntityMetadata.
@Test
public void shouldAddBaseEntityMetadata() throws Exception {
CtField ctField = mock(CtField.class);
CtClass ctClass = mock(CtClass.class);
CtClass superClass = mock(CtClass.class);
ClassData classData = mock(ClassData.class);
ClassPool pool = mock(ClassPool.class);
PowerMockito.mockStatic(MotechClassPool.class);
PowerMockito.when(MotechClassPool.getDefault()).thenReturn(pool);
when(classData.getClassName()).thenReturn(CLASS_NAME);
when(classData.getModule()).thenReturn(MODULE);
when(classData.getNamespace()).thenReturn(NAMESPACE);
when(entity.getTableName()).thenReturn(TABLE_NAME);
when(pool.getOrNull(CLASS_NAME)).thenReturn(ctClass);
when(ctClass.getField("id")).thenReturn(ctField);
when(ctClass.getSuperclass()).thenReturn(superClass);
when(superClass.getName()).thenReturn(Object.class.getName());
when(jdoMetadata.newPackageMetadata(PACKAGE)).thenReturn(packageMetadata);
when(packageMetadata.newClassMetadata(ENTITY_NAME)).thenReturn(classMetadata);
entityMetadataBuilder.addBaseMetadata(jdoMetadata, classData, EntityType.STANDARD, Sample.class);
verify(jdoMetadata).newPackageMetadata(PACKAGE);
verify(packageMetadata).newClassMetadata(ENTITY_NAME);
verify(classMetadata).setTable(TABLE_NAME_3);
verifyCommonClassMetadata();
}
Aggregations