Search in sources :

Example 51 with CtField

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());
    }
}
Also used : CtField(javassist.CtField) NotFoundException(javassist.NotFoundException) CannotCompileException(javassist.CannotCompileException)

Example 52 with CtField

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();
    }
}
Also used : CodeConverter(javassist.CodeConverter) CtMethod(javassist.CtMethod) Method(java.lang.reflect.Method) CannotCompileException(javassist.CannotCompileException) NotFoundException(javassist.NotFoundException) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) CtField(javassist.CtField) CtMethod(javassist.CtMethod)

Example 53 with CtField

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);
}
Also used : CtField(javassist.CtField)

Example 54 with CtField

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");
}
Also used : CtClass(javassist.CtClass) FieldMetadata(javax.jdo.metadata.FieldMetadata) ForeignKeyMetadata(javax.jdo.metadata.ForeignKeyMetadata) CtField(javassist.CtField) Matchers.anyString(org.mockito.Matchers.anyString) MetadataDto(org.motechproject.mds.dto.MetadataDto) LookupFieldDto(org.motechproject.mds.dto.LookupFieldDto) FieldDto(org.motechproject.mds.dto.FieldDto) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Example 55 with CtField

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();
}
Also used : CtClass(javassist.CtClass) ClassData(org.motechproject.mds.domain.ClassData) CtField(javassist.CtField) ClassPool(javassist.ClassPool) MotechClassPool(org.motechproject.mds.javassist.MotechClassPool) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

CtField (javassist.CtField)76 CtClass (javassist.CtClass)47 CtMethod (javassist.CtMethod)27 CannotCompileException (javassist.CannotCompileException)24 NotFoundException (javassist.NotFoundException)22 ClassPool (javassist.ClassPool)20 CtConstructor (javassist.CtConstructor)15 Test (org.junit.Test)12 ClassFile (javassist.bytecode.ClassFile)9 IOException (java.io.IOException)7 Method (java.lang.reflect.Method)7 ArrayList (java.util.ArrayList)6 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4 ConstPool (javassist.bytecode.ConstPool)4 SMethod (org.bimserver.shared.meta.SMethod)4 SParameter (org.bimserver.shared.meta.SParameter)4 InsertableMethod (com.github.stephanenicolas.afterburner.inserts.InsertableMethod)3 SimpleInsertableMethod (com.github.stephanenicolas.afterburner.inserts.SimpleInsertableMethod)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3