EclassImpl setEPackage() - java

I need to work with some emf code without having any clue how it works. The code uses EcoreUtil.copy(...) to clone the classes. I added a EClass to the class i created like this:
EClassImpl c = (EClassImpl)EcoreFactory.eINSTANCE.createEClass();
System.out.println(c.getEPackage().getEFactoryInstance());
And also overrode eStaticClass() like this:
#Override
protected EClass eStaticClass() {
EClassImpl c = (EClassImpl)EcoreFactory.eINSTANCE.createEClass();
return c;
}
Now i have the problem, that the copy routine tries to use:
eClass.getEPackage().getEFactoryInstance().create(eClass);
Which returns a nullpointer exception, since getEPackage() returns null. Unfortunatly there seems to be no setter for the EPackage, so how do i set it?

Had the same problem. See in http://emfjson.org/docs/ how they use the API as an example.
samplePackage
.getEClassifiers()
.add(userClass);
This will add the class to the package and vice versa.

I managed to solve it myself, here is my solution in case anybody else ever comes across this:
EPackageImpl epi = (EPackageImpl)EcoreFactory.eINSTANCE.createEPackage();
c.eBasicSetContainer(epi, EcorePackage.ECLASSIFIER__EPACKAGE, null);

Related

How can I change a number in a interface object from a variable in Java using something like Reflection or Javassist

I have a variable, which is a new interface. I would like to change something inside of that.
I am not sure if this is possible with something like Reflection or Javassist.
This is fairly hard to explain, but if you look at the example you might understand me a bit better.
If you need more information, please ask because I really need to know this.
(this is code from ProtocolLib, which uses Netty. I want to patch something in ProtocolLib at runtime; hence I want to use something like Reflection or Javassist)
Actually; I just noticed that with some spaghetti code I can get this to work using Reflection. I will edit this post once again to let you know if this worked and then share my solution for others that might encounter the same issue as me.
Here is an example:
final ChannelInboundHandler endInitProtocol = new ChannelInitializer<Channel>() {
#Override
protected void initChannel(final Channel channel) throws Exception {
try {
synchronized (networkManagers) {
if (MinecraftVersion.getCurrentVersion().getMinor() >= 12 /* I want to change this 12 to an 8 using Reflection or something like Javassist */) {
channel.eventLoop().submit(() ->
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject());
} else {
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject();
}
}
} catch (Exception ex) {
reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(ex));
}
}
};
I completely forgot to tell that this question has been solved.
My solution:
I downloaded the ProtocolLib source code, then I made my changes to get it to work. I then compiled ProtocolLib, opened it with WinRAR, and extracted the anonymous class (ProtocolInjector$1). I added that class to my resources folder. I then used Javassist to create a new class out of the compiled class file (.class) at runtime and then I replaced the broken ProtocolInjector$1 class with the compiled fixed one.
You can see my commit here on how I fixed that: GitHub

TestNG expectedExceptionsMessageRegExp and externalized messages

I'm using TestNG for my unit tests and I'd like to check exception messages. OK, #Test(expectedExceptionsMessageRegExp = ...) is exactly what I need, right? Well, at the same time I'd like to externalize my messages so they aren't mixed with my code. I'm loosely following a guide by Brian Goetz, so my exception code looks like
throw new IllegalArgumentException(MessageFormat.format(
EXCEPTIONS.getString(EX_NOT_A_VALID_LETTER), c));
Works perfectly for me, except these two things don't exactly mix. I can't write
#Test(dataProvider = "getInvalidLetters",
expectedExceptions = {IllegalArgumentException.class},
expectedExceptionsMessageRegExp = regexize(EXCEPTIONS.getString(EX_NOT_A_VALID_LETTER)))
Here, regexize is a function that is supposed to replace {0}-style placeholders with .*. However, this fails with a “element value must be a constant expression”. Makes sense, since it's needed at compile time. But what are possible workarounds?
I can imagine a test code generator that would replace these constructs with real message regexps, but it would be a pain to integrate it with IDE, SCM, build tools and so on.
Another option is to use try-catch and check exception message manually. But this is ugly.
Lastly, I think it should be possible to hack TestNG with something like
#Test(expectedExceptionsMessageBundle = "bundle.name.goes.here",
expectedExceptionsMessageLocaleProvider = "functionReturningListOfLocales"
expectedExceptionsMessageKey = "MESSAGE_KEY_GOES_HERE")
This would be a great thing, really. Except that it won't be the same TestNG that Maven fetches for me from the repo. Another option is to implement this, contribute a patch to TestNG and wait for it to be released. I'm seriously considering this option now, but maybe there's an easier way? Haven't I missed something obvious? I can't possibly be the only one with this issue!
Or maybe I'm externalizing my messages in a wrong way. But a guy like Brian Goetz can't be wrong, now can he? Or did I get him wrong?
Update
Based on the answer given here, I've made a tutorial on the topic, covering some pitfalls, especially when using NetBeans 8.1.
Why not using an annotation transformer here?
You will be able to do something like:
#LocalizedException(expectedExceptionsMessageBundle = "bundle.name.goes.here",
expectedExceptionsMessageLocaleProvider = "functionReturningListOfLocales"
expectedExceptionsMessageKey = "MESSAGE_KEY_GOES_HERE")
#Test(dataProvider = "getInvalidLetters",
expectedExceptions = {IllegalArgumentException.class)
public void test() {
// ...
}
Where the annotation transformer will look like:
public class LocalizedExceptionTransformer implements IAnnotationTransformer {
public void transform(ITest annotation, Class testClass,
Constructor testConstructor, Method testMethod) {
if (testMethod != null) {
LocalizedException le = testMethod.getAnnotation(LocalizedException.class);
if (le != null) {
String regexp = regexize(le);
annotation.setExpectedExceptionsMessageRegExp(regexp);
}
}
}
}

Picocontainer 2.14.3 and AOP

I'm trying to use AOP with picocontainer.
so far I found in the documentation:
http://picocontainer.codehaus.org/interception.html
pico = new DefaultPicoContainer();
pico.as(INTERCEPT).addComponent(Apple.class, BraeburnApple.class);
and then create the interceptor, but looking through the code, I cannot find the INTERCEPT property anywhere.
as receives a Properties value, which pico implements in Characteristics class.
anyone has a clue, or has implemented it before and knows how to keep with it?
Thanks
looks like the property for this Behavior is somehow missing in this pico version, check org.picocontainer.Characteristics in older versions, I really hope it was implemented somewhere :)
Also there's old styled way for interception in pico: http://www.markhneedham.com/blog/2008/11/11/logging-with-pico-container/
Since the 2.14.3 org.picocontainer.behaviors still have these classes, I suppose this way is ok
This worked for me. First, create a proxy by extending a bean:
public static class ChangeMapInfoEndpointInterceptor extends MapInfoRoutingManagementBean {
#Override
public void setEndpoint(String endpoint) {
System.out.println("setEndpoint called");
}
}
Then pass it to the intercepting-styled container:
MutablePicoContainer context = new PicoBuilder().withBehaviors(new Intercepting()).build();
context.addComponent(MapInfoRoutingManagement.class, MapInfoRoutingManagementBean.class);
Intercepted intercepted = context.getComponentAdapter(MapInfoRoutingManagement.class).findAdapterOfType(Intercepted.class);
intercepted.addPostInvocation(MapInfoRoutingManagement.class, new ChangeMapInfoEndpointInterceptor());

GWT.create(clazz) "generics" approach

I have to develop an "generic" wigdet for a GWT/GXT project and to do so I need to create an instance of an object which type is unknown. I found an approach that works perfectly in dev mode but as soon as I try to compile my project and deploy it I get an Only class literals may be used as arguments to GWT.create() error.
Here is a sample of what I do:
public class GenericEditableGrid<M> extends Grid<M>{
private final ToolBar toolBar = new ToolBar();
private final TextButton newItemButton = new TextButton();
protected GridInlineEditing<M> editing;
private final Class<M> clazzM;
public GenericEditableGrid(Class<M> parametrizedClass, String gridTitle, ListStore<M> listStore, ColumnModel<M> cm) {
super(listStore, cm);
clazzM = parametrizedClass;
// ... then I create my widget
bind();
}
private void bind(){
newItemButton.addSelectHandler(new SelectEvent.SelectHandler() {
#Override
public void onSelect(SelectEvent selectEvent) {
editing.cancelEditing();
// it is the folliwing line which is the problem obviously
M element = GWT.create(clazzM);
getStore().add(0, element);
int index = 0;
editing.startEditing(new Grid.GridCell(getStore().indexOf(element), index));
}
});
}
}
And this is how I use it in my subclasses:
super(InternationalString.class, gridTitle, new ListStore<InternationalString>(isprops.key()), buildColumnModel());
Basically, I would like to know what the problem is exactly with this approach and eventually how I should do to make it well.
Please note that my concern is not just to make it work, but more to do it the right way. As I could just avoid the problem using an abstract method which would handle the GWT.create() method in the daughter classes. But this is not the design I want, it just doesn't look right.
What I don't get also is what's the difference between doing this:
MyClass e = GWT.create(MyClass.class);
and:
Class<MyClass> clazz=MyClass.class;
MyClass e = GWT.create(clazz);
Because as far as I am concerned I think this is basically what I am doing and it looks like the same thing. Isn't it?
There's a well-worded explanation in this forum:
As the error message indicates, only class literals may be passed to the GWT.create method. The reason for this is that all GWT.create calls are basically turned into constructors at compile time, using the deferred binding rules for your module. As a result, all classes must be decided at compile time - your code requires that the at runtime the class is decided. This is too late, and so cannot be compiled.
GWT is not proper java, and so cannot be always treated as java. This is one such example of things that cannot be done in gwt. ...
What is it you are trying to do? Either you are making it far more complicated than it needs to be, or you need to write a generator to do it instead of taking this approach.

How to ask BeanUtils to ignore null values

Using Commons beanUtils I would like to know how to ask any converter say the Dateconverter to ignore null values and use null as default. As an example consider a public class,
public class X {
private Date date1;
private String string1;
//add public getters and setters
}
and my convertertest as,
public class Apache {
#Test
public void testSimple() throws Exception {
X x1 = new X(), x2 = new X();
x1.setString1("X");
x1.setDate1(null);
org.apache.commons.beanutils.BeanUtils.copyProperties(x2, x1);
//throws ConversionException
System.out.println(x2.getString1());
System.out.println(x2.getDate1());
}
}
The above throws a NPE since the date happens to be null. This looks a very primitive scenario to me which should be handled by default (as in, I would expect x2 to have null value for date1). The doco tells me that I can ask the converter to do this. Can someone point me as to the best way for doing this ?
I dont want to get hold of the Converter and isUseDefault() to be true because then I have to do it for all Date, Enum and many other converters !
Apparently it looks like, there is a way to tell the ConvertUtils to not throw exceptions on null values which is achieved by calling
BeanUtilsBean.getInstance().getConvertUtils().register(false, false, 0);
The best solution is update to BeanUtils 1.9.0, since this problem is fixed as you can see here https://issues.apache.org/jira/browse/BEANUTILS-454
Maybe a little late but looks that you can register a DateConverter
https://issues.apache.org/jira/browse/BEANUTILS-387
I recently ran into this issue and just converted my variable to a string to avoid this error and converted it back to a date when needed. Not the most elegant solution, but for simplicity and to avoid problems like this, it's a viable solution. The other caveat was that BeanUtils would fire off it's methods before my classes would load, so I opted for this rather than a more complicated solution to the problem using custom classloaders.
By the way, prior to verion 1.8.0, BeanUtils itself would ignore these null values.
See this link:
No value specified for 'Date' when the field is a java.util.Date with a null value for a detailed explanation.
I am somewhat amazed that such a simple case as setting a null value in a bean, like this:
BeanUtils.setProperty(pojo, "date", null);
causes crashing behavior, as described above.
For what it's worth, here is my workaround:
import org.apache.commons.beanutils.BeanMap;
BeanMap beanMap = new BeanMap(pojo);
Method writeMethod = beanMap.getWriteMethod("date");
writeMethod.invoke(pojo, null);

Categories

Resources