Custom converter to avoid the exception of IllegalAccessException while mapping XMLGregorianCalendarImpl in dozer - dozer

Initially I was getting the below exception: I am using dozer 5.4. I am having the xerces jar file in my classpath. I am new to dozer so any kind of help is very much appreciated.
org.dozer.MappingException: java.lang.IllegalAccessException: Class org.dozer.util.ReflectionUtils can not access a member of class org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl with modifiers "public"
I read from other posts from this site that the solution to the above is to write a custom converter for XmlGregorianCalender.
Below is the code for the custom converter. Currently the convertFrom method is getting invoked and all the values being passed are null.
Custom Converter:
import javax.xml.datatype.XMLGregorianCalendar;
import org.dozer.DozerConverter;
public class XMLGregorianCalendarCustomConvertor extends
DozerConverter<XMLGregorianCalendar, XMLGregorianCalendar>{
public XMLGregorianCalendarCustomConvertor() {
super(XMLGregorianCalendar.class, XMLGregorianCalendar.class);
// TODO Auto-generated constructor stub
}
#Override
public XMLGregorianCalendar convertTo(XMLGregorianCalendar source,
XMLGregorianCalendar destination) {
if (source == null) {
return null;
}
else{
return source;
}
}
#Override
public XMLGregorianCalendar convertFrom(XMLGregorianCalendar source,
XMLGregorianCalendar destination) {
if(destination == null){
return null;
}
else{
return destination;
}
}
}
Mapping xml
<configuration>
<custom-converters>
<converter type="com.code.user.XMLGregorianCalendarCustomConvertor" >
<class-a>javax.xml.datatype.XMLGregorianCalendar</class-a>
<class-b>javax.xml.datatype.XMLGregorianCalendar</class-b>
</converter>
</custom-converters>
</configuration>

How about copying it by reference ? If its an option for you you can do it like this:
<configuration>
<copy-by-references>
<copy-by-reference>
javax.xml.datatype.XMLGregorianCalendar
</copy-by-reference>
</copy-by-references>
</configuration>

The problem is the class:org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl is not a public implementation of: javax.xml.datatype.XMLGregorianCalendar
The solution is to simply add is-accessible="true" property to you destination class in Dozer converter configuration like that:
Mapping.xml
<configuration>
<custom-converters>
<converter type="com.code.user.XMLGregorianCalendarCustomConvertor" >
<class-a>javax.xml.datatype.XMLGregorianCalendar</class-a>
<class-b is-accessible="true">javax.xml.datatype.XMLGregorianCalendar</class-b>
</converter>
</custom-converters>
</configuration>
Hope it will help anyone!

Related

Vert.x Service Proxies: Just after I change service methods from returning Future<T> to Uni<T> of Smallrye Mutiny, the code generation failed

I've sucessfully generated service proxies for service having methods returning Future<T>,
but just after I changed those methods to return Uni<T> according to API Translation - Smallrye Mutiny Vert.x bindings,
when I try to execute mvn clean compile it always tells me this error message :
Could not generate model for com.example.beers.BarmanService#giveMeAStaticBeer(java.lang.String): Proxy methods must have void or Fluent returns
I would need your help to enlighten me how to fix it.
I put those codes on GitHub, and these are some critical ones:
//BarmanService.java
#VertxGen
#ProxyGen
public interface BarmanService {
Uni<Beer> giveMeAStaticBeer(String customerName);
Uni<Integer> getMyBill(String customerName);
Uni<Void> payMyBill(String customerName);
static BarmanService createProxy(Vertx vertx, String address) {
return new BarmanServiceVertxEBProxy(vertx, address);
}
}
//BarmanServiceImpl.java
public class BarmanServiceImpl implements BarmanService {
Map<String, Integer> bills;
public BarmanServiceImpl() {
this.bills = new HashMap<>();
}
#Override
public Uni<Beer> giveMeAStaticBeer(String customerName) {
Beer beer = new Beer("Workshop River Stout", "English Stout", 5);
return Uni.createFrom().item(() -> beer);
}
#Override
public Uni<Integer> getMyBill(String customerName) {
return Uni.createFrom().item(() -> bills.get(customerName));
}
#Override
public Uni<Void> payMyBill(String customerName) {
bills.remove(customerName);
System.out.println("Removed debt of " + customerName);
return Uni.createFrom().voidItem();
}
}
//package-info.java
#ModuleGen(groupPackage = "com.example", name = "beers")
package com.example.beers;
import io.vertx.codegen.annotations.ModuleGen;
<!-- //pom.xml -->
<dependencies>
<!-- // ... -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-codegen</artifactId>
<classifier>processor</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-service-proxy</artifactId>
</dependency>
<!-- // ... -->
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-mutiny-vertx-core</artifactId>
<version>2.30.1</version>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>vertx-mutiny-generator</artifactId>
<version>2.30.1</version>
</dependency>
<!-- // ... -->
</dependencies>
PS In the beginning, when I generated service proxies for service having methods returning Future<T>, there is a generated class returning Uni<T>, but I have no idea how to use it:
package com.example.mutiny.beers;
#io.smallrye.mutiny.vertx.MutinyGen(com.example.beers.BarmanService.class)
public class BarmanService {
public static final io.smallrye.mutiny.vertx.TypeArg<BarmanService> __TYPE_ARG = new io.smallrye.mutiny.vertx.TypeArg<>( obj -> new BarmanService((com.example.beers.BarmanService) obj),
BarmanService::getDelegate
);
private final com.example.beers.BarmanService delegate;
public BarmanService(com.example.beers.BarmanService delegate) {
this.delegate = delegate;
}
public BarmanService(Object delegate) {
this.delegate = (com.example.beers.BarmanService)delegate;
}
/**
* Empty constructor used by CDI, do not use this constructor directly.
**/
BarmanService() {
this.delegate = null;
}
public com.example.beers.BarmanService getDelegate() {
return delegate;
}
#CheckReturnValue
public io.smallrye.mutiny.Uni<com.example.beers.Beer> giveMeAStaticBeer(String customerName) {
return io.smallrye.mutiny.vertx.UniHelper.toUni(delegate.giveMeAStaticBeer(customerName));}
public com.example.beers.Beer giveMeAStaticBeerAndAwait(String customerName) {
return giveMeAStaticBeer(customerName).await().indefinitely();
}
public void giveMeAStaticBeerAndForget(String customerName) {
giveMeAStaticBeer(customerName).subscribe().with(io.smallrye.mutiny.vertx.UniHelper.NOOP);
}
// ...
public static com.example.mutiny.beers.BarmanService createProxy(io.vertx.mutiny.core.Vertx vertx, String address) {
com.example.mutiny.beers.BarmanService ret = com.example.mutiny.beers.BarmanService.newInstance((com.example.beers.BarmanService)com.example.beers.BarmanService.createProxy(vertx.getDelegate(), address));
return ret;
}
public static BarmanService newInstance(com.example.beers.BarmanService arg) {
return arg != null ? new BarmanService(arg) : null;
}
}
I just figured it out by myself. About to change service methods from returning Future<T> to Uni<T>,
The wrong apporach I did:
Edit package-info to remove useFutures = true
Edit service interfaces and change returning types
Edit service implimentations and change returning types, also change logic
Edit verticles to handle Uni<T> returned from service
And it turned out that the first three steps I did is unnecessary,
the suitable approach is:
Wrap vertx:
io.vertx.mutiny.core.Vertx mutinyVertx = new io.vertx.mutiny.core.Vertx(vertx);
Change the use of service interface to the generated one
import com.example.mutiny.beers.BarmanService;
Use the wrapped vertx:
BarmanService barmanService = BarmanService.createProxy(mutinyVertx, "beers.services.myapplication");
Edit verticles to handle Uni<T> returned from service
My problem has been solved, but I am not sure is it a good apporach to manually wrap the vertx on the MainVerticle launched by io.vertx.core.Launcher: io.vertx.mutiny.core.Vertx mutinyVertx = new io.vertx.mutiny.core.Vertx(vertx);, any suggestions guys?

my activemq plugin not work

I write an ActiveMQ plugin, but it does not work.
The code:
package cn.ennwifi.mqttplugin;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerPlugin;
public class MqttPlugin implements BrokerPlugin {
public Broker installPlugin(Broker broker) throws Exception {
return new MqttFilter(broker);
}
}
package cn.ennwifi.mqttplugin;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.command.ConnectionInfo;
public class MqttFilter extends BrokerFilter {
public MqttFilter(Broker broker) {
super(broker);
System.out.println("mqtt插件");
}
#Override
public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
System.out.println("mqtt连接信息:" + info.getClientId());
if (info.getUserName() != "123") {
return;
}
super.addConnection(context, info);
}
}
The configure:
<plugins>
<bean xmlns="http://www.springframework.org/schema/beans" id="myplugin" class="cn.ennwifi.mqttplugin.MqttPlugin"/>
</plugins>
I used mvn:clean package pack a jar,put it to activemq/lib
The version is 5.14.1
I change my code
if (info.getUserName() == null) {
throw new Exception("用户名不能为空");
}
I used throw an exception replace return.
Use Log4j to be able to see what's happening.
Do something like below:
private static Logger LOG = LoggerFactory.getLogger(MqttFilter.class);
LOG.info("my message");
Hope this helps.

Eclipse CDT extend AdapterFactory

I try to override the functionality of CDT ResumeAtLine, MoveToLine, RunToLine. For this reason I created a custom SuspendResumeAdapterFactory but it isn't loaded but compiles and runs without error. Do I maybe need a custom adaptableType too?
Here is the content of my plugin.xml.
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="my.package.CustomSuspendResumeAdapterFactory"
adaptableType="org.eclipse.cdt.dsf.ui.viewmodel.IVMContext">
<adapter type="org.eclipse.debug.core.model.ISuspendResume"/>
</factory>
</extension>
And here my CustomSuspendResumeAdapterFactory this class is reconstructed from memory not 100% sure if the syntax is correct, but I think it should be clear to see what I want to do.
package my.package;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.MoveToLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.ResumeAtLine;
import org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.ISuspendResume;
public class CustomSuspendResumeAdapterFactory implements IAdapterFactory {
static class SuspendResume implements ISuspendResume, IAdaptable {
private final CustomRunToLine fRunToLine;
private final CustomMoveToLine fMoveToLine;
private final CustomResumeAtLine fResumeAtLine;
SuspendResume(IExecutionDMContext execCtx) {
fRunToLine = new CustomRunToLine(execCtx);
fMoveToLine = new CustomMoveToLine(execCtx);
fResumeAtLine = new CustomResumeAtLine(execCtx);
}
#SuppressWarnings("unchecked")
#Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isInstance(RunToLine.class)) {
System.out.println("CUSTOM RUNTOLINE");
return (T)fRunToLine;
}
if (adapter.isInstance(MoveToLine.class)) {
System.out.println("CUSTOM MOVETOLINE");
return (T)fMoveToLine;
}
if (adapter.isInstance(ResumeToLine.class)) {
System.out.println("CUSTOM RESUMEATLINE");
return (T)fResumeAtLine;
}
return null;
}
#Override
public boolean canResume() { return false; }
#Override
public boolean canSuspend() { return false; }
// This must return true because the platform
// RunToLineActionDelegate will only enable the
// action if we are suspended
#Override
public boolean isSuspended() { return true; }
#Override
public void resume() throws DebugException {}
#Override
public void suspend() throws DebugException {}
}
#SuppressWarnings("unchecked")
#Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (ISuspendResume.class.equals(adapterType)) {
if (adaptableObject instanceof IDMVMContext) {
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(
((IDMVMContext)adaptableObject).getDMContext(),
IExecutionDMContext.class);
// It only makes sense to RunToLine, MoveToLine or
// ResumeAtLine if we are dealing with a thread, not a container
if (execDmc != null && !(execDmc instanceof IContainerDMContext)) {
return (T)new SuspendResume(execDmc);
}
}
}
return null;
}
#Override
public Class<?>[] getAdapterList() {
return new Class[] { ISuspendResume.class };
}
}
Why your code is not run
You have provided a new adapter factory that converts object types that are already handled. i.e. your plugin.xml says you can convert IVMContext to ISuspendResume. But the DSF plug-in already provides such an adapter factory. If you have a new target type (like IMySpecialRunToLine) you could install a factory for that, it would take IVMContext and convert it to a IMySpecialRunToLine).
Although dated, the Eclipse Corner Article on Adapter Pattern may be useful if this is a new concept.
How to do custom Run To Line implementation
If you want to provide different implementation of Run To Line, you need to provide your own version of org.eclipse.cdt.dsf.debug.service.IRunControl2.runToLine(IExecutionDMContext, String, int, boolean, RequestMonitor). The org.eclipse.cdt.dsf.debug.internal.ui.actions.RunToLine class is simply glue to connect UI features (such as buttons/etc some provided directly, some by the core eclipse debug) to the DSF backend. i.e. if you look at what RunToLine does, all it actually does is get the IRunControl2 service and call runToLine on it.
The way to provider your own implementation of IRunControl2 is override org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createRunControlService(DsfSession) and provide your own GdbDebugServicesFactory in your custom launch delegate by overriding org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate.newServiceFactory(ILaunchConfiguration, String)
RunToLine will be triggered when the user select Run To Line from the popup menu in the editor, as per this screenshot:

E4 Preference Initializer won´t get called

I´m trying to migrate my e3-rcp-app to a e4-rcp-app.
Therefore I need to define my default Preferences. (Not the Pref.Pages)
And by doing and trying so, I just can´t get my Initializer called. Here Is my initializer-class:
public class MyPreferenceInitializer extends AbstractPreferenceInitializer {
public MyPreferenceInitializer (){}
#Override
public void initializeDefaultPreferences() {
Preferences defaults = DefaultScope.INSTANCE.getNode(InspectIT.ID);
// Set defaults using things like:
defaults.put("DUMMY", "DUMMYCONTENT");
try {
defaults.flush();
} catch (BackingStoreException e) {
e.printStackTrace();
}
//And this other approach to make sure that one of them works
IPreferenceStore store = InspectIT.getDefault().getPreferenceStore();
store.setDefault("DUMMY", "DUMMYCONTENT");
try {
((Preferences) store).flush();
} catch (BackingStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Dummy impl
default Preferences....,
}
}
I also got an Activator class with the following structure: (Just posting the relevant methods(?))
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
private static Activator plugin;
private volatile ScopedPreferenceStore preferenceStore;
public void start(BundleContext context) throws Exception {
plugin = this;
Activator.context = context;
locateRuntimeDir();
logListener = new LogListener();
Platform.addLogListener(logListener);
//access to my initializor
String text = getPreferenceStore().getDefaultString("DUMMY");
String text2 = getPreferenceStore().getString("DUMMY");
}
public void stop(BundleContext context) throws Exception {
Activator.context = null;
plugin = null;
}
public static <E> E getService(Class<E> clazz) {
ServiceReference<E> reference = context.getServiceReference(clazz);
if (null != reference) {
return context.getService(reference);
}
throw new RuntimeException("Requested service of the class " + clazz.getName() + " is not registered in the bundle.");
}
public ScopedPreferenceStore getPreferenceStore() {
if (null == preferenceStore) {
synchronized (this) {
if (null == preferenceStore) {
preferenceStore = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, ID);
}
}
}
return preferenceStore;
}
}
The ScopedPreferenceStore I´m using is the one available at: https://github.com/opcoach/e4Preferences/tree/master/com.opcoach.e4.preferences
As well, I declared the plugin.xml Extension like this (I do need this, right?)
...
<extension
point="org.eclipse.core.runtime.preferences">
<initializer class="MyApplication.rcp.preferences.MyPreferenceInitializer ">
</initializer>
</extension>
...
I´m using Eclipse 4.5.1 on a win7 x64
I googled a lot and found a lot of Threads concerning this, but I just can´t find my mistake =/.
Anyone got a suggestion for why my default preferences initializer won´t get called?
Thanks in advance
You must still use the org.eclipse.core.runtime.preferences extension point to define the preferences initializer.
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="package.MyPreferenceInitializer">
</initializer>
</extension>
In the initializer use:
#Override
public void initializeDefaultPreferences()
{
Preferences defaults = DefaultScope.INSTANCE.getNode(Activator.ID);
// Set defaults using things like:
defaults.putInt("pref id", 0);
}
Finally I found a solution for this issue.
Accidentally got over this problem again and the mistake was in the Activator. I wrongly set the ID onto a wrong name. I reset it to my projects name and now it is working!
public ScopedPreferenceStore getPreferenceStore() {
if (null == preferenceStore) {
synchronized (this) {
if (null == preferenceStore)
preferenceStore = new ScopedPreferenceStore(ConfigurationScope.INSTANCE, ID);
}
}
return preferenceStore;
}
ID = Project-Name

jBoss deployment of message-driven bean spec violation

I have an java EE application which has one message-driven bean and it runs fine on JBoss 4, however when I configure the project for JBoss 6 and deploy on it, I get this error;
WARN [org.jboss.ejb.deployers.EjbDeployer.verifier] EJB spec violation:
...
The message driven bean must declare one onMessage() method.
...
org.jboss.deployers.spi.DeploymentException: Verification of Enterprise Beans failed, see above for error messages.
But my bean HAS the onMessage method! It would not have worked on jboss 4 either then.
Why do I get this error!?
Edit:
The class in question looks like this
package ...
imports ...
public class MyMDB implements MessageDrivenBean, MessageListener {
AnotherSessionBean a;
OneMoreSessionBean b;
public MyMDB() {}
public void onMessage(Message message) {
if (message instanceof TextMessage) {
try {
//Lookup sessionBeans by jndi, create them
lookupABean();
// check message-type, then invokie
a.handle(message);
// else
b.handle(message);
} catch (SomeException e) {
//handling it
}
}
}
public void lookupABean() {
try {
// code to lookup session beans and create.
} catch (CreateException e) { // handling it and catching NamingException too }
}
}
Edit 2:
And this is the jboss.xml relevant parts
<message-driven>
<ejb-name>MyMDB</ejb-name>
<destination-jndi-name>topic/A_Topic</destination-jndi-name>
<local-jndi-name>A_Topic</local-jndi-name>
<mdb-user>user</mdb-user>
<mdb-passwd>pass</mdb-passwd>
<mdb-client-id>MyMessageBean</mdb-client-id>
<mdb-subscription-id>subid</mdb-subscription-id>
<resource-ref>
<res-ref-name>jms/TopicFactory</res-ref-name>
<jndi-name>jms/TopicFactory</jndi-name>
</resource-ref>
</message-driven>
Edit 3:
I just removed all my jars from the project, and only re-added relevant ones (from new versions also) to put out NoClassDefFound errors.
Still the problem remains.
Edit:
Any directions, what area should I look at? My project, or jboss-configration, or the deployment settings??
org.jboss.ejb.deployers.EjbDeployer.verifier
looks for
public void onMessage(javax.jms.Message)
via some code like this (this is from JBoss5):
/**
* Check if the given message is the onMessage() method
*/
public boolean isOnMessageMethod(Method m)
{
if ("onMessage".equals(m.getName()))
{
Class[] paramTypes = m.getParameterTypes();
if (paramTypes.length == 1)
{
if (Message.class.equals(paramTypes[0]))
return true;
}
}
return false;
}
It is important that the parameter type is javax.jms.Message and nothing else, for example some subclass or superclass or some implementing class.
Your signature is public void onMessage(Message message) which looks ok on first sight.
A Class is equal only in its ClassLoader. If for some reasons javax.jms.Message is available in different classloaders in the same JVM, strange things can happen, depending on the ClassLoader of the EjbDeployer.verifier. Maybe the EjbDeployer.verifer has a access to javax.jms.Message in another ClassLoader as MyMDB. As result, both javax.jms.Message are not equal to each other, although they are the same byte-code and literally exists. The EjbVerifier will warn about missing onMessage, because javax.jms.Message on ClassLoader A is not equal to javax.jms.Message on ClassLoader B.
This can happen when libraries with javax.jms.Message is copied on wrong places on the JBoss AS. So I guess - from a distance - that there is some jars containing javax.jms.Message in wrong places on the JBoss or the EAR. For example some wrong jbossallclient.jar in the EAR.
Make sure your EAR does not contain its own copies of the javax.ejb classes (or any javax classes at all, for that matter). JBoss 4 and 6 have rather different classloading semantics, and what works on one may not work on the other. For example, if your EAR's lib contained its own copies of Message or MessageListener, then it may no longer work.
I tried it out on "JBossAS [6.0.0.20100911-M5 "Neo"]" and Eclipse Helios
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.Message;
import javax.jms.MessageListener;
#MessageDriven(
activationConfig = { #ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Topic"
) },
mappedName = "topic/A_Topic",
messageListenerInterface = MessageListener.class)
public class MyMDB implements MessageListener, MessageDrivenBean {
private static final long serialVersionUID = -4923389997501209506L;
public MyMDB() {
// TODO Auto-generated constructor stub
}
#Override
public void ejbRemove() {
// TODO Auto-generated method stub
}
#Override
public void setMessageDrivenContext(MessageDrivenContext arg0) {
// TODO Auto-generated method stub
}
#Override
public void onMessage(Message message) {
// TODO Auto-generated method stub
}
}
And this setting works. Do you have the same imports for your bean (perhaps there was an automatic import gone wrong???)