Liferay Serivce Builder: Not able to run dynamic query - liferay

I have two plugin portlets. First has service builder with all entities. Second portlet is using service's jar file to execute Dynamic query.
I am using first's service jar in my second plugin portlet to interact with database. But in this jar file there is not any Impl class. Thats why i am getting error Impl Class not found.
Below is for reference:
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(XXX.class,
PortletClassLoaderUtil.getClassLoader());
try {
XXXLocalServiceUtil.dynamicQuery(dynamicQuery);
} catch (SystemException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Error:
[DynamicQueryFactoryImpl:96] Unable find model com.compass.model.impl.XXXImpl
java.lang.ClassNotFoundException: com.compass.model.impl.XXXImpl
Nomal Functions are working fine of service builder

just don't use the DynamicQueryFactoryUtil but the XXXLocalServiceUtil this way
DynamicQuery dynamicQuery = XXXLocalServiceUtil.dynamicQuery()
try {
XXXLocalServiceUtil.dynamicQuery(dynamicQuery);
} catch (SystemException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
If you want to use the factory you have to use the interface model not the impl of the entity so if you have an entity FooImpl sue the Foo.class and use the classloder of you service plugin portlet
Classloader cl =(ClassLoader) PortletBeanLocatorUtil.locate("services-portlet", "portletClassLoader");
DynamicQueryFactoryUtil.forClass(XXX.class, cl);

Both works for me..
ClassLoader classLoader = (ClassLoader)PortletBeanLocatorUtil.locate(ClpSerializer.getServletContextName(), "portletClassLoader");
OR
ClassLoader classLoader = PortletBeanLocatorUtil.getBeanLocator(ClpSerializer.getServletContextName()).getClassLoader();
DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(charges.class,classLoader);
Thanks #Romeo.

public static void getuserList(){
DynamicQuery dynamicQuery = XXLocalServiceUtil.dynamicQuery();
System.out.println("dynamicQuery");
dynamicQuery.add(PropertyFactoryUtil.forName("field1").eq("field_name"));
List<XX> userList = XXLocalServiceUtil.dynamicQuery(dynamicQuery);
System.out.println(userList);
}
This is working for me !!!!

Related

How to multi-thread parsing of JMS messages

In my Spring Boot project, I have two JMS listeners listening to one queue. All messages received from the queue have to be processed in the same way and persisted / updated in the database (Oracle). Currently, I have a synchronized method in a class that is doing the parsing of the messages. As expected, all thread read messages simultaneously, but parsing is done one by one as the method (parseMessage()) is synchronized. What I want is to parse the messages simultaneously and do database operations as well.
How can I solve this?
I don't want to create two different classes with the same code and use #Qualifier to call different classes in each listener, as the code for parsing the message is the same.
The ideal solution, I think, is to do database operations using a new synchronized method in a new class, but parsing the message in a multi-threaded way. So, at a time only one thread can say persist / update. When a thread is not waiting to persist / update, it continues the parsing on its own thread.
Please correct me if I am wrong or if you find the optimal solution. Let me know if any other info is needed.
JMS Controller Class
#RestController
#EnableJms
public class JMSController {
#Autowired
private IParseMapXml iParseMapXml;
#JmsListener(destination = "${app.jms_destinaltion}")
public void receiveMessage1(String recvMsg) {
try {
InputSource is = new InputSource(new StringReader(recvMsg.replaceAll("&", "&amp")));
Document doc = new SAXReader().read(is);
iParseMapXml.parseMessage(doc);
} catch (Exception e) {
}
}
#JmsListener(destination = "${app.jms_destinaltion}")
public void receiveMessage2(String recvMsg) {
try {
InputSource is = new InputSource(new StringReader(recvMsg.replaceAll("&", "&amp")));
Document doc = new SAXReader().read(is);
iParseMapXml.parseMessage(doc);
} catch (Exception e) {
}
}
}
Parse XML Interface
public interface IParseMapXml {
public void parseMessage(Document doc);
}
Parsing Implementation
public class ParsingMessageClass implements IParseMapXml{
#Override
#Transactional
synchronized public void parseMessage(Document doc) {
// TODO Auto-generated method stub
....
PROCESS DATA/MESSAGE
....
DO DB OPERATIONS
}
}

Throw Exception in ModelListener Liferay

Hello Liferay Experts,
I have a requirement where I need to stop an Admin from assigning a role, I am trying to implement this with a ModelListener.
Here is the code..
#Component(immediate = true, service = ModelListener.class)
public class TestUserModelListener extends BaseModelListener<User> {
#Override
public void onBeforeAddAssociation(Object classPK, String associationClassName, Objext accociationClassPK) throws ModelListenerException {
// ...
throw new ModelListenerException("User creation not allowed");
}
}
When this code executes, the exception is thrown but the UI doesnt handle it correctly, the control panel Menus are not displayed and the exception message is not displayed to the user.
How to throw an exception and handle it correctly in UI and display error message to the user.
Thanks
M
Andre Albert already gave you the correct hints in the comments.
You should keep the ModelListener and override the ActionCommand additionally.
First, read the tutorial about Overriding MVC Comands. When implementing your custom Command, use Liferay's implemenation as basis (don't forget to add the higher service.ranking) and replace the catch block with something like this:
// I took the freedom and refactored Liferay's catch block a little bit
catch (NoSuchUserException | PrincipalException e) {
SessionErrors.add(actionRequest, e.getClass());
actionResponse.setRenderParameter("mvcPath", "/error.jsp");
} catch (MembershipPolicyException e) {
SessionErrors.add(actionRequest, e.getClass(), e);
actionResponse.setRenderParameter("mvcPath", "/edit_user.jsp");
actionResponse.setRenderParameter("screenNavigationCategoryKey", UserFormConstants.CATEGORY_KEY_GENERAL);
actionResponse.setRenderParameter("screenNavigationEntryKey", UserFormConstants.ENTRY_KEY_ROLES);
} catch (ForbiddenRoleAssociationException e) {
// Here you can add a SessionError
// and set some render parameters
} catch (Exception e) {
throw e;
}
The ForbiddenRoleAssociationException does not exist yet. It's purpose is to distinguish this special case of a ModelListenerException from others which might not interest you. You'll have to implement it yourself. Just extend the ModelListenerException:
public class ForbiddenRoleAssociationException extends ModelListenerException {
// here might be some constructors
}
Now adjust your ModelListener so that it throws your new ForbiddenRoeAssociationException:
#Component(immediate = true, service = ModelListener.class)
public class TestUserModelListener extends BaseModelListener<User> {
#Override
public void onBeforeAddAssociation(Object classPK, String associationClassName, Objext accociationClassPK) throws ModelListenerException {
// ...
throw new ForbiddenRoleAssociationException(); // or any other constructor
}
}
This way you should be able to display error messages to admins (depending on your code in the catch block of the ForbiddenRoleAssociationException) and circumvent any other (programmatic) attempt to assign the Role as well.

Handling service layer exception in Java EE frontend method

I maintain a web application that have a page with the JSF tag <f:event. I have rewrote a method in a service class for it to throw a business exception. However, when the business exception is thrown, it isn't caught in managed bean and the exception is showed on the page. Seems that my code try/catch doesn't work.
In XHTML:
<f:event listener="#{resourceBean.init(enrollment)}" type="preRenderView" />
Listener method in Managed Bean:
private boolean canCreateResource;
public void init(Enrollment enrollment) {
(...)
try {
canCreateResource = resourceService.canCreateResource(enrollment);
} catch (BusinessException e) {
canCreateResource = false;
}
}
Method in service class:
public boolean canCreateResource(Enrollment enrollment) {
if (...) {
if (mandateService.isCoordinator(user, course)) {
return true;
} else {
throw new BusinessException("Undefined business rule.");
}
}
return false;
}
From what I read on other sites, I suppose I have to implement some JSF's handler class. But which and how?
EDITED
OBS 1: The BusinessException class extends RuntimeException class.
OBS 2: The attribute canCreateResource was created to control the render of a button.
It's because you threw a RuntimeException from an EJB.
When such RuntimeException is not annotated with #ApplicationException, then the EJB container will wrap it in an javax.ejb.EJBException and rethrow it. This is done so because runtime exceptions are usually only used to indicate bugs in code logic, i.e. programmer's mistakes and not enduser's mistakes. You know, NullPointerException, IllegalArgumentException, IndexOutOfBoundsException, NumberFormatException and friends. This allows the EJB client to have one catch-all point for such runtime exceptions, like catch (EJBException e) { There's a bug in the service layer or in the way how we are using it! }
If you had tried catch (Exception e) and inspected the actual exception, then you'd have noticed that.
Fix your BusinessException class accordingly to add that annotation, it will then be recognized as a real application exception and not be wrapped in an EJBException:
#ApplicationException(rollback=true)
public class BusinessException extends RuntimeException {
// ...
}
Do note that in case you throw an non-RuntimeException, then you still need to keep the annotation on that, explicitly with rollback=true, because by default it wouldn't perform a rollback, on the contrary to a RuntimeException without the annotation.
#ApplicationException(rollback=true)
public class BusinessException extends Exception {
// ...
}
Summarized:
RuntimeException thrown from transactional EJB method will perform full rollback, but exception will be wrapped in EJBException.
RuntimeException with #ApplicationException from transactional EJB method will only perform full rollback when rollback=true is explicitly set.
Exception from transactional EJB method will not perform full rollback.
Exception with #ApplicationException from transactional EJB method will only perform full rollback when rollback=true is explicitly set.
Note that #ApplicationException is inherited over all subclasses of the custom exception, so you don't need to repeat it over all of them. Best would be to have it as an abstract class. See also the examples in the related question linked below.
See also:
Letting the presentation layer (JSF) handle business exceptions from service layer (EJB)
If isCoordinator method can eventually throw an exception you should add a try catch block inside canCreateResource method. You can throw your own exception or propagate the original one. In both cases you have to declare it in the method signature. If you throw BusinessException:
public void canCreateResource(Enrollment enrollment) throws BusinessException
Do not return any value. Or return a boolean value but do not throw any exception.
In the catch block inside the init method add the Facelet message exception:
...
} catch (BusinessException e) {
this.canCreateResource = false;
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), ""));
}
}
Also in your page you have to add <h:messages> tag.
In case you want to catch an exception that you did not create yourself (and you are not able to annotate with #ApplicationException), you can catch all exceptions and see if one of the causes is of the type you want to catch.
You can check the causes of the exception recursively:
public static <T extends Throwable> T getCauseOfType(final Throwable throwable,
final Class<T> type) {
if (throwable == null) {
return null;
}
return type.isInstance(throwable) ? (T) throwable : getCauseOfType(throwable.getCause(), type);
}
public static <T extends Throwable> boolean hasCauseOfType(final Throwable throwable,
final Class<T> type) {
return getCauseOfType(throwable, type) != null;
}
You can use this like:
try {
...
}
catch (Exception e) {
if (hasCauseOfType(e, SomeException.class)) {
// Special handling
}
else {
throw e;
}
}

Cobertura, how to coverage catch-clause which will never occur

i have the ambitious goal to get 100% test coverage in cobertura. How can i achieve this on this code? There will never be an exception because the file is on the classpath. Can i remove files fropm classpath with junit?
try {
InputStreamReader reader = new InputStreamReader(WsdlSource.class.getClassLoader().getResourceAsStream("stringresources/stringresources.properties"), "UTF-8");
try {
p.load(reader);
} finally {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
First of all, to be able to test things right you have to learn what what loose coupling is and what Mock Objects are.
Basically, it is never a good idea to create an object with new because you create a hard dependency between the class InputStreamReader and your logic.
If your object p implements some kind of an interface, it would be good if you pass the instance of it from outside of your logic. Some implementations of Mock Objects also allow you to mock a class but I would not recommend that.
For example if you write your code like that:
public myMethod(SomeKindOfInterface p, InputStreamReader reader) {
try {
p.load(reader);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch(IOException e) {
//intentionally left blank, nothing could be done upon exception on closing
}
}
}
Then in your JUnit you could use Mockito to mock the IOException.
InputStreamReader reader = new InputStreamReader(WsdlSource.class.getClassLoader().getResourceAsStream("stringresources/stringresources.properties"), "UTF-8");
SomeKindOfInterface mock = Mockito.mock(SomeKindOfInterface.class);
Mockito.when(mock.load(reader)).thenThrow(new IOException());
myInstance.myMethod(mock, reader);
This way you would have your catch block covered.

jsf 2.2 get the path for a propertie file

i want to read out from a propertie file in my jsf 2.2 project. i use eclipse kepler.
i try to use this in my java-bean in the folder src with the package de.exanple. The file of the bean is called PageServiceBean.java.
The propertie file is in the WEB-INF/resources/prop folder. The propertie file is called config.properties.
I have read that i can change the resouce folder in jsf 2.2 in the web.xml file with the javax.faces.WEBAPP_RESOUCRES_DIRECTORY param name and the param value like /WEB_INF/resoucres
But i don't get the path to the config file.
Can you tell where i can get the path name. I think i must use a relativ path name.
Can you please help me?
Update
I execute the second code fragment from you like:
private Properties getProperties() {
Properties prop = new Properties();
try {
//load a properties file
prop.load(new FileInputStream("config2.properties"));
} catch(Exception e) {
}
return prop;
}
public void setProperty1(Integer value) {
Properties prop = getProperties();
prop.setProperty("ort", value.toString());
try {
prop.store(new FileOutputStream("config2.properties"), null);
Properties prop2 = getProperties();
} catch (IOException ex) {
Logger.getLogger(PageServiceBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
It works! I use the Properties prop3 = getProperties(); to read the the propertie file config2.properties. The File is Store in the eclipse home path ECLIPSE_HOME = C:\elipse_jee\eclipse. Can i change the path into a specific path, like WEB_INF/resources?
I will show you my approach to your need, but I won't try to answer your question.
To use properties files in a JEE application I create a Stateless bean that serves the rest of the application with the getter and setter for the properties. Only this EJB will access the property file in the server and I use the java.util.Properties.
private Properties getProperties() {
Properties prop = new Properties();
try {
//load a properties file
prop.load(new FileInputStream("config.properties"));
} catch(Exception e) {
}
return prop;
}
After I have the access methods for a specifc property:
public Integer getProperty1() {
Properties prop = getProperties();
String value = prop.getProperty("myProperty1Name");
if(value != null) {
return Integer.parseInt(value );
}
return 0;
}
public void setProperty1(Integer value) {
Properties prop = getProperties();
prop.setProperty("myProperty1Name", value.toString());
try {
prop.store(new FileOutputStream("config.properties"), null);
} catch (IOException ex) {
Logger.getLogger(PropertiesManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
In this approach, if the file doesn't exist it will be created. The default value of a property will be hard coded though. For this approach, it doesn't matter where your file is placed. The actual location will depend on your JEE server configuration, domain configuration, application deployment files, etc.
Web content resources are available by ServletContext#getResourceAsStream() and its JSF delegator ExternalContext#getResourceAsStream(). So, this should do:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
prop.load(ec.getResourceAsStream("/WEB-INF/resources/prop/config2.properties"));
See also:
Where to place and how to read configuration resource files in servlet based application?

Resources