How to inject EJB from different EAR in same glassfish - glassfish

I have been trying to implement this design for couple of days ago and had no success. (before continuing I tell that I have read this article "How can I inject an EJB from an other application on the same GlassFish Server?" and other than glassfish-ejb-jar.xml I tried everything in it )
I have 2 ear application. test.ear is my main app which I want to test it, but I don't want to add any remote interfaces in this project, so I created another .ear(automation.ear) which contains remote interfaces and inject EJBs from test.ear . so my standalone application calls automation app and can not access test application directly.
each application contains these modules: entities, ejb , ear (for example automation application contains :automation-entities, automation-ejb, automation-ear)
here is my journey :
(I deployed test.ear before all these attempts)
-first try: I added test.ejb with ejb type as a maven dependency to automation-ejb pom.xml and injected EJB of test.ear in one of the beans of automation project and gave it a mappedName; it worked however I realized that it is a false positive and it actually doesn't go to the implementation of test.ear. it uses the copy it has (because of dependency)
- second try: I added a plugin in pom.xml of test.ear to create ejb-client for me (which only contains the interfaces and not the implementation) and added this .jar to automation pom.xml as a dependency, then injected the ejb gave it mappedName and try to deply ; well it complained about not finding the class!--> can't deploy
- third try: I added a copy of the interface I wanted to use(from test.ear) in automation.ear and removed the dependencies in pom.xml of automation. injected EJB and gave it the mappedName; tried to deploy and no luck ! still can't find the class--> can't deploy
Here are my classes:
test.ear application
package com.ericsson.test.service;
import javax.ejb.Local;
#Local
public interface TestService1 {
public String TestMethod1();
}
//////////////////////////////////////////////////////
package com.ericsson.test.service;
import javax.ejb.Local;
import javax.ejb.Stateless;
#Local(TestService1.class)
#Stateless(name = "TestService1")
public class TestServiceBean1 implements TestService1{
#Override
public String TestMethod1() {
return "Test Method1";
}
}
automation.ear application
#Remote
public interface RemoteInterfaceTest{
public void doSomething();
}
////////////////////////////////////////////////////////////////////////
package com.ericsson.test.service;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.naming.InitialContext;
#Singleton
#Startup
public class RemoteInterfaceTestBean implements RemoteInterfaceTest {
#EJB(mappedName = "Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1/local")
private TestService1 testService1EJB;
#PostConstruct
public void doSomething() {
try {
InitialContext ic = new InitialContext();
TestService1 service1 = (TestService1) ic
.lookup("java:global/Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1");
System.out.println(service1.TestMethod1());
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("OOOOOOPPPPPPSSSSSSSSS ! First try");
}
try {
testService1EJB.TestMethod1();
} catch (Exception e) {
System.out.println("OOOOOOPPPPPPSSSSSSSSS ! Second try");
}
}
}
and this is the exception I get:
SEVERE: Exception while deploying the app [automation-csdp-remote] : Cannot resolve reference Local ejb-ref name=com.ericsson.test.service.RemoteInterfaceTestBean/testService1EJB,Local 3.x interface =com.ericsson.test.service.TestService1,ejb-link=null,lookup=,mappedName=Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1/local,jndi-name=,refType=Session
I have tried played with it like 1000 times, I checked the glass fish and the class is there, why it can not find it ? any idea would be greatly appreciated.
I am using EJB 3.x , glassfish 3.1.2 , maven 3.0.5, eclipse kepler

Related

How to schedule job by helidon MP?

Im Try to create schedule job sample, buy task dont execute.
what's wrong?
#ApplicationScoped
public class CustomApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(FileService.class);
return classes;
}
}
public class FileService {
public void schedulerFeature() throws InterruptedException {
Scheduling.fixedRateBuilder()
.delay(4)
.initialDelay(2)
.timeUnit(TimeUnit.SECONDS)
.task(inv -> {
System.out.println("Running in:" + Thread.currentThread().getName());
System.out.println("Every 4 seconds an action, with an initial delay");
})
.build();
Thread.sleep(12000);
}
}
Im Try to create schedule job sample, buy task dont execute.
I don't know which version of Helidon you're using, and hence I don't know which version of JAX-RS/Jakarta RESTful Web Services you're using. For simplicity and brevity, I will assume you are using Helidon 3.x and therefore Jakarta RESTful Web Services 3.0.0.
This is not a Helidon question, but rather a basic JAX-RS/Jakarta RESTful Web Services question. You are really asking: "Why is my FileService class not instantiated by Jersey?"
Checking the documentation for Application#getClasses(), we can see that it reads: "Get a set of root resource, provider and feature classes." Your FileService class does not meet any of these requirements so it is simply ignored.
Guessing some more: I see you use the word "feature" in your example. This suggests that perhaps you want this class to actually be a true Jakarta RESTful Web Services Feature. Once again, the documentation here will tell you what you need to know to do next.
I revised my application and i had imported wrong maven lib. To schedule a job It is necessary import microprofile scheduling maven artifact:
<dependency>
<groupId>io.helidon.microprofile.scheduling</groupId>
<artifactId>helidon-microprofile-scheduling</artifactId>
<version>3.0.2</version>
</dependency>
import java.util.HashSet;
import java.util.Set;
#ApplicationScoped
public class CustomApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(FileService.class);
return classes;
}
}
import io.helidon.microprofile.scheduling.Scheduled;
import jakarta.enterprise.context.ApplicationScoped;
/**
* File service.
*/
#ApplicationScoped
public class FileService {
#Scheduled("0/2 * * * * ? *")
//#FixedRate(1)
public void schedulerFeature() {
System.out.println("Running");
}
}

start application (from jar) on Weblogic startup

I'm using Weblogic 12c, I need to run app before/with the web app starts.
the app should fetch information and write it to db.
I read that in previous versions of WL programmers used to work with ApplicationLifecycleListener, but it is deprecated now.
I'm compiling the project to ear file.
I also tried to use ejb3.2 eager singleton, but it didn't worked.
Is there any working alternative?
I solved the issue by creating EJB as the following:
#Singleton
#Startup
public class StartupBean {
#PostConstruct
private void startup() { ... }
#PreDestroy
private void shutdown() { ... }
...
}
Creating the EJB Singleton instances is one of the Weblogic life cycle init calls, I put my java code under startup() method.

NullPointerException and #EJB

I use EJB3+JavaEE6+JBoss. I am absolutely newbie in EJB. I wrote this code:
package server.ejb;
#Remote
public interface HelloUser
{
void sayHello( String name );
}
#Stateless
public class HelloUserBean implements HelloUser
{
#Override public void sayHello( String name )
{
System.out.println( "Hello " + name );
}
}
Having assebled this code with Maven and deployed it on JBoss, I wrote a client:
import server.ejb.HelloUserBean;
import javax.ejb.EJB;
public class Test
{
#EJB
public static HelloUserBean bean;
public static void main( String... args )
{
bean.sayHello( "Alex" );
}
}
After compiling, I've got NullPointerException. It said that bean was null. Using JDNI + PersistentContext I could get a success, but I still can't use DI as well. Please, help me
I reorginized my code! Actually I wrote another server-side project with the same sence and a standalone client-app. Here is the structure of server-side app:
#Remote
public interface EchoRemote{
String getMessage();
}
#Stateless
public class EchoBean implements EchoRemote{
#Override
public String getMessage(){
return "Hello From Stateless Bean";
}
}
public class InvokationClient{
#EJB
private EchoRemote bean;
public String getMessage(){
return bean.getMessage();
}
}
And here is the client-side standalone app:
import com.steeplesoft.client.InvokationClient;
public class Main{
public static void main( String... args ) throws IOException{
InvokationClient client = new InvokationClient();
FileWriter fileWriter = new FileWriter( "D:/invokation_client_test.txt" );
fileWriter.write( client.getMessage() );
fileWriter.close();
}
}
I've got empty file and NullPointerEception in console
I hope you can help me :) It's tremendously important for me!!!
So you start your Test-class standalone in a separate JVM. Where did you configure to which JBoss it should connect? Which component does the dependency injection? Since you don't have a DI container that manages the Test-class and since the connection to JBoss is not configured anywhere, this can't work.
In order to make it work, you can do the following:
1) Write a Servlet, use #EJB in the Servlet and deploy it on JBoss. Put your EJB and the Servlet in the same WAR to make it easy. The Servlet is managed by the container and DI works. As a newbie with EJB I would do this first.
2) Do a JNDI-Lookup and call your EJB from a standalone client as described in https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI
3) Use an Application Client Container (ACC) as described in http://blogs.steeplesoft.com/posts/2011/02/22/java-ees-buried-treasure-the-application-client-container/ Deploy the EAR to jboss and invoke the client locally
$JBOSS_HOME/bin/appclient.sh --host remote://localhost:4447 ./local/path/to/enterpriseapplication-0.1-SNAPSHOT.ear#appclient-0.1-SNAPSHOT.jar
Remark: When I tried the example from blogs.steeplesoft.com, I had problems with the Swing classes, but it did work JBoss EAP 6.2, when I removed the Swing classes.

EJB Injection failure on deploy

I've got a problem exxh EJB's.
First of all, my setup: I am using GlassFish & JEE6. I have got a REST-Service packaged as a WAR and a bean packaged as an EJB-Jar. They are not inside an EAR.
The EJB should be used from the REST-WAR via #EJB, but when I try to deploy the WAR, GlassFish shows this error:
Error occurred during deployment:
Exception while deploying the app [exx-upload-1.0] : Cannot resolve reference Local ejb-ref name=com.ex.exx.model.FileUpload/ocr,Local 3.x interface =com.ex.exx.api.IOCRService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session. Please see server.log for more details.
(The EJB was deployed before without any erros).
I have no clue why. Here is the EJB Code:
Interface:
#Local
public interface IOCRService {
public String performOCRonImage(BufferedImage input);
}
and Implementation:
#Stateless
#LocalBean
public class OCRScanner implements IOCRService {
private Logger logger = Logger.getLogger(this.getClass().getName());
private final static String NOT_RECOGNIZED = "Can not regocnize text";
/**
* Default constructor.
*/
public OCRScanner() {
logger.log(Level.INFO, "### OCR SCANNER BUILD" + this);
}
public String performOCRonImage(BufferedImage input) {
logger.log(Level.INFO, "### OCR SCANNER CALLED" + this);
}
...
And here is the important part in the WAR:
public class FileUpload {
private final File PROPERTIES_FILE = new File(
"fileUploadProperties.properties");
private final String PARAMETER_NAME = "file";
private final Logger logger = Logger.getLogger(this.getClass().getName());
#EJB
private IOCRService ocr;
public Response uploadFile(...) {
// do some stuff
logger.log(Level.INFO, "### EJB" + ocr.toString())
}
Anny suggestions? I can not find my failure here.
Solved this, by replaceing #Local with #Remote.
This works, however, I am not satisfied as I do not understand why.
Basically, given the specs (eg. explained in the tutorial), an application can only access other application's EJB, if they are decorated with #Remote.
Thus, you have 3 options:
decorate your EJB with #Remote (what you have done),
package both together inside an ear (as they would reside in the
same application then). But if you intent to deploy them in seperate
applications or even seperate servers, use 1.)
use CDI with #Inject, but this will still only discover the EJB if
either in the same application, or decorated as #Remote if not.
HTH,
Alex
You should not use #EJB if the target is not an EJB. I guess this is your case because you are trying to inject into a class in your WAR.
Instead use:
#Inject
private IOCRService ocr;
Basically, #Inject is better in most cases, because:
it is more typesafe,
it supports #Alternatives
it is aware of the scope of the injected object.
Another solution it's to add #Stateless(name=""), this worked form

Dozer DozerBeanMapper Instantiation Startup EJB App Server Glassfish

Dozer's documentation states that you should only have one instance of DozerBeanMapper running in the app on the server. For initial development I ignored this, now I want to update the app to do this.
How can I instantiate the DozerBeanMapper class when the application starts on glassfish, and how would I access its "map" method in another class once the application has started or been newly deployed?
This is for EJBs so I can't use any servlet to do this.
OK, so I've finally had time to refactor this code. With the pointer from #Mikko Maunu, I am editing my question to provide the code that I have working for me for anyone who might find it useful in the future.
package com.xyz.utilities.singleton;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import org.dozer.DozerBeanMapper;
#Startup
#Singleton
public class DozerInstantiator {
private DozerBeanMapper mapper = null;
#PostConstruct
void init() {
mapper = new DozerBeanMapper();
}
public DozerBeanMapper getMapper() {
return mapper;
}
}
And here is a straight forward usecase:
Inject an EJB member variable to your client class:
#EJB
DozerInstantiator di;
Within a method somewhere in the client class you can invoke the dozer mapper like so:
Credentials credentials = di.getMapper().map(credentialsDTO, Credentials.class);
// or
Credentials credentials = new Credentials();
di.getMapper().map(credentialsDTO, credentials);
If this is wrong or off base, someone please leave a comment. Until then, this seems to work so I'll use this solution I've developed with Mikko's input.
If you are using GlassFish 3.x, then you can use EJB 3.1 Singleton Session Bean:
#Startup //initialization in application startup
#Singleton //only one instance
public class DozerInitializer {
private String status;
#PostConstruct //executed once and only once when sole instance is created
void init {
//do steps needed to instantiate DozerBeanMapper
//here
}
}