I have these classes:
My problem is that for each class I am having to manually register the node.
/**
* Contains the encoder for messages from the server.
*
* #since 18/08/2018
*/
public abstract class MessageEncoder<T> {
/**
* Register this encoder to a message.
*/
public abstract void register();
/**
* Get the encoded message to send to the client.
*
* #param message The message.
* #return the {#link GamePacket} ready to be sent.
*/
public abstract GamePacket encode(T message);
}
Where < T > is always someClass extends Message.
And here is how a message encoder looks like:
public final class ComponentMessageEncoder extends MessageEncoder<ComponentTextMessage> {
#Override
public void register() {
GameConstants.RELEASE.register(ComponentTextMessage.class, this);
}
#Override
public GamePacket encode(ComponentTextMessage message) {
// TODO Auto-generated method stub
return null;
}
}
As you can see the items in the register method, I have to manually type that for every encoder I make.
Is there a shortcut for this that I can just put in MessageEncoder abstract class instead?
I could not find anything that works here
Edit:
Where register sig. is:
/**
* The encoders.
*/
private final Map<Class<? extends Message>, MessageEncoder<?>> encoders = new HashMap<>();
/**
* Register a encoder to a message.
*
* #param message The message.
* #param encoder The encoder.
*/
public void register(Class<? extends Message> message, MessageEncoder<?> encoder) {
encoders.put(message, encoder);
}
You can do slightly better with:
public abstract class MessageEncoder<T extends Message> {
protected MessageEncoder(Class<? extends T> messageClass) {
GameConstants.RELEASE.register(messageClass, this);
}
/**
* Get the encoded message to send to the client.
*
* #param message The message.
* #return the {#link GamePacket} ready to be sent.
*/
public abstract GamePacket encode(T message);
}
Now subclasses would do:
public final class ComponentMessageEncoder extends MessageEncoder<ComponentTextMessage> {
ComponentMessageEncoder() {
super(ComponentTextMessage.class);
}
// etc as before
}
This cuts down slightly on the repetition, and it allows the compiler to stop you from getting it wrong, so it's something of a win.
Related
I've written a class in Java that allows classes to listen for events fired by other classes (Just like EventEmitter in JavaScript). This thing works really well, but when a class listening for an event dies, the callback function the class created for the event lives on, and can cause problems when called as the scope is no longer valid for it.
I'm looking for a way to detect when an callback's parent class is dead, so I can remove the callback rather than call it.
Listening code:
//This function/interface will never be cleaned up after the parent class dies
otherclass.on("eventcalled", new EventEmitter.EventInterface() {
#Override
public void onEvent() {
System.out.println("Event Called!");
}
});
Emitting Class:
public class OtherClass extends EventEmitter {
public OtherClass(String token) {
emit("eventcalled");
}
}
and the EventEmitter class:
package com.active.xxxxx.xxxxx;
import android.util.Pair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class EventEmitter {
public interface EventInterface {
default void onEvent() {};
default void onEvent(byte[] data) {};
default void onEvent(float data) {};
default void onEvent(byte[] data, int size) {};
}
private HashMap<String, List<Pair<EventInterface, Boolean>>> eventListeners = new HashMap<String, List<Pair<EventInterface, Boolean>>>();
/**
* Listen for events for the specified event ID. These events can be emitted with the 'emit' function
* #param event the event id to listen for
* #param toAdd the callback function to call
* when the event is emitted.
* Callback functions must be of
* type EventEmitter.EventInterface
* and override the desired onEvent overload
* </code>
*
*/
public void on(String event, EventInterface toAdd) {
if (!eventListeners.containsKey(event))
eventListeners.put(event, new ArrayList<>());
eventListeners.get(event).add(Pair.create(toAdd, false));
}
/**
* Listen for events for the specified event ID. These events can be emitted with the 'emit' function
* This function is like the <code>.on()</code> function, but it will only be called once, then discarded.
* #param event the event id to listen for
* #param toAdd the callback function to call
* when the event is emitted.
* Callback functions must be of
* type EventEmitter.EventInterface
* and override the desired onEvent overload
* </code>
*
*/
public void once(String event, EventInterface toAdd) {
if (!eventListeners.containsKey(event))
eventListeners.put(event, new ArrayList<>());
eventListeners.get(event).add(Pair.create(toAdd, true));
}
/**
* Emit an event to anyone listen to this event id.
* #param event the event id to emit
*/
public void emit(String event)
{
if (!eventListeners.containsKey(event))
return;
for (Pair<EventInterface, Boolean> ev : eventListeners.get(event))
ev.first.onEvent();
_removeOnces(eventListeners.get(event));
}
/**
* Emit an event to anyone listen to this event id.
* #param event the event id to emit
* #param data the float data associated with this event
*/
public void emit(String event, float data)
{
if (!eventListeners.containsKey(event))
return;
for (Pair<EventInterface, Boolean> ev : eventListeners.get(event))
ev.first.onEvent(data);
_removeOnces(eventListeners.get(event));
}
/**
* Emit an event to anyone listen to this event id.
* #param event the event id to emit
* #param data the byte array data associated with this event
*/
public void emit(String event, byte[] data)
{
if (!eventListeners.containsKey(event))
return;
for (Pair<EventInterface, Boolean> ev : eventListeners.get(event))
ev.first.onEvent(data);
_removeOnces(eventListeners.get(event));
}
/**
* Emit an event to anyone listen to this event id.
* #param event the event id to emit
* #param data the byte array data associated with this event
* #param size the size of the byte array data associated with this event
*/
public void emit(String event, byte[] data, int size)
{
if (!eventListeners.containsKey(event))
return;
for (Pair<EventInterface, Boolean> ev : eventListeners.get(event))
ev.first.onEvent(data, size);
_removeOnces(eventListeners.get(event));
}
private void _removeOnces(List<Pair<EventInterface, Boolean>> listeners)
{
Iterator itr = listeners.iterator();
while (itr.hasNext())
if (((Pair<EventInterface, Boolean>)itr.next()).second) //Remove this event from the list if the bool is 'true' (Marked as a once event)
itr.remove();
}
/**
* Remove all event listeners from this event id.
* #param event the event id to remove listeners from
*/
public void off(String event) {
if (!eventListeners.containsKey(event))
return;
eventListeners.get(event).clear();
}
/**
* Remove all event listeners from this emitter.
*/
public void clearListeners() {
eventListeners.clear();
}
}
I'm trying to consume wsdl client that can be found on this link https://tim-erp.com/ERPX_WEB/awws/ErpX.awws?wsdl
My java code looks like this
public class SoapServicesImpl extends WebServiceGatewaySupport implements SoapServices {
#Override
public String doAuth(AuthDto authDto){
AuthStrct authStrct = new AuthStrct();
authStrct.setFirmaNaziv(authDto.getNazivFirme());
authStrct.setGodina(authDto.getGodina());
authStrct.setPassword(authDto.getPassword());
authStrct.setUsername(authDto.getUsername());
return callService(new ObjectFactory().createAuthStrct(authStrct));
}
#SuppressWarnings("unchecked")
public <T> T callService(JAXBElement<?> jaxbRequest) {
jaxbRequest.getValue();
JAXBElement<T> jaxbResponse;
try {
jaxbResponse = (JAXBElement<T>) getWebServiceTemplate().marshalSendAndReceive(jaxbRequest);
} catch (WebServiceException e) {
e.printStackTrace();
throw e;
}
return jaxbResponse.getValue();
}
}
package-info looks like this
#javax.xml.bind.annotation.XmlSchema(namespace = "urn:ErpX")
package rs.sweetchoice.commonservice.generated;
Generated ObjectFactory snippet:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.3.0
// See https://javaee.github.io/jaxb-v2/
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2020.09.05 at 01:28:42 PM CEST
//
package rs.sweetchoice.commonservice.generated;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.namespace.QName;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the rs.sweetchoice.commonservice.generated package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
#XmlRegistry
public class ObjectFactory {
private final static QName _WSID_QNAME = new QName("urn:ErpX", "WSID");
private final static QName _AUTH_QNAME = new QName("urn:ErpX", "authStrct");
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: rs.sweetchoice.commonservice.generated
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {#link AutoCompleteStrct }
*
*/
public AutoCompleteStrct createAutoCompleteStrct() {
return new AutoCompleteStrct();
}
/**
* Create an instance of {#link KorpaStrct }
*
*/
public KorpaStrct createKorpaStrct() {
return new KorpaStrct();
}
/**
* Create an instance of {#link CmbStrct }
*
*/
public CmbStrct createCmbStrct() {
return new CmbStrct();
}
/**
* Create an instance of {#link AuthStrct }
*
*/
#XmlElementDecl(namespace = "urn:ErpX", name = "authStrct")
public JAXBElement<AuthStrct> createAuthStrct(AuthStrct value) {
return new JAXBElement<>(_AUTH_QNAME, AuthStrct.class, null, value);
}
/**
* Create an instance of {#link FilterStrct }
*
*/
public FilterStrct createFilterStrct() {
return new FilterStrct();
}
/**
* Create an instance of {#link ProfakStavStrct }
*
*/
public ProfakStavStrct createProfakStavStrct() {
return new ProfakStavStrct();
}
/**
* Create an instance of {#link ProfakStrct }
*
*/
public ProfakStrct createProfakStrct() {
return new ProfakStrct();
}
/**
* Create an instance of {#link RacunStavStrct }
*
*/
public RacunStavStrct createRacunStavStrct() {
return new RacunStavStrct();
}
/**
* Create an instance of {#link RacunStrct }
*
*/
public RacunStrct createRacunStrct() {
return new RacunStrct();
}
/**
* Create an instance of {#link UplKomitStrct }
*
*/
public UplKomitStrct createUplKomitStrct() {
return new UplKomitStrct();
}
/**
* Create an instance of {#link UplListaStavStrct }
*
*/
public UplListaStavStrct createUplListaStavStrct() {
return new UplListaStavStrct();
}
/**
* Create an instance of {#link UplListaStrct }
*
*/
public UplListaStrct createUplListaStrct() {
return new UplListaStrct();
}
/**
* Create an instance of {#link WsGetRoba }
*
*/
public WsGetRoba createWsGetRoba() {
return new WsGetRoba();
}
/**
* Create an instance of {#link WsGetKomit }
*
*/
public WsGetKomit createWsGetKomit() {
return new WsGetKomit();
}
/**
* Create an instance of {#link WsGetGrpRoba }
*
*/
public WsGetGrpRoba createWsGetGrpRoba() {
return new WsGetGrpRoba();
}
/**
* Create an instance of {#link WsGetGrpKomit }
*
*/
public WsGetGrpKomit createWsGetGrpKomit() {
return new WsGetGrpKomit();
}
/**
* Create an instance of {#link WsGetManuf }
*
*/
public WsGetManuf createWsGetManuf() {
return new WsGetManuf();
}
/**
* Create an instance of {#link WsUplProfak }
*
*/
public WsUplProfak createWsUplProfak() {
return new WsUplProfak();
}
/**
* Create an instance of {#link WsGetMagacin }
*
*/
public WsGetMagacin createWsGetMagacin() {
return new WsGetMagacin();
}
/**
* Create an instance of {#link WsGetAkcijskeCene }
*
*/
public WsGetAkcijskeCene createWsGetAkcijskeCene() {
return new WsGetAkcijskeCene();
}
/**
* Create an instance of {#link WsUplKomit }
*
*/
public WsUplKomit createWsUplKomit() {
return new WsUplKomit();
}
/**
* Create an instance of {#link WsUplKomitResponse }
*
*/
public WsUplKomitResponse createWsUplKomitResponse() {
return new WsUplKomitResponse();
}
/**
* Create an instance of {#link WsUplRacun }
*
*/
public WsUplRacun createWsUplRacun() {
return new WsUplRacun();
}
/**
* Create an instance of {#link JAXBElement }{#code <}{#link byte[]}{#code >}
*
* #param value
* Java instance representing xml element's value.
* #return
* the new instance of {#link JAXBElement }{#code <}{#link byte[]}{#code >}
*/
#XmlElementDecl(namespace = "urn:ErpX", name = "WSID")
#XmlJavaTypeAdapter(HexBinaryAdapter.class)
public JAXBElement<byte[]> createWSID(byte[] value) {
return new JAXBElement<byte[]>(_WSID_QNAME, byte[].class, null, ((byte[]) value));
}
}
And i get error
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault"). Expected elements are <{urn:ErpX}WSID>,<{urn:ErpX}authStrct>
Using java 11 and spring boot 2.3.3.
EDIT this is my config class
#Configuration
public class WsConfig {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("rs.sweetchoice.commonservice.generated");
return marshaller;
}
#Bean
public SoapServicesImpl soapServicesImpl(Jaxb2Marshaller marshaller) {
SoapServicesImpl client = new SoapServicesImpl();
client.setDefaultUri("https://tim-erp.com/ERPX_WEB/awws/ErpX.awws");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
Try to setCheckConnectionForFault to false on WebServiceTemplate. For example, replace the method:
public <T> T callService(JAXBElement<?> jaxbRequest) {
jaxbRequest.getValue();
JAXBElement<T> jaxbResponse;
try {
WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
webServiceTemplate.setCheckConnectionForFault(false);
jaxbResponse = (JAXBElement<T>) webServiceTemplate.marshalSendAndReceive(jaxbRequest);
} catch (WebServiceException e) {
e.printStackTrace();
throw e;
}
return jaxbResponse.getValue();
}
In my project, I have used as a code base the Lightbend activator template. It works perfect but the Actor in example is not created with parameters.
I need to create a new Actor and pass to it a parameter during construction such as :
getContext().actorOf(SpringExtProvider.get(actorSystem).props("ControllerActor",type), "controller_" + type)
In this use case, the controller needs to be able to be created with a props paremeter type which is used to typed (obviously) the controller. Each Actor is specifically design to handle and control a specific king of object depending on its type.
But I can't add a new parameter in the props method to pass this parameter. It is not working.
This is my code :
SpringExtension.java
package com.orange.spectre.core.akka.configuration;
import akka.actor.AbstractExtensionId;
import akka.actor.ExtendedActorSystem;
import akka.actor.Extension;
import akka.actor.Props;
import com.orange.spectre.core.config.SpringActorProducer;
import org.springframework.context.ApplicationContext;
/**
* Created by Hervé Darritchon on 04/04/2016.
* <p>
* An Akka Extension to provide access to Spring managed Actor Beans.
*/
public class SpringExtension extends AbstractExtensionId<SpringExtension.SpringExt> {
/**
* The identifier used to access the SpringExtension.
*/
public static SpringExtension SpringExtProvider = new SpringExtension();
/**
* Is used by Akka to instantiate the Extension identified by this
* ExtensionId, internal use only.
*/
#Override
public SpringExt createExtension(ExtendedActorSystem system) {
return new SpringExt();
}
/**
* The Extension implementation.
*/
public static class SpringExt implements Extension {
private volatile ApplicationContext applicationContext;
/**
* Used to initialize the Spring application context for the extension.
*
* #param applicationContext
*/
public void initialize(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* Create a Props for the specified actorBeanName using the
* SpringActorProducer class.
*
* #param actorBeanName The name of the actor bean to create Props for
* #return a Props that will create the named actor bean using Spring
*/
public Props props(String actorBeanName) {
return Props.create(SpringActorProducer.class,
applicationContext, actorBeanName);
}
public Props props(String actorBeanName, String type) {
return Props.create(SpringActorProducer.class,
applicationContext, actorBeanName,type);
}
}
}
SpringActorProducer
package com.orange.spectre.core.config;
import akka.actor.Actor;
import akka.actor.IndirectActorProducer;
import org.springframework.context.ApplicationContext;
/**
* Created by Hervé Darritchon on 21/03/2016.
*/
public class SpringActorProducer implements IndirectActorProducer {
private final ApplicationContext applicationContext;
private final String actorBeanName;
private final String type;
public SpringActorProducer(ApplicationContext applicationContext,
String actorBeanName) {
this.applicationContext = applicationContext;
this.actorBeanName = actorBeanName;
this.type = null;
}
public SpringActorProducer(ApplicationContext applicationContext,
String actorBeanName, String type) {
this.applicationContext = applicationContext;
this.actorBeanName = actorBeanName;
this.type = type;
}
#Override
public Actor produce() {
return (Actor) applicationContext.getBean(actorBeanName);
}
#Override
public Class<? extends Actor> actorClass() {
return (Class<? extends Actor>) applicationContext.getType(actorBeanName);
}
}
I can't create an actor with a props parameter as it is possible basically with Akka like (Documentation) :
public class DemoActor extends UntypedActor {
/**
* Create Props for an actor of this type.
* #param magicNumber The magic number to be passed to this actor’s constructor.
* #return a Props for creating this actor, which can then be further configured
* (e.g. calling `.withDispatcher()` on it)
*/
public static Props props(final int magicNumber) {
return Props.create(new Creator<DemoActor>() {
private static final long serialVersionUID = 1L;
#Override
public DemoActor create() throws Exception {
return new DemoActor(magicNumber);
}
});
}
final int magicNumber;
public DemoActor(int magicNumber) {
this.magicNumber = magicNumber;
}
#Override
public void onReceive(Object msg) {
// some behavior here
}
}
system.actorOf(DemoActor.props(42), "demo");
If you can help me, it should be great !
Thanks.
I'm agree with "nickebbitt". Not sure that it is spossible. And one of the way is to inject an implementation of magic number generator into the actor.
Furthermore, I wouldlike to suggest following IndirectActorProducer implementation:
public class SpringDIActor implements IndirectActorProducer {
private static final Logger LOG = LoggerFactory.getLogger(SpringDIActor.class);
private Class<? extends Actor> type;
private Actor actorInstance = null;
public SpringDIActor(Class<? extends Actor> type) {
this.type = type;
}
public SpringDIActor(Actor actorInstance) {
this.actorInstance = actorInstance;
}
/**
* This factory method must produce a fresh actor instance upon each
* invocation. <b>It is not permitted to return the same instance more than
* once.</b>
*/
#Override
public Actor produce() {
Actor newActor = actorInstance;
actorInstance = null;
if (newActor == null) {
try {
newActor = type.newInstance();
} catch (InstantiationException e) {
LOG.error("Unable to create actor of type:{}", type, e);
} catch (IllegalAccessException e) {
LOG.error("Unable to create actor of type:{}", type, e);
}
}
ApplicationContextProvider.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(newActor);
return newActor;
}
/**
* This method is used by [[Props]] to determine the type of actor which will
* be created. This means that an instance of this `IndirectActorProducer`
* will be created in order to call this method during any call to
* [[Props#actorClass]]; it should be noted that such calls may
* performed during actor set-up before the actual actor’s instantiation, and
* that the instance created for calling `actorClass` is not necessarily reused
* later to produce the actor.
*/
#Override
public Class<? extends Actor> actorClass() {
return type;
}}
This allows you co create actors without direct accesing to SpringContext from any code as follows:
ActorSystem.create("system").actorOf(Props.create(SpringDIActor.class, DemoActor.class))
Then just to use #Autowired annotation into the DemoActor.
No additional annotation on DemoActor is not required.
As per the startup instructions I was able to successfully generate table classes in JOOQ that end up looking like so:
public class AgencyMeta extends TableImpl<AgencyMetaRecord> {
private static final long serialVersionUID = 214852552;
/**
* The reference instance of <code>PUBLIC.AGENCY_META</code>
*/
public static final AgencyMeta AGENCY_META = new AgencyMeta();
/**
* The class holding records for this type
*/
#Override
public Class<AgencyMetaRecord> getRecordType() {
return AgencyMetaRecord.class;
}
/**
* The column <code>PUBLIC.AGENCY_META.ID</code>.
*/
public final TableField<AgencyMetaRecord, Long> ID = createField("ID", org.jooq.impl.SQLDataType.BIGINT.nullable(false).defaulted(true), this, "");
/**
* The column <code>PUBLIC.AGENCY_META.AGENCY_ID</code>.
*/
public final TableField<AgencyMetaRecord, Long> AGENCY_ID = createField("AGENCY_ID", org.jooq.impl.SQLDataType.BIGINT.nullable(false), this, "");
/**
* The column <code>PUBLIC.AGENCY_META.KEY</code>.
*/
public final TableField<AgencyMetaRecord, String> KEY = createField("KEY", org.jooq.impl.SQLDataType.VARCHAR.length(255).nullable(false), this, "");
/**
* The column <code>PUBLIC.AGENCY_META.VALUE</code>.
*/
public final TableField<AgencyMetaRecord, String> VALUE = createField("VALUE", org.jooq.impl.SQLDataType.CLOB, this, "");
/**
* Create a <code>PUBLIC.AGENCY_META</code> table reference
*/
public AgencyMeta() {
this("AGENCY_META", null);
}
/**
* Create an aliased <code>PUBLIC.AGENCY_META</code> table reference
*/
public AgencyMeta(String alias) {
this(alias, AGENCY_META);
}
private AgencyMeta(String alias, Table<AgencyMetaRecord> aliased) {
this(alias, aliased, null);
}
private AgencyMeta(String alias, Table<AgencyMetaRecord> aliased, Field<?>[] parameters) {
super(alias, Public.PUBLIC, aliased, parameters, "");
}
/**
* {#inheritDoc}
*/
#Override
public Identity<AgencyMetaRecord, Long> getIdentity() {
return Keys.IDENTITY_AGENCY_META;
}
/**
* {#inheritDoc}
*/
#Override
public UniqueKey<AgencyMetaRecord> getPrimaryKey() {
return Keys.CONSTRAINT_A0;
}
/**
* {#inheritDoc}
*/
#Override
public List<UniqueKey<AgencyMetaRecord>> getKeys() {
return Arrays.<UniqueKey<AgencyMetaRecord>>asList(Keys.CONSTRAINT_A0, Keys.CONSTRAINT_A0F);
}
/**
* {#inheritDoc}
*/
#Override
public List<ForeignKey<AgencyMetaRecord, ?>> getReferences() {
return Arrays.<ForeignKey<AgencyMetaRecord, ?>>asList(Keys.CONSTRAINT_A0FC);
}
/**
* {#inheritDoc}
*/
#Override
public AgencyMeta as(String alias) {
return new AgencyMeta(alias, this);
}
/**
* Rename this table
*/
public AgencyMeta rename(String name) {
return new AgencyMeta(name, null);
}
}
Apparently it has all the ingredients to create a table, and in part I can do so like this:
create.createTable(PRODUCT).column(PRODUCT.ID, SQLDataType.BIGINT.nullable(false).defaulted(true)).execute();
And so forth...
When the program starts up for the first time, I would like to build the h2 database on the spot.
Is there a way to create a table or even the whole database in a one-shot command? It would seem there should be based on what is provided.
As far as i know, there is only posibility to issue DDL commands manually, as described in documentation: ddl statements
The documentation describes that:
jOOQ's DDL support is currently still very limited. In the long run, jOOQ will support the most important statement types for frequent informal database migrations, though. Note that jOOQ will not aim to replace existing database migration frameworks. At Data Geekery, we usually recommend using Flyway for migrations. See also the tutorial about using jOOQ with Flyway for more information.
I have a question regarding static method access. I have a class within i have 4 static method. as shown in code:
package com.itrucking.util;
public class ZKUtil implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
* #author Shekhar
* #param _class
* #param listbox
* To make Listbox sorting enabled
* #throws NoSuchMethodException
* #throws SecurityException
*/
public static void setSortingEnabled(Class<?> _class, Listbox listbox){
Map<Listheader, String> sortingPair = new HashMap<Listheader, String>();
sortingPair = getMapForSorting(_class, listbox);
if (!sortingPair.isEmpty()) {
for (Map.Entry<Listheader, String> entry : sortingPair.entrySet()) {
entry.getKey().setSortAscending(
new FieldComparator(entry.getValue(), true));
entry.getKey().setSortDescending(
new FieldComparator(entry.getValue(), false));
}
}
}
/**
* #author Shekhar
* #param _class
* #param listbox
* #return Map<Listheader, String>
*/
private static Map<Listheader, String> getMapForSorting(Class<?> _class,Listbox listbox) {
List<Listheader> headerList = getListHeaderList(listbox);
Map<Listheader, String> sortingPair = new HashMap<Listheader, String>();
System.out.println(_class);
Field[] fields = _class.getDeclaredFields();
for (Field f : fields) {
// System.out.println(f.getName()+":"+f.getType());
for (Listheader lh : headerList) {
if (f.getName().equals(getId(lh)))
sortingPair.put(lh, f.getName());
}
}
System.out.println(sortingPair);
return sortingPair;
}
private static String getId(Listheader listheader) {
String listheaderId = null;
if (listheader.getId().contains("_")) {
listheaderId = listheader.getId().split("_")[1];
// System.out.println("listheaderId->"+listheaderId);
}
return listheaderId;
}
/**
* #author Shekhar
* #param listbox
* #return List<Listheader>
*/
#SuppressWarnings("unchecked")
private static List<Listheader> getListHeaderList(Listbox listbox) {
List<Listheader> headerList = new ArrayList<Listheader>();
Listhead listhead = null;
List<Component> listboxComponentList = listbox.getChildren();
for (Component listboxComponent : listboxComponentList) {
if (listboxComponent instanceof Listhead) {
listhead = (Listhead) listboxComponent;
break;
}
}
List<Component> listOfComp = listhead.getChildren();
if (listhead != null) {
for (Component c : listOfComp) {
if (c instanceof Listheader)
headerList.add((Listheader) c);
}
}
return headerList;
}
}
and i am calling setSortingEnabled() method from onLoadShipperDetailsListCtrl() from code bellow :
package com.itrucking.webui.controller;
public class ShipperDetailsListCtrl{
/**
* #param e
* #return void
*/
public void onCreate$window_shipperDetailsList(Event e){
onLoadShipperDetailsListCtrl();
}
/**
* #return void
*/
public void onLoadShipperDetailsListCtrl(){
System.out.println("onLoadShipperDetailsListCtrl called.");
shipperList = shipperService.getShipperList();
doRenderListboxShipperDetailsList(shipperList);
ZKUtil.setSortingEnabled(ShipperMaster.class, listbox_shipperDetailsList);
}
}
so what i think if i am calling setSortingEnabled() method from other class so i kept is as public and other method's i kept as private but it's giving me error as :
java.lang.NoSuchMethodError: com/itrucking/util/ZKUtil.getMapForSorting(Ljava/lang/Class;Lorg/zkoss/zul/Listbox;)Ljava/util/Map;
Why there is error NoSuchMethodError for ZKUtil.getMapForSorting() call in setSortingEnabled()
I know we can call private method from public in the same class. So i am not able to understand what is the problem.
Thanks in advance.
A NoSuchMethodError (the runtime error saying a method can't be found, instead of a compiler error) usually means that the .class files you're using are of a different version than the files you compiled against. In this case, you probably made changes to ZKUtil.java, but the JVM is loading an outdated version of ZKUtil.class. Clean and rebuild all of your .class files.