Deploying OLD EJBs to Weblogic 12. Desactivate EJB Checker - deployment

I´m in trouble with old EJBs that i have no control over the source code, there is no source code, only the ejb jar. They were born in weblogic 5.
We are migrating to weblogic 12c and When i deploy then, the EJB checker give me some compliance ejb errors.
I have been investigating the class ...
[Loaded weblogic.ejb.container.compliance.EJBComplianceChecker from ......product/Oracle_Home/wlserver/modules/com.oracle.weblogic.ejb.jar]
Decompiled and I have found this ....
public final class EJBComplianceChecker
extends BaseComplianceChecker
implements ComplianceChecker, PlatformConstants
{
public static final boolean isNeedCheck = Boolean.getBoolean("ignoreEJBChecker");
static final ComplianceChecker INSTANCE = new EJBComplianceChecker();
public void checkDeploymentInfo(DeploymentInfo di)
throws ErrorCollectionException
{
if (isNeedCheck) {
return;
}
Set<Class<?>> deploymentInfoCheckers = new HashSet();
Object interceptorChecker = null;
Object[] relationshipCheckers = null;
for (BeanInfo bi : di.getBeanInfos()) ....
I think this might be some kind of deployment configuration, but i have found no information about it...
public static final boolean isNeedCheck = Boolean.getBoolean("ignoreEJBChecker");
it controls the value and let it check or not.
if (isNeedCheck) {
return;
}
thanks

that seems to work. Know i can not see the error.
Thank for all Emmanuel

Related

Run method after deploying and save the result with to database

I have started a Quarkus project and i have there 2 tables, i am trying to run a Method immediately after deploying, In the method i use Entitymanger to save some results in the database.
In pure Jakarta EE, you could an EJB and annotate it with #Startup. But Since quarkus uses CDI.
#ApplicationScoped
public class StartApp {
private static final String PERSISTENCE_UNIT_NAME = "Employee";
public void init(#Observes #Initialized(ApplicationScoped.class) Object init) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
Directory directory = new Directory("/some/info", true, false, ".xml");
em.persist(directory);
em.close();
}
}
How can i do that!? some guess !
I think what you need is this:
#ApplicationScoped
class StartApp {
void startup(#Observes StartupEvent event) {
// Do whatever needs to be done.
}
}
More information and options can be found on the very well documented quarkus pages. https://quarkus.io/guides/cdi-reference#startup-event
Ps. don't forget about your transactions and maybe take a look at Hibernate ORM.

#Inject not working in AttributeConverter

I have a simple AttributeConverter implementation in which I try to inject an object which have to provide the conversion logic, but #Inject seem not to work for this case. The converter class looks like this:
#Converter(autoApply=false)
public class String2ByteArrayConverter implements AttributeConverter<String, byte[]>
{
#Inject
private Crypto crypto;
#Override
public byte[] convertToDatabaseColumn(String usrReadable)
{
return crypto.pg_encrypt(usrReadable);
}
#Override
public String convertToEntityAttribute(byte[] dbType)
{
return crypto.pg_decrypt(dbType);
}
}
When the #Converter is triggered it throws an NullPointerException because the property crypto is not being initialized from the container. Why is that?
I'm using Glassfish 4 and in all other cases #Inject works just fine.
Is it not possible to use CDI on converters?
Any help will be appreciated :)
The accent of my question is more the AttributeConverter part. I understand that for the CDI to work a bean must meet the conditions described here http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html.
I also have tried to force the CDI to work by implementing the following constructor:
#Inject
public String2ByteArrayConverter(Crypto crypto)
{
this.crypto = crypto;
}
And now I got the following exception which doesn't give me any clue:
2015-07-23T01:03:24.835+0200|Severe: Exception during life cycle processing
org.glassfish.deployment.common.DeploymentException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [PU_VMA] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-7172] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered when instantiating the class [class model.converter.String2ByteArrayConverter].
Internal Exception: java.lang.InstantiationException: model.converter.String2ByteArrayConverter
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createDeployFailedPersistenceException(EntityManagerSetupImpl.java:820)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:760)
...
I even tried using #Producer or #Decorator in order to have the CDI working on that place, but I still think there is something specific with the AttributeConverter which doesn't allow CDI. So problem not solved yet.
Unfortunately you can't inject CDI beans into a JPA converter, however in CDI 1.1 you can inject your Crypto programmatically :
Crypto crypto = javax.enterprise.inject.spi.CDI.current().select(Crypto.class).get()
For reference, JPA 2.2 will allow CDI to be used with AttributeConverter, and some vendors already support this (EclipseLink, DataNucleus JPA are the ones I know of that do it).
You're trying to combine two different worlds, as CDI doesn't know about JPA Stuff and vice-versa. (One annotation parser of course doesn't know about the other)
What you CAN do, is this:
/**
* #author Jakob Galbavy <code>jg#chex.at</code>
*/
#Converter
#Singleton
#Startup
public class UserConverter implements AttributeConverter<User, Long> {
#Inject
private UserRepository userRepository;
private static UserRepository staticUserRepository;
#PostConstruct
public void init() {
staticUserRepository = this.userRepository;
}
#Override
public Long convertToDatabaseColumn(User attribute) {
if (null == attribute) {
return null;
}
return attribute.getId();
}
#Override
public User convertToEntityAttribute(Long dbData) {
if (null == dbData) {
return null;
}
return staticUserRepository.findById(dbData);
}
}
This way, you would create a Singleton EJB, that is created on boot of the container, setting the static class attribute in the PostConstruct phase. You then just use the static Repository instead of the injected field (which will still be NULL, when used as a JPA Converter).
Well, CDI still doesn't work for AttributeConverter, which would be the most elegant solution, but I have found a satisfying workaround. The workaround is using #FacesConverter. Unfortunately per default CDI doesn't work in faces converters and validators either, but thanks to the Apache MyFaces CODI API you can make it work unsing the #Advaced annotation :) So I came up with an implementation like this:
#Advanced
#FacesConverter("cryptoConverter")
public class CryptoJSFConverter implements Converter
{
private CryptoController crypto = new CryptoController();
#Inject
PatientController ptCtrl;
public Object getAsObject(FacesContext fc, UIComponent uic, String value)
{
if(value != null)
return crypto.pg_encrypt(value, ptCtrl.getSecretKey());
else
return null;
}
public String getAsString(FacesContext fc, UIComponent uic, Object object)
{
String res = crypto.pg_decrypt((byte[]) object, ptCtrl.getSecretKey());
return res;
}
}
The injected managed bean has to be explicitly annotated with #Named and some scope definition. A declaration in faces-config.xml doesn't work! In my solution it looks like this:
#Named
#SessionScoped
public class PatientController extends PersistanceManager
{
...
}
Now one has a context information in the converter. In my case it is session/user specific cryptography configuration.
Of course in such a solution it is very likely that a custom #FacesValidator is also needed, but thanks to CODI one have the possibility for using CDI here also (analog to converter).

catalina.base system property override in spring-boot?

My project uses the catalina.base system property to get resources relative to that property's folder location. When working in Eclipse, I pass -Dcatalina.base=. as a VM argument to the application's Main class.
My Main class is implemented like this:
#ComponentScan
#EnableAutoConfiguration
public class Main {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) {
if ( logger.isDebugEnabled() ) {
String debugCatalinaBase = System.getProperty("catalina.base");
// here catalinaBase is set to "." as expected.
logger.debug("catalinaBase: {}", debugCatalinaBase);
}
SpringApplication.run(Main.class, args);
}
}
As part of this project, I then have an ApplicationConfig class which is implemented like this:
#Configuration
public class ApplicationConfig {
private static final Logger logger = LogManager.getLogger();
#Value("${catalina.base}")
private String catalinaBase;
#Bean
public Properties jndiProperties() {
if ( logger.isDebugEnabled() ) {
String debugCatalinaBase = System.getProperty("catalina.base");
// here catalinaBase is set to "C:\Users\theUser\AppData\Local\Temp\tomcat.8558104871268204693.8081". NOT as expected!!!
logger.debug("catalinaBase: {}", debugCatalinaBase);
}
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,
CnsContextFactory.class.getName());
properties.setProperty(Context.PROVIDER_URL,
"file:" + catalinaBase + "\\conf\\jndi.properties");
return properties;
}
#Bean( name = "propertyConfigurer" )
public static PropertySourcesPlaceholderConfigurer propertyConfigurer() {
PropertySourcesPlaceholderConfigurer configurer =
new PropertySourcesPlaceholderConfigurer();
return configurer;
}
}
As you can see in the code snippet's comments, in ApplicationConfig the catalina.base system property has changed and I am not sure why or where this happened?
For info, my project uses spring-boot-starter-xxx:1.1.4.RELEASE jars, and spring-xxx:4.0.6.RELEASE jars.
Also, I have another project which follows pretty much the same overall pattern and uses the same jars and that project always sees catalina.base set to "." as expected. So I am wondering if the problem has something to do with the order in which spring configurations are loaded in the problematic project or something along those lines?
Thanks in advance for any help on this.
PM
String Boot calls Tomcat.setBaseDir(...) from TomcatEmbeddedServletContainerFactory using a temporary directory as the source. Tomcat actually sets the catalina.base property when the initBaseDir() method in org.apache.catalina.startup.Tomcat is called.
You need to add server.tomcat.basedir to your application.properties if you don't want Spring Boot to use a temp folder.

How to access EJB from a Quartz Job

Well, I'm using Quartz to schedule some jobs that I need in my application. But, I need some way to access a Stateful SessionBean on my Job. I knew that I can't inject it with #EJB. Can anyone help me?
Thanks.
I used the EJB3InvokerJob to invoke the methods of my EJB. Then I created my jobs that extends the EJB3InvokerJob, put the parameters of what EJB and method it should call and then call the super.execute().
The EJB3InvokerJob can be found here: http://jira.opensymphony.com/secure/attachment/13356/EJB3InvokerJob.java
My Job is looking like this:
public class BuscaSistecJob extends EJB3InvokerJob implements Job{
private final Logger logger = Logger.getLogger(this.getClass());
#Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap dataMap = jobExecutionContext.getMergedJobDataMap();
dataMap.put(EJB_JNDI_NAME_KEY, "java:app/JobService");
dataMap.put(EJB_INTERFACE_NAME_KEY, "br.org.cni.pronatec.controller.service.JobServiceLocal");
dataMap.put(EJB_METHOD_KEY, "buscaSistec");
Object[] arguments = new Object[1];
arguments[0] = jobExecutionContext.getTrigger().getStartTime();
dataMap.put(EJB_ARGS_KEY, arguments);
Class[] argumentTypes = new Class[1];
argumentTypes[0] = Date.class;
dataMap.put(EJB_ARG_TYPES_KEY, argumentTypes);
super.execute(jobExecutionContext);
}
}
And my EJB is like this:
#Stateless
#EJB(name="java:app/JobService", beanInterface=JobServiceLocal.class)
public class JobService implements JobServiceLocal {
#PersistenceContext
private EntityManager entityManager;
#Resource
private UserTransaction userTransaction;
#Override
public void buscaSistec(Date dataAgendamento) {
// Do something
}
I expect to help someone.
A simple solution would be to lookup the EJB via JNDI in the Job implementation.
final Context context = new InitialContext();
myService= (MyService) context
.lookup("java:global/my-app/myejbmodule-ejb/MyService");
I have done this in a current application I am developing on Glassfish 3.1.
you can do that simply by lookup the EJB via JNDI in the Job implementation. In particular, the JNDI name will be:
mappedName#name_of_businessInterface
where name_of_businessInterface is the fully qualified name of the business interface of this session bean. For example, if you specify mappedName="bank" and the fully qualified name of the business interface is com.CheckingAccount, then the JNDI of the business interface is bank#com.CheckingAccount.
Code Example:
Context context = new InitialContext();
MyService myService= (MyService) context.lookup("MyService#com.test.IMyService");

netbeans 7.0 applications client from database entity beans and session beans

In netbeans versions previous 7.0 was possible to write the following,
#Stateless(mappedName="Soelprotocol")
public class ProtocolFacade implements ProtocolFacadeLocal, ProtocolFacadeRemote {
#PersistenceContext(unitName = "SOEL-ejbPU")
private EntityManager em;
public void create(Protocol protocol) {
em.persist(protocol);
}
public void edit(Protocol protocol) {
em.merge(protocol);
}
public void remove(Protocol protocol) {
em.remove(em.merge(protocol));
}
public Protocol find(Object id) {
return em.find(Protocol.class, id);
}
public List<Protocol> findAll() {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Protocol.class));
return em.createQuery(cq).getResultList();
}
public List<Protocol> findRange(int[] range) {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Protocol.class));
Query q = em.createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
public int count() {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<Protocol> rt = cq.from(Protocol.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
When I try to create a remote session bean for database entity beans the check box label says "Remote in a project" with a message:
There is no suitable project available into which Remote interface could be stored. An open Ant based Java Class Library project is required.
With netbans 7.0 how to create an application client that uses remote session beans that created for database entity beans?
Is somewhere an complete example?
Vivien,
Create your application client as a separate Java application (or class library) project. If this project is open when you create the remote session bean in your EJB Module project, and you check the "create remote interface" option, Netbeans will propose this project for the remote interface.
It will then add the remote interface and EJB client container libraries to the client project.
Here's a complete example: http://netbeans.org/kb/docs/javaee/entappclient.html
good luck!