I am trying to pass reference of an interface as a property in a class (inheriting another class), I am getting an error. I tried same thing in a class which does not inherit anything and it works fine. I don't know if I am missing anything here. Any help is appreciated. Thanks :)
Class :
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.impl.ScheduledPollConsumer;
import com.walmart.utils.storeConfig.api.IStoreConfigService;
public class WalPipeConsumer extends ScheduledPollConsumer
{
final static private String CLASS_NAME = WalPipeConsumer.class.getName();
final static private Logger logger = Logger.getLogger(CLASS_NAME);
protected Hashtable pipeBuffers;
private Vector msgs = new Vector();
private int arrrayLength = 0, headerLength = 0;
private final Endpoint endpoint;
private final String pipe;
private IStoreConfigService storeConfigService;
public WalPipeConsumer(Endpoint endpoint, Processor processor, String pipe)
throws Exception
{
super(endpoint, processor);
logger.finest("inside the wal pipe consumer constructor");
this.pipe = pipe;
this.endpoint = endpoint;
this.countryCode = countryCode;
logger.finest("before starting the thread");
new Thread(new WalPipeInputRunner(), "WalCamel Pipe Consumer[" + pipe
+ "]").start();
logger.finest("after starting the thread");
}
// There are some more functions
/**
* #param storeConfigServicethe storeConfigService to set
*/
public void setStoreConfigService(IStoreConfigService storeConfigService) {
this.storeConfigService = storeConfigService;
}
Blueprint.xml:
<reference id="storeConfigService"
interface="com.walmart.utils.storeConfig.api.IStoreConfigService" />
<bean id="storeConfigAdapter" class="com.tgcs.walpipe.endpoint.StoreConfigAdapter" init-method="init">
<property name="storeConfigService" ref="storeConfigService" />
</bean>
<bean id="WalPipeConsumer" class="com.tgcs.walpipe.endpoint.WalPipeConsumer">
<property name="storeConfigService" ref="storeConfigService" />
</bean>
Error:
[2017.09.15-10:34:00.788] [SEVERE]
[org.apache.aries.blueprint.container.BlueprintContainerImpl]
[org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun] - Unable
to start blueprint container for bundle com.tgcs.walpipe.endpoint
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to
find a matching constructor on class
com.tgcs.walpipe.endpoint.WalPipeConsumer for arguments [] when
instanciating bean WalPipeConsumer
Blueprint tries to create an instance of WalPipeConsumer. You are using a property to set the storeConfigService. So blueprint will first call the empty Constructor to instantiate the class and then call the setter to set the storeConfigService.
As the class does not have an empty construtor this will fail.
To solve this you either need an empty constructor or use elements to set all parameters of the existing constructor.
Related
I'm developing an application that manages accounts. I made a Package named org.sid.entities where exists the IBanqueJob interface and below its code
package org.sid.metier;
import org.sid.entities.Compte;
import org.sid.entities.Operation;
import org.springframework.data.domain.Page;
public interface IBanqueMetier {
public Compte consulterCompte(String CodeCompte);
public void verser(String CodeCompte,double mt);
public void retirer(String CodeCompte, double mt);
public void virement(String Cp1, String Cp2, double mt);
public Page<Operation> listOperation(String cp,int page,int size);
}
and the implementation of this interface, below is its code
package org.sid.metier;
import java.util.Date;
import org.sid.dao.CompteRepository;
import org.sid.dao.OperationRepository;
import org.sid.entities.Compte;
import org.sid.entities.Operation;
import org.sid.entities.Versement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional
public class BanqueMetierImpl implements IBanqueMetier {
#Autowired
private CompteRepository compteRepository;
#Autowired
private OperationRepository operationRepository;
#Override
public Compte consulterCompte(String CodeCompte) {
Compte cp = compteRepository.findById(CodeCompte);
if (cp == null)
throw new RuntimeException("compte introuvable");
return cp;
}
i have an error in this line below that says "Type mismatch: cannot convert from Optional to Compte "
Compte cp = compteRepository.findById(CodeCompte);
findById returns an Optional of something, meaning that we either have a single result for a given id or we don't have anything for that.
In order to unpack this Optional, what I usually advise to do is the following:
Compte cp = compteRepository.findById(CodeCompte).orElseThrow(() -> new Exception("Element not found!");
This will throw an exception in case we don't find anything for that specific id.
In some cases is more beneficial to return some default value instead of throwing an exception. In this case we can use this:
Compte cp = compteRepository.findById(CodeCompte).orElse(new Compte());
or with a supplier:
Compte cp = compteRepository.findById(CodeCompte).orElseGet(() -> new Compte());
compteRepository.findById returns an Optional as it implements probably the CrudRepository Interface.
So please use
Optional<Compte> cp = compteRepository.findById(CodeCompte);
I have a list of objects with common base class. I wish to serialize (and deserialize) this list so that each list element is serialized with its root element equal to the name of the type and not have the wrapping object around the element.
I tried using JsonTypeInfo with Id.Name and As.WRAPPER_OBJECT which produces an XML with proper element names but (obviously) with another layer of XML elements (from the list itself).
package zm.study.xmlserialize.jackson;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
public class JacksonListTest4 {
public static class L {
public List<A> as = new ArrayList<>();
}
#JsonTypeInfo(use = Id.NAME, include=As.WRAPPER_OBJECT)
#JsonSubTypes({
#JsonSubTypes.Type(value=B.class, name="b"),
#JsonSubTypes.Type(value=C.class, name="c"),
})
public static abstract class A {
}
public static class B extends A {
}
public static class C extends A {
}
#Test
public void test() throws Exception
{
L l = new L();
l.as.add(new B());
l.as.add(new C());
new XmlMapper().enable(SerializationFeature.INDENT_OUTPUT)
.writeValue(System.out, l);
}
}
I would like to get:
<L>
<as>
<b/>
<c/>
</as>
</L>
Instead I get:
<L>
<as>
<as>
<b/>
</as>
<as>
<c/>
</as>
</as>
</L>
If you know what you want it to look like you're better off writing an XSD and then using a tool like JAXB to create a serialization/deserialization Java object.
I want to declare and instantiate a HashMap in one go in JCodeModel.
I do:
jc.field(JMod.PRIVATE, HashMap.class, "initAttributes");
which declares it but doesn't instantiate it. How do I instantiate it?
Thanks
In the simplest case, you can just append the initialization directly to your creation of the field:
jc.field(JMod.PRIVATE, HashMap.class, "initAttributes")
.init(JExpr._new(codeModel.ref(HashMap.class)));
Some further hints:
Considering that you should usually program to an interface, it is a good practice to declare the variable using a type that is "as basic as possible". You should hardly ever declare a variable as
private HashMap map;
but basically always only as
private Map map;
because Map is the interface that is relevant here.
You can also add generics in JCodeModel. These usually involve some calls to narrow on certain types. It is a bit more effort, but it will generate code that can be compiled without causing warnings due to the raw types.
An example is shown here. (It uses String as the key type and Integer as the value type of the map. You may adjust this accordingly)
import java.util.HashMap;
import java.util.Map;
import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JMod;
import com.sun.codemodel.writer.SingleStreamCodeWriter;
public class InitializeFieldInCodeModel
{
public static void main(String[] args) throws Exception
{
JCodeModel codeModel = new JCodeModel();
JDefinedClass definedClass = codeModel._class("com.example.Example");
JClass keyType = codeModel.ref(String.class);
JClass valueType = codeModel.ref(Integer.class);
JClass mapClass =
codeModel.ref(Map.class).narrow(keyType, valueType);
JClass hashMapClass =
codeModel.ref(HashMap.class).narrow(keyType, valueType);
definedClass.field(JMod.PRIVATE, mapClass, "initAttributes")
.init(JExpr._new(hashMapClass));
CodeWriter codeWriter = new SingleStreamCodeWriter(System.out);
codeModel.build(codeWriter);
}
}
The generated class looks as follows:
package com.example;
import java.util.HashMap;
import java.util.Map;
public class Example {
private Map<String, Integer> initAttributes = new HashMap<String, Integer>();
}
Here is my requirement in Java 6: I am using Eclipse JUNO.
Annotate a method with a custom annotation.
During compilation, raise warning message if a method is calling the
annotated method.
I am looking for something like #Deprecated annotation.
This is what I have done:
Wrote a custom annotation.
Wrote an annotation processor to read and process the methods with
the annotation.
Created a jar and added it in annotation processor path. My sample code (see below) raises the warning message in the annotated method. But it is not my requirement.
What I couldn’t do:
I could not get the calling methods. I want to raise the warning
message in those calling methods.
My sample code:
Custom annotation:
package tool.apichecks;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.SOURCE)
#Target({ ElementType.METHOD })
public #interface HighCostMethod {
String altMethod();
}
Annotation Processor:
package tool.apichecks;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
#SupportedAnnotationTypes({ "tool.apichecks.HighCostMethod" })
public class MethodProcessor extends AbstractProcessor {
private enum MethodType {
HIGH_COST(HighCostMethod.class.getName());
private String name;
private MethodType(String name) {
this.name = name;
}
private static MethodType getMethodType(String name) {
MethodType methodType = null;
for (MethodType methodType2 : MethodType.values()) {
if (methodType2.name.equals(name)) {
methodType = methodType2;
break;
}
}
return methodType;
}
}
private ProcessingEnvironment processingEnvironment;
#Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
this.processingEnvironment = processingEnvironment;
}
#Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnvironment) {
if (!roundEnvironment.processingOver()) {
for (TypeElement annotation : annotations) {
final Set<? extends Element> elements = roundEnvironment
.getElementsAnnotatedWith(annotation);
MethodType methodType = MethodType.getMethodType(annotation
.toString());
for (Element element : elements) {
switch (methodType) {
case HIGH_COST: {
processHighCostMethod(element);
break;
}
}
}
}
}
return true;
}
protected void processHighCostMethod(Element element) {
HighCostMethod highCostMethod = element
.getAnnotation(HighCostMethod.class);
/* TODO This warns the annotated method itself. I don't want this. I want to warn the methods that calls this method */
processingEnvironment
.getMessager()
.printMessage(
Kind.WARNING,
String.format(
"Do not use high cost method %s. Instead use %s method.",
element, highCostMethod.altMethod()), element);
}
}
Using an AnnotationProcessor will only work on the files containing the annotations or overriding methods, but not calling methods. Maybe there's a way around this, but then you will probably be limited by projects, because the processor only looks at one project at a time.
I guess you need to write an Eclipse plugin with a builder, that analyses code in all files and checks called methods for annotations.
That a lot more work than an annotation processor, but you also have more options. E.g. you could implement a quick fix for the error markers.
I'm trying to intercept any call to getConnection() method to setup the dbms indentifier . I've implemented an aspect to get it but I don't get anything. Any idea? Thanks!
import java.sql.CallableStatement;
import java.sql.Connection;
import javax.servlet.http.HttpSession;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import es.iberia.tryp.model.entities.Usuario;
#Component
#Aspect
public class ConnectionAspect {
#AfterReturning(value = "execution(java.sql.Connection javax.sql.DataSource+.getConnection(..))", returning = "connection")
//#AfterReturning(value = "execution(java.sql.Connection org.springframework.jdbc.datasource.*.*(*))", returning = "connection")
//#AfterReturning(value = "execution(java.sql.Connection java.sql.Connection *(..))", returning = "connection")
//#AfterReturning(value = "execution(java.sql.Connection org.springframework.jdbc.datasource.DriverManagerDataSource.*(..))", returning = "connection")
public void prepare (Connection connection) throws Throwable {
HttpSession httpSession = (HttpSession) RequestContextHolder.currentRequestAttributes().resolveReference(RequestAttributes.REFERENCE_SESSION);
if (httpSession!=null && (Usuario)httpSession.getAttribute("usuario")!=null && ((String)((Usuario)httpSession.getAttribute("usuario")).getNomina())!=null) {
String nomina = (String)((Usuario)httpSession.getAttribute("usuario")).getNomina();
String prepSql = "{ call DBMS_SESSION.SET_IDENTIFIER('" + nomina +"') }";
CallableStatement cs = connection.prepareCall(prepSql);
cs.execute();
cs.close();
}
}
}
Check whether you have added the below tag in your xml file.
aop:aspectj-autoproxy
Also check whether you have added the bean definition inside the xml for this ConnectionAspect class.
Yes, I have an idea: Actually your pointcuts match the desired calls, but they are in the java package which (like the javax package) is excluded from weaving by default.
There is a way to remove that restriction via command line and aop.xml, but please be aware of potential problems concerning classloading. You have to make sure the classloader loading the java classes has a weaver attached, so if you have the option not to use LTW, just weave the JDK class files and use those woven classes, and you will be fine. Otherwise you might have a "hen and egg" problem.