Comments (7)
Calling withoutCode
creates an abstract method and a constructor cannot be abstract
. Instead, you would need to call the Object
class's default constructor. For this, you would need to implement approriate byte code. You can do this by creating a simple Instrumentation
:
TypeDescription objectType = new TypeDescription.ForLoadedType(Object.class);
new Instrumentation.Simple(
MethodVariableAccess.forType(objectType).loadFromIndex(0),
MethodInvocation.invoke(objectType.getDeclaredMethods().filter(isConstructor()).getOnly())
.special(objectType),
MethodReturn.VOID);
I recognize this use case and that this should be easier. I will add a utility instrumentation that makes this a one-liner in the future.
Also, you might want the type itself to be public
what you did not specify.
from byte-buddy.
Thanks mate. It was working in the end:
Find all annotated classes:
public static Set<Constructor> getSQLInjectedItemSubClassCtors() {
Predicate<String> filter = new FilterBuilder().include("mycore.legacy.*")
.include("myother.legacy.core.*");
Reflections reflections = new Reflections(new ConfigurationBuilder().filterInputsBy(filter)
.setScanners(
new SubTypesScanner().filterResultsBy(filter),
new MethodAnnotationsScanner().filterResultsBy( filter),
new MethodParameterScanner()).setUrls( ClasspathHelper.forClassLoader()));
Set<Constructor> annotated = reflections.getConstructorsAnnotatedWith(SQLInject.class);
return annotated;
}
Then create the mixin for them:
public static Class<?> createMixinFor(final Class declaringClass) {
assert(declaringClass != null);
try {
Annotation methodAnnotation = JacksonItemMixin.class.getDeclaredConstructor(Long.class).getAnnotation(JsonCreator.class);
assert(methodAnnotation != null);
Annotation parameterAnnotation = JacksonItemMixin.class.getDeclaredConstructor(Long.class).getParameterAnnotations()[0][0];
assert(parameterAnnotation != null);
LOG.debug("Annotation: {}",parameterAnnotation.annotationType());
TypeDescription objectType = new TypeDescription.ForLoadedType(Object.class);
Instrumentation instrumentation = new Instrumentation.Simple(MethodVariableAccess.forType(objectType).loadFromIndex(0), MethodInvocation.invoke(
objectType.getDeclaredMethods().filter(ElementMatchers.isConstructor()).getOnly()).special(objectType), MethodReturn.VOID);
Class<?> dynamicType = new ByteBuddy().withModifiers(TypeManifestation.ABSTRACT)
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.name(declaringClass.getCanonicalName().concat("MixIn"))
.defineConstructor(Arrays.<Class<?>>asList(Long.class), Visibility.PROTECTED)
.intercept(instrumentation)
.annotateMethod(methodAnnotation)
.annotateParameter(0, parameterAnnotation)
.make()
.load(CachingItemFactory.class.getClassLoader(), ClassLoadingStrategy.Default.CHILD_FIRST_PERSISTENT)
.getLoaded();
LOG.debug("created Mixin {} for {}", dynamicType, declaringClass);
assert(dynamicType.getDeclaredConstructor(Long.class) != null);
assert(dynamicType.getDeclaredConstructor(Long.class).getAnnotation(JsonCreator.class) != null);
assert(dynamicType.getDeclaredConstructor(Long.class).getParameterAnnotations()[0][0] != null);
return dynamicType;
} catch (NoSuchMethodException nme) {
LOG.error("createMixinFor: ", nme);
}
return null;
}
Finally, use jackson mapper to apply this all:
objectMapper = new ObjectMapper();
// use generated Mixin Classes
Set<Constructor> ctors = getSQLInjectedItemSubClassCtors();
for (Constructor ctor : ctors) {
// add mixin annotations for inheritance relationships
Class<?> persistenceClass = ctor.getDeclaringClass();
objectMapper.addMixInAnnotations(persistenceClass, createMixinFor(persistenceClass));
}
from byte-buddy.
Great, I would like to keep this issue open until I had the time to implement an instrumentation that makes this impler. Thanks for reporting and providing feedback.
from byte-buddy.
Oops sorry didn't want to disturb your work flow....
from byte-buddy.
No worries. I appreciate the clean-up and the feedback. This just serves me as a reminder.
from byte-buddy.
I implemented a MethodCall
instrumentation that is included in the next version of Byte Buddy. You can then create the instrumentation by:
MethodCall.invoke(Object.class.getDeclaredConstructor())
This instrumentation also allows you to hand over parameters if you wanted to call a constructor that takes parameters.
from byte-buddy.
This instrumentation is now implemented in the latest version and pushed to Maven Central.
from byte-buddy.
Related Issues (20)
- Can ByteBuddy add synchronized to intercepted setters? HOT 2
- Can ByteBuddy make a non-static field be final? HOT 1
- seems that namedOneOf isn't working as expected HOT 1
- Release missing of version 1.14.15 HOT 1
- java.lang.NoSuchMethodError when using the agent for method instrumentation HOT 2
- Cannot invoke public constructor HOT 5
- ByteBuddyAgent, Java 21 - A Java agent has been loaded dynamically HOT 2
- include method does not exist for Method Delegation approach HOT 6
- Having trouble delegating added instance method to static method HOT 2
- Setting value in constructor aliases collections HOT 5
- Is it possible to lazily instantiate AllArguments?
- install transformer takes too long time HOT 3
- Example that could be used in documentation HOT 6
- Issues attaching to Solaris Hotspot on Solaris 10 and 11. HOT 1
- How to generate multi-level generic code ? HOT 2
- java.lang.IllegalAccessError HOT 15
- InjectionStrategy.UsingUnsafe.OfFactory HOT 1
- java.lang.IncompatibleClassChangeError: Interface method reference: java.util.stream.Sink.begin(J)V HOT 1
- defineField not working well HOT 1
- JDK class enhancements HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from byte-buddy.