I have the following in my beans spring XML configuration file. here they are trying to get the password from a properties file run time and decrypt the password by calling the class "SpringPwdDecrypterUtil" which extends spring FactoryBean.
Question: in properties file where they mentioned with user and password. But the password is decrypted one which will be decrpted by the below configuration. I want to know how they(existing prod applicaiton) would have generated the password(decrpyted) and placed in the text file !
bean.xml
<property name="password">
<bean class="com.cname.SpringPwdDecrypterUtil">
<property name="password">
<value>${db.password}</value>
</property>
</bean>
</property>
--SpringPwdDecrypterUtil.java
package com.cname;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.FactoryBean;
public class SpringPwdDecrypterUtil
implements FactoryBean
{
private String password = null;
private String key = null;
public void setPassword(String password) {
this.password = password;
}
public void setKey(String key) {
this.key = key;
}
public Object getObject() {
if (StringUtils.isNotEmpty(this.key)) {
return CryptoUtils.decryptAndEncodeBase64(this.key, this.password);
}
return CryptoUtils.decryptAndEncodeBase64(this.password);
}
public Class getObjectType() {
return String.class;
}
public boolean isSingleton() {
return true;
}
}
Related
I'm in the process of upgrading the spring framework version used in our webapp from 3.1.4 to 4.1.8. With the new Spring version, A few of our unit tests are failing because #Autowired is no longer working. This is one of the failing tests:
#ContextConfiguration(locations={"/math-application-context.xml"})
public class MathematicaMathServiceTest extends JavaMathServiceTest{
#Autowired
private KernelLinkPool mathematicalKernelPool;
protected static String originalServiceType = System.getProperty("calculation.math.service.type");
#AfterClass
public static void unsetMathServiceType(){
System.clearProperty("calculation.math.service.type");
}
#BeforeClass
public static void setMathServiceType(){
System.setProperty("calculation.math.service.type","Mathematica");
}
#Test
public void testMathematicaService() throws Exception{
try {
acquireKernelAndExecute(0);
Assert.assertEquals(0, mathematicalKernelPool.getBorrowingThreadsCount());
} catch(UnsatisfiedLinkError e) {
System.out.println("Mathematica not installed. Skipping test");
}catch(Exception ex){
if (!ExceptionFormatter.hasCause(ex, MathServiceNotConfiguredException.class)){throw ex;}
if (System.getProperty(MathService.SERVICE_CONFIGURED_SYSTEM_VARIABLE) != null){
throw ex;
}
logger.error("Cannot execute test. Math service is not configured");
}
}
}
This is the KernelLinkPool class:
public class KernelLinkPool extends GenericObjectPool implements InitializingBean{
private static final int RETRY_TIMEOUT_MS = 5000;
private static final long STARTUP_WAIT_TIME_MS = 10000;
private boolean mathematicaConfigured = true;
private PoolableObjectFactory factory;
// ensures that multiple requests from the same thread will be given the same KernelLink object
private static ThreadLocal<KernelLink> threadBoundKernel = new ThreadLocal<KernelLink>();
// holds the number of requests issued on each thread
private static ThreadLocal<Integer> callDepth = new ThreadLocal<Integer>();
private long maxBorrowWait;
private Integer maxKernels;
private boolean releaseLicenseOnReturn;
private Logger logger = LoggerFactory.getLogger(this.getClass());
// (used only for unit testing at this point)
private Map<String,Integer> borrowingThreads = new ConcurrentHashMap<String,Integer>();
public KernelLinkPool(PoolableObjectFactory factory) {
super(factory);
this.factory = factory;
this.setMaxWait(maxBorrowWait);
}
#Override
public Object borrowObject() throws Exception{
return borrowObject(this.maxBorrowWait);
}
public Object borrowObject(long waitTime) throws Exception {
long starttime = System.currentTimeMillis();
if (!mathematicaConfigured){
throw new MathServiceNotConfiguredException();
}
try{
if (callDepth.get() == null){
callDepth.set(1);
}else{
callDepth.set(callDepth.get()+1);
}
KernelLink link = null;
if (threadBoundKernel.get() != null){
link = threadBoundKernel.get();
}else{
//obtain kernelLink from object pool
//retry when borrowObject fail until
//maxBorrowWait is reached
while(true){
try{
logger.debug("Borrowing MathKernel from object pool");
link = (KernelLink) super.borrowObject();
break;
}catch(KernelLinkCreationException ex){
long timeElapsed = System.currentTimeMillis() - starttime;
logger.info("Failed to borrow MathKernel. Time elapsed [" + timeElapsed + "] ms", ex);
if(timeElapsed >= waitTime){
logger.info("Retry timeout reached");
throw ex;
}
Thread.sleep(RETRY_TIMEOUT_MS);
}
}
logger.debug("borrowed [" + link + "]");
threadBoundKernel.set(link);
}
borrowingThreads.put(Thread.currentThread().getName(),callDepth.get());
return link;
}catch(Exception ex){
logger.error("Failed to acquire Mathematica kernel. Borrowing threads [" + borrowingThreads + "]");
throw ex;
}
}
public void returnObject(Object obj) throws Exception {
callDepth.set(callDepth.get()-1);
if (callDepth.get() <= 0){
threadBoundKernel.set(null);
borrowingThreads.remove(Thread.currentThread().getName());
if (releaseLicenseOnReturn){
// will destroy obj
super.invalidateObject(obj);
}
else{
// will park obj in the pool of idle objects
super.returnObject(obj);
}
}else{
borrowingThreads.put(Thread.currentThread().getName(),callDepth.get());
}
}
#Override
public void afterPropertiesSet() throws Exception {
try{
if (maxKernels == 0){
List<KernelLink> links = new ArrayList<KernelLink>();
while (true){
try{
links.add((KernelLink)factory.makeObject());
}catch(KernelLinkCreationException ex){
break;
}
}
if(links.isEmpty()){
logger.warn("No available Mathematica license!");
mathematicaConfigured = false;
return;
}
for (KernelLink link : links){
factory.destroyObject(link);
}
logger.info("Detected number of available Mathematica license = [" + links.size() + "]");
setMaxActive(links.size());
setMaxIdle(links.size());
}else{
if(maxKernels < 0){
logger.info("Set number of Mathematica license to no limit");
}else{
logger.info("Set number of Mathematica license to [" + maxKernels + "]");
}
setMaxActive(maxKernels);
setMaxIdle(maxKernels);
}
Object ob = borrowObject(STARTUP_WAIT_TIME_MS);
returnObject(ob);
mathematicaConfigured = true;
}catch(Throwable ex){
logger.warn("Mathematica kernel pool could not be configured: ", ex.getMessage());
mathematicaConfigured = false;
}
}
public int getBorrowingThreadsCount() {
return borrowingThreads.size();
}
public Integer getMaxKernels() {
return maxKernels;
}
public void setMaxKernels(Integer maxKernels) {
this.maxKernels = maxKernels;
}
public boolean isMathematicaConfigured(){
return mathematicaConfigured;
}
public boolean isReleaseLicenseOnReturn() {
return releaseLicenseOnReturn;
}
public void setReleaseLicenseOnReturn(boolean releaseLicenseOnReturn) {
this.releaseLicenseOnReturn = releaseLicenseOnReturn;
}
public long getMaxBorrowWait() {
return maxBorrowWait;
}
public void setMaxBorrowWait(long maxBorrowWait) {
this.maxBorrowWait = maxBorrowWait;
}
}
The tests are failing with this exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.etse.math.wolfram.KernelLinkPool] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
This is the math-application-context file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<beans profile="unitTest,integratedTest,activeServer">
<bean class="org.springframework.jmx.export.MBeanExporter"
lazy-init="false">
<property name="registrationBehaviorName" value="REGISTRATION_IGNORE_EXISTING" />
<property name="beans">
<map>
<entry key="etse.math:name=MathematicalKernelFactory"
value-ref="mathematicalKernelFactory" />
<entry key="etse.math:name=MathematicalKernelPool" value-ref="mathematicalKernelPool" />
</map>
</property>
</bean>
<bean id="mathService" class="com.etse.math.MathServiceFactoryBean">
<property name="mathServiceType" value="${calculation.math.service.type}"/>
<property name="mathematicaService" ref="mathematicaService"/>
</bean>
<bean id="mathematicaService" class="com.etse.math.wolfram.MathematicaService">
<property name="kernelPool" ref="mathematicalKernelPool" />
<property name="minParallelizationSize" value="${calculation.mathematica.kernel.parallel.batch.size}" />
</bean>
<bean id="mathematicalKernelPool" class="com.etse.math.wolfram.KernelLinkPool"
destroy-method="close">
<constructor-arg ref="mathematicalKernelFactory" />
<property name="maxKernels" value="${calculation.mathematica.max.kernels}" />
<property name="maxBorrowWait"
value="${calculation.mathematica.kernel.borrow.max.wait}" />
<property name="releaseLicenseOnReturn"
value="${calculation.mathematica.kernel.release.license.on.return}" />
</bean>
<bean id="mathematicalKernelFactory" class="com.etse.math.wolfram.KernelLinkFactory">
<property name="debugPackets" value="false" />
<property name="linkMode" value="launch" />
<property name="mathematicaKernelLocation" value="${calculation.mathematica.kernel.location}" />
<property name="mathematicaLibraryLocation" value="${calculation.mathematica.library.location}" />
<property name="mathematicaAddOnsDirectory" value="${calculation.mathematica.addons.directory}" />
<property name="linkProtocol" value="sharedMemory" />
</bean>
</beans>
<beans profile="passiveServer,thickClient,tools">
<bean id="mathService" class="com.etse.math.DummyMathService"/>
</beans>
I also tried using the application context to load the bean, but that failed with the following exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mathematicalKernelPool' is defined
If I remove the autowired field, the test fails with a NoSuchBeanDefinitionException for another bean (mathService) that is loaded via the application context in a super class. So it appears that the application context from math-application-context is not loaded for some reason. Any idea of what could be happening here? Thank you.
UPDATE:
I took a look at the beans defined in the application context and confirmed that none of the beans defined in math-application-context are present. The application context contains only beans defined in another context file loaded by the super class. Why would it fail to load math-application-context?
At this point I would honestly get rid of the XML config and go total annotation/code based. Create a Config class and have it create any beans you need to be autowired.
It was a profile issue. The super class to the test was using:
#ProfileValueSourceConfiguration(TestProfileValueSource.class)
to set the profile, but it was not working. After removing that annotation I added:
#ActiveProfiles(resolver=TestProfileValueSource.class) and now its working again.
The following managed operation exists in the project:
#ManagedOperation(description = "Some description")
#ManagedOperationParameters({
#ManagedOperationParameter(name = "key", description = "Some description"),
})
public void foo(String key) {
// some logic
}
Also there is a property which can be used in Spring context by surrounding it with dollar sign and square brackets:
"${some.property.key}"
Is it possible to use the value of aforementioned property key in the managed operation annotation description? Something like:
#ManagedOperationParameter(name = "key",
description = "Some description, please note that the key is ${some.property.key}")
Not out-of-the-box, but it's pretty easy to customize...
public class CustomAttributeSource extends AnnotationJmxAttributeSource implements EmbeddedValueResolverAware {
private StringValueResolver embeddedValueResolver;
#Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.embeddedValueResolver = resolver;
}
#Override
public ManagedAttribute getManagedAttribute(Method method) throws InvalidMetadataException {
ManagedAttribute managedAttribute = super.getManagedAttribute(method);
if (this.embeddedValueResolver != null) {
managedAttribute
.setDescription(this.embeddedValueResolver.resolveStringValue(managedAttribute.getDescription()));
}
return managedAttribute;
}
#Override
public ManagedOperation getManagedOperation(Method method) throws InvalidMetadataException {
ManagedOperation managedOperation = super.getManagedOperation(method);
if (this.embeddedValueResolver != null) {
managedOperation
.setDescription(this.embeddedValueResolver.resolveStringValue(managedOperation.getDescription()));
}
return managedOperation;
}
}
Then...
<bean class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter">
<property name="assembler">
<bean class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource">
<bean class="foo.CustomAttributeSource" />
</property>
</bean>
</property>
</bean>
I am trying to write some information about the user who opens the web application which i made. The web app is simple. When open it it shows users ip, user-agent, and the time of the last log into the app. I`ve made this app with these technologies: Spring, Maven, Tomcat, Hibernate and MySQL. It seems that everything is working correctly but when i open the app in browser in do note make a record to Data Base and i must start manually Main.java to make a record but the record is no correct because it does not record the real information but it record NULL everywhere. I have two questions - How to do all this automatically (when i open the web app to have a record in DB) and Why my records are every time NULL.
public class Main {
public static void main(String[] args) {
UserInfo user = new UserInfo();
user.setRollNo(7);
user.setIp(UserController.ip);
user.setUserAgent(UserController.userAgent);
user.setDate((Date) UserController.date);
SessionFactory sessionFactory = new AnnotationConfiguration()
.configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}
UserController.java
#Controller
public class UserController {
public static String ip;
public static String userAgent;
public static Date date;
#Autowired
private HttpServletRequest request;
#RequestMapping(value = "/connection")
public ModelAndView getUserInfo() {
ModelAndView modelandView = new ModelAndView("UserInfo");
ip = request.getRemoteAddr();
modelandView.addObject("msg1", "Your IP is " + ip);
userAgent = request.getHeader("User-Agent");
modelandView.addObject("msg2", "Your User agent is " + userAgent);
date = new java.util.Date();
/*
* Calendar calendar = Calendar.getInstance(); java.sql.Date startDate =
* new java.sql.Date(calendar.getTime() .getTime());
*/
modelandView.addObject("msg3", "Your last log was at " + date);
return modelandView;
}
}
UserInfo.java
#Entity
#Table(name = "USER_INFORMATION")
public class UserInfo {
#Id
private int rollNo;
private String ip;
private String userAgent;
private Date date;
public int getRollNo() {
return rollNo;
}
public void setRollNo(int rollNo) {
this.rollNo = rollNo;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/browserinfo</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<mapping class="com.nikola.hellocontroller.UserInfo" />
</session-factory>
</hibernate-configuration>
According to this:
#novy154 I am trying to make e record to DB with the users IP, user-agent info and the time when the user was lastloged in the app. After that i want to display all records in the app.
First of all, you need to have some DataAccessLayer. Something like
public interface UserInfoRepository {
void save(UserInfo userInfo);
Collection<UserInfo> findAll();
}
and it's implementation.
Then maybe some service over the Repository, but it doesn't matter in this case, so let's skip it.
You need to inject your repository into controller and:
1) invoke userInfoRepository.save(newlyCreatedUserInfo)
2) pass all UserInfos to your view (by invoking userInfoRepository.findAll() and putting the result in modelAndView) and display it somehow.
Let me know if you need help implementing this.
But this is just in purpose of learning how to make simple crud-like application, cause this doesn't make any sense. You can't even identify your user, you just want to track each visitor's ip, user info and so on.
// edit:
Repository implementation would be something like:
#Repository
#Transactional
public class UserInfoRepositoryImpl implements UserInfoRepository {
#Autowired
private SessionFactory sessionFactory;
#Override
public void save(UserInfo userInfo) {
getCurrentSession.save(userInfo);
}
#Override
public Collection<UserInfo> findAll() {
final Criteria root = getCurrentSession().createCriteria(UserInfo.class);
return Collections.checkedList(root.list(), UserInfo.class);
}
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
Then in your controller method you need to invoke save(newlyCreatedUserInfo) to store your info in the database and
modelAndView.addObject("userInfos", repository.findAll());
to retrieve all data and pass it to a view.
Of course remember about
...
#Autowired
private UserInfoRepository userInfoRepository;
...
in controller.
Note that since spring-data-jpa provides you more powerful repositories out of the box, this is reinventing a wheel.
I am doing an application in springs with maven. i wrote all properties in app.properties file
file structure is like this
src/main/resource
|_
| templates
| |_mytempaltefile.vm
|_ app.properties
i gave the path(absloute) in app.property
app.properties file
template.base.path=D\:/SVN/trunk/tfbdirect/src/main/resources/templates
utilities-spring.xml
<bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<props>
<prop key="resource.loader">file</prop>
<prop key="file.resource.loader.class">
org.apache.velocity.runtime.resource.loader.FileResourceLoader
</prop>
<prop key="file.resource.loader.path">${template.base.path}</prop>
<prop key="file.resource.loader.cache">false</prop>
</props>
</property>
</bean>
my class
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.ui.velocity.VelocityEngineUtils;
import com.providerpay.tfbdirect.service.mail.MailSenderService;
public class LoginServiceImpl implements ILoginService{
/**
* Injected through Spring IOC
*/
ILoginDAO loginDAO;
ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl;
PlatformTransactionManager txmanager;
//IForgotPasswordDAO forgotPasswordDAO;
private VelocityEngine velocityEngine;
private String appURL;
private MailSenderService mailSenderService;
TFBLogger log = TFBLoggerFactory.getLogger(RuleServer.class);
public String getAppURL() {
return appURL;
}
public void setAppURL(String appURL) {
this.appURL = appURL;
}
public MailSenderService getMailSenderService() {
return mailSenderService;
}
public VelocityEngine getVelocityEngine() {
return velocityEngine;
}
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
public void setMailSenderService(MailSenderService mailSenderService) {
this.mailSenderService = mailSenderService;
}
public ILoginDAO getLoginDAO() {
return loginDAO;
}
public void setLoginDAO(ILoginDAO loginDAO) {
this.loginDAO = loginDAO;
}
public ClaimRuleProcessServiceImpl getClaimRuleProcessServiceImpl() {
return claimRuleProcessServiceImpl;
}
public void setClaimRuleProcessServiceImpl(
ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl) {
this.claimRuleProcessServiceImpl = claimRuleProcessServiceImpl;
}
public void setTxmanager(PlatformTransactionManager txmanager) {
this.txmanager = txmanager;
}
/**
* Validates Login
* #param loginView
* #return
*/
public boolean isValidLogin(LoginView loginView) {
/* create tx definition object */
DefaultTransactionDefinition paramTransactionDefinition = new DefaultTransactionDefinition();
TransactionStatus status = txmanager.getTransaction(paramTransactionDefinition );
boolean result = false;
try{
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
Feedback feedback = claimRuleProcessServiceImpl.validateClaimEligibility(loginEntity);
log.info( "Rule executed was " +feedback.getAll());
for (FeedbackMessage feedbackmessaage :feedback.getAll())
{
log.info("\n--------------");
log.info(feedbackmessaage.getRuleCd());
log.info(feedbackmessaage.getMessage());
log.info(feedbackmessaage.getSeverity().getName());
log.info("\n--------------");
}
result = loginDAO.isValidLogin(loginEntity);
log.debug("result = {}", result);
txmanager.commit(status);
}catch(Exception e){
txmanager.rollback(status);
throw new TfbException("Error occured while validating login credentials");
}
return result;
}
#Autowired
VelocityEngine velocityengine;
public boolean mailResetLink(LoginView loginView) {
String toEmailAddress;
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
/* getting user Email from DAO*/
toEmailAddress = loginDAO.getEmailByUsername(loginEntity);
if(toEmailAddress != null && toEmailAddress.trim().length() > 0)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put("user", loginEntity);
model.put("appURL", appURL);
String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "emailTemplate.vm","UTF-8", model);
mailSenderService.sendMail("from mail", toEmailAddress, "Password Reset Link",body);
}
else
{
return false;
}
return true;
}
public boolean resetPassword(LoginView loginView)
{
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
return loginDAO.resetPassword(loginEntity);
}
}
every thing fine but i need to change the absolute path to relative path.. i tried many ways.
i tried like following
template.base.path=/templates/
but still getting below error .
ResourceManager : unable to find resource 'emailTemplate.vm' in any resource loader.
can any one help me..
Thanks in advance
You are falling into a common pitfall when using velocity with spring : you place your templates in one location and use a resource loader that searches them in another place. So you have 2 common usages :
put templates in classpath (as you do) and use ClasspathResourceLoader
resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
it is simple with little dependencies, but it forces you to put templates in classpath ...
put templates under WEB-INF (as you would do for JSPs) and use WebappResourceLoader from velocity tools
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path=/WEB-INF/velocity/
it is more natural for a template location, but you add a dependency on velocity tools.
And let spring manage dependencies but not instanciating via new ...
I had the same problem recently with karaf OSGi framework.
In a CXF resource class (Login in this context) you have to initialize the Velocity Engine like this:
public Login() {
/* first, get and initialize an engine */
ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
}
Then, in the web method, instantiate the template:
/* create a context and add data */
synchronized (initLock) {
if (loginTemplate == null) {
loginTemplate = ve.getTemplate("templates/login.vm");
}
}
VelocityContext context = new VelocityContext();
Unfortunately, it didn't work out to load the template immediately after the ve.init() call in the constructor.
Your configuration seems correct. If you instantiate the VelocityEngine instance using "new", try following:
#Autowired
VelocityEngine velocityEngine;
i cannot use any bean value in my custom control.:
for instance:
this is my foo.taglib.xml file.
<facelet-taglib>
<namespace>http://www.penguenyuvasi.org/tags</namespace>
<tag>
<tag-name>test</tag-name>
<component>
<component-type>test.Data</component-type>
</component>
</tag>
</facelet-taglib>
faces-config.xml
<component>
<component-type>test.Data</component-type>
<component-class>test.Data</component-class>
</component>
test.Data class
package test;
import java.io.IOException;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
public class Data extends UIComponentBase {
private Object msg;
#Override
public String getFamily() {
return "test.Data";
}
#Override
public void encodeBegin(FacesContext context) throws IOException {
super.encodeBegin(context);
context.getResponseWriter().write(msg.toString());
}
public void setMsg(Object msg) {
this.msg = msg;
}
}
Bean.java:
package test;
public class Bean {
private String temp = "vada";
public String getTemp() {
return temp;
}
}
test.xhtml (doesn't work)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://www.penguenyuvasi.org/tags">
<py:test msg="#{bean.temp}" />
</html>
test.xhtml (works)
<py:test msg="#{bean.temp}" />
In your test.Data class, I suggest that you implement the getter for msg like that:
public String getMsg() {
if (msg != null) {
return msg;
}
ValueBinding vb = getValueBinding("msg");
if (vb != null) {
return (String) vb.getValue(getFacesContext());
}
return null;
}
And then, in your encodeBegin method:
...
context.getResponseWriter().write(getMsg());
...
This getter method is needed in order to evaluate the expression you may give to the msg attribute in your JSF page.
Edit, to use ValueExpression instead of the deprecated ValueBinding:
ValueExpression ve = getValueExpression("msg");
if (ve != null) {
return (String) ve.getValue(getFacesContext().getELContext());
}