Is there any way to enable cdi within this #ClientEndpoint class (still using annotations as opposed to programmatic endpoint classes)? I am using wildfly 14 and java 8.
Here is the code that creates the session, passing the classname to the "createConnection" method:
#ApplicationScoped //TODO move this to be request scoped
public class SessionProducer {
#Produces
public Session getSession(InjectionPoint ip) {
SessionAnnotation annotation = ip.getAnnotated().getAnnotation(SessionAnnotation.class);
if(annotation != null) {
Class clazz = annotation.clazz();
String url = annotation.serverURL();
WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
try {
return webSocketContainer.connectToServer(clazz, new URI(url)); //<----------this is the line that uses the annotated class (clazz is a reference to the class)
} catch (DeploymentException | IOException | URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
/**
* The destroy/disposer metho for the session
* #param session
*/
public void close(#Disposes Session session) {
try {
session.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here is the annotated endpoint class:
#ClientEndpoint
public class CryptoCompareWSClient {
#Inject
#CryptoCompare
private Event<String> cryptoCompareEvent; //<--------this is always null, no cdi happens
public CryptoCompareWSClient() {
System.out.println("constructor");
//cryptoCompareEvent = new Event();
}
#PostConstruct
public void init() {
System.out.println("post construct"); //<---------this never gets called
}
#OnOpen
public void open(Session session) {
//session.getAsyncRemote().sendText("SubAdd: { subs: ['0~Poloniex~BTC~USD'] }" /*"test"*/);
System.out.println("opened");
}
#OnClose
public void close(Session session) {
System.out.println("Session " + session + " closed");
}
#OnError
public void error(Throwable error) {
System.out.println("Error: " + error.getMessage());
}
#OnMessage
public void message(String message, Session session) {
System.out.println("Message");
//cryptoCompareEvent.fireAsync(message);
}
}
Is there any way to enable cdi in the enabled class?
Thanks.
I have following code:
main:
#SpringBootApplication
#EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
In some place I have code like this:
public enum EmailMessage {
....
void sendSilent(String from, String[] recipients, Map<String, ?> properties) {
long start= System.currentTimeMillis();
try {
emailService.sendEmail(from, this.subject, recipients, properties, this.templateFileName);
} catch (Exception e) {
LOGGER.warn("Could not send email", e);
}
finally {
System.out.println("Result:" + (System.currentTimeMillis()- start)/1000 + " Thread:" + Thread.currentThread().getId());
System.out.println();
}
}
}
Here I am setting emailService:
#Service
public static class EmailService {
#PostConstruct
public void initialize() {
//to provide reference to EmailService to enum because enum could not be component
EmailMessage.emailService = this;
}
....
}
sendEmail:
#Async
public void sendEmail(String from, String subject, String[] to, Map<String, ?> props, String templateFileName) throws Exception {
.... //here some which executes slowly
System.out.println( " sendEmail Thread:" + Thread.currentThread().getId());
}
The code I provided produces following output:
sendEmail Thread:1
Result:9 Thread:1
As you can see thread the same for both methods. And code executes 9 sec.
What do I wrong?
I have the following two code tests.
first: JavaTypeTest() which blocks access to java.io.File as expected.
second: JavaMethodGetFileTest() which does not block access when a java.io.File object is returned thus bypassing the filter.
is it not supposed to block anything when Java.type() is used? or is there a specific way I should be adding the objects to the engine?
expected output:
JavaTypeTest success: true
JavaMethodGetFileTest success: true
actual output:
JavaTypeTest success: true
Z:\eclipse ws\NashornTests\.
JavaMethodGetFileTest success: false
The reasoning behind this is I want a proxy class that has only allowed methods which return allowed objects but have a getInstance() method which returns a dissallowedObject so that I have access to the instance contained in the proxy without exposing it to Nashorn.
public class NashornTest
{
class NashornClassFilter implements ClassFilter
{
public NashornClassFilter()
{
}
#Override
public boolean exposeToScripts(String clazz)
{
if (clazz.equals("java.io.File")) return false;
return true;
}
}
public static class AllowedClass
{
public AllowedClass()
{
}
public File disallowedMethod()
{
return new File(".");
}
}
public static void main(String[] args)
{
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
NashornClassFilter filter = new NashornTest().new NashornClassFilter();
NashornScriptEngine engine = (NashornScriptEngine) factory.getScriptEngine(filter);
NashornClassFilter filter1 = new NashornTest().new NashornClassFilter();
NashornScriptEngine engine1 = (NashornScriptEngine) factory.getScriptEngine(filter1);
System.out.println("JavaTypeTest success: " + JavaTypeTest(engine));
System.out.println("JavaMethodGetFileTest success: " + JavaMethodGetFileTest(engine1));
}
public static boolean JavaTypeTest(NashornScriptEngine engine)
{
try
{
engine.eval(
"function wrapper(){ "
+ "Java.type('java.io.File');"
+ "}");
((Invocable) engine).invokeFunction("wrapper");
}
catch (RuntimeException e)
{
if(e.getCause() instanceof ClassNotFoundException) return true;
e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
return false;
}
public static boolean JavaMethodGetFileTest(NashornScriptEngine engine)
{
try
{
engine.put("allowed", new AllowedClass());
engine.eval(
"function wrapper(){ "
+ "var file = allowed.disallowedMethod();"
+ "print(file.getAbsolutePath());"
+ "}");
((Invocable) engine).invokeFunction("wrapper");
}
catch(RuntimeException e)
{
if(e.getCause() instanceof ClassNotFoundException) return true;
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
}
I am in a scenario where I need to Unit test on class which is involving some bean formation and it require real data which I dont have, for more reference Below is the code.
the adapter class which I want to Mock
public class TIBCOAdapter {
public TIBCOAdapter(final GIAFProperties giafProperties) throws Exception {
if (giafProperties != null) {
this.giafProperties = giafProperties;
} else {
LOG.info("Error: No properties found");
}
init();
}
public void init() throws IOException {
factory = initializeQueueConnectionFactory();
requestQueue = initializeRequestQueue();
}
private QueueConnectionFactory initializeQueueConnectionFactory() {
final DurationRecord start = DurationLog.logBefore();
final JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiTemplate(new JndiTemplate(giafProperties.getProperties()));
bean.setJndiName(GIAFPropertyUtil.getPropertyString(giafProperties, "externalJndiName"));
try {
bean.afterPropertiesSet();
} catch (Exception e) {
throw new GIAFRuntimeException(e);
}
final ConnectionFactory targetConnectionFactory = (ConnectionFactory) bean
.getObject();
LOG.info("Got target connection factory: " + targetConnectionFactory);
final MultiCachingConnectionFactory factoryLocal = new MultiCachingConnectionFactory(
targetConnectionFactory, giafProperties);
DurationLog.logAfter(start);
return factoryLocal;
}
private Queue initializeRequestQueue() {
final JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiTemplate(new JndiTemplate(giafProperties.getProperties()));
bean.setJndiName(GIAFPropertyUtil.getPropertyString(giafProperties,
"request-queue"));
try {
bean.afterPropertiesSet();
} catch (Exception e) {
throw new GIAFRuntimeException(e);
}
return (Queue) bean.getObject();
}
}
The actual class where its object is created, which I don't want and that's why I want to mock creation of TIBCOAdapter
public class SomeClass {
public String getResponse(TestClientFilter testClientFilter) throws ICAException {
if (!filterValid(testClientFilter)) {
return null;
}
try {
Properties properties = new Properties(); // Sucess
GIAFProperties giafProperties = new GIAFProperties(properties, null); // sucess
addProperties(properties, testClientFilter); // sucess
TIBCOAdapter tibcoAdapter = new TIBCOAdapter(giafProperties); // ERROR This is the line which I want to mock
return (String) tibcoAdapter.invokeRequestResponse(testClientFilter.getMessage());
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new ICAException(e);
}
}
}
and this is my TEST
public class TestClientBusinessTest {
#Mock
private TIBCOAdapter tibco;
#InjectMocks
#Autowired
private SomeClass test;
#BeforeClass
public void setUp() throws NamingException {
MockitoAnnotations.initMocks(this);
}
private String returnStatement;
#Test(dataProvider = "getTestClientResponseBusiness", dataProviderClass = StaticDataProvider.class)
public void getResponse(TestClientFilter testClientFilter) throws Exception {
when(tibco.invokeRequestResponse(Matchers.any(TestClientFilter.class))).thenReturn(new Object());
test.getResponse(testClientFilter);
tibco.invokeRequestResponse(testClientFilter.getMessage());
}
}
These lines of code are making problem from TIBCOAdapters internal functions.
bean.setJndiTemplate(new JndiTemplate(giafProperties.getProperties()));
bean.setJndiName(GIAFPropertyUtil.getPropertyString(giafProperties, "externalJndiName"));
My Java application requires a retry logic on remote calls failures.
These remote calls are:
scattered all over the application
pertain to different Remote Service classes.
Also, the retry logic may have varying retry interval and varying retry attempts.
I need a generic retry() implementation which can make appropriate method calls depending on from where it is called. Below is a simple code illustration of I am looking for. I know we can attempt to do this using java reflection, but, is there a framework or an open source available somewhere which is read-to-use?
try {
ClassA objA = remoteServiceA.call(paramA1, paramA2, ...);
} catch (Exception e){
ClassA objA = (ClassA)retry(remoteService, listOfParams, ..); // generic method call
}
..
try {
ClassB objB = remoteServiceB.call(paramB1, paramB2, ...);
} catch (Exception e){
ClassA objB = (ClassB)retry(remoteService, listOfParams, ..); // generic method call
}
As already suggested, you should use AOP and Java annotations. I would recommend a read-made mechanism from jcabi-aspects (I'm a developer):
#RetryOnFailure(attempts = 3, delay = 5)
public String load(URL url) {
return url.openConnection().getContent();
}
Read also this blog post: http://www.yegor256.com/2014/08/15/retry-java-method-on-exception.html
Update: Check RetryFunc from Cactoos.
This is a book example of where aspectj (or aop in general) can be used, see 8.2.7 Example in Spring documentation and 5 Reasons Java Developers Should Learn and Use AspectJ.
Basically an aspect intercepts all calls to given methods (specified using annotation, naming convention, whatever) and retries.
Assume you have a method, that need to retied at every 500ms and upto 5 times.
Current class:
public class RemoteCaller{
Service serviceCaller;
public void remoteCall(String message) {
serviceCaller.updateDetails( this.message);
return null;
}
}
Modified approach:
public class RetriableHelper<T> implements Callable<T> {
private Callable<T> task;
private int numberOfRetries;
private int numberOfTriesLeft;
private long timeToWait;
public RetriableHelper(int numberOfRetries, long timeToWait, Callable<T> task) {
this.numberOfRetries = numberOfRetries;
numberOfTriesLeft = numberOfRetries;
this.timeToWait = timeToWait;
this.task = task;
}
public T call() throws Exception {
while (true) {
try {
return task.call();
} catch (InterruptedException e) {
throw e;
} catch (CancellationException e) {
throw e;
} catch (Exception e) {
numberOfTriesLeft--;
if (numberOfTriesLeft == 0) {
throw e;
}
Thread.sleep(timeToWait);
}
}
}
}
Backend system/remote call class:
public class RemoteCaller{
Service serviceCaller;
public void remoteCall(String message) {
class RemoteCallable implements Callable<Void> {
String message;
public RemoteCallable( String message)
{
this.message = message;
}
public Void call() throws Exception{
serviceCaller.updateDetails( this.message);
return null;
}
}
RetriableHelper<Void> retriableHelper = new RetriableHelper<Void>(5, 500, new RemoteCallable( message));
try {
retriableHelper.call();
} catch (Exception e) {
throw e;
}
}
}
enter link description here Spring has a retry annotation which servers the purpose
Step 1: Add following dependency to your POM
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.5.RELEASE</version>
</dependency>
Step 2: Enabling Spring Retry
To enable Spring Retry in an application, we need to add the #EnableRetry annotation to our #Configuration class:
Ex:
#Configuration
#EnableRetry
public class AppConfig { ... }
Step 3: To add retry functionality to methods, #Retryable can be used:
Ex:
#Service
public interface MyService {
#Retryable(
value = { SQLException.class },
maxAttempts = 2,
backoff = #Backoff(delay = 5000))
void retryService(String sql) throws SQLException;
...
}
Step 4.The #Recover annotation is used to define a separate recovery method when a #Retryable method fails with a specified exception:
Ex:
#Service
public interface MyService {
...
#Recover
void recover(SQLException e, String sql);
}
See Url for more details : http://www.baeldung.com/spring-retry
where do you get the services from? use a factory to Proxy the service you get from the original factory. The proxy can then implement the retry transparently. See the java Proxy/ProxyGenerators in reflection.
If you are using spring , then better go with Aspects.
Otherwise, below sample solution can work:
public class Test
{
public static void main(String[] args) throws Exception
{
Test test = new Test();
test.toRunFirst("Hello! This is normal invocation");
runWithRetry(test, "toRunFirst", "Hello! This is First, called with retry");
runWithRetry(test, "toRunSecond", "Hello! This is Second, called with retry");
}
public void toRunFirst(String s) {
System.out.println(s);
}
public void toRunSecond(String s) {
System.out.println(s);
}
public static Object runWithRetry(Object obj, String methodName, Object... args) throws Exception
{
Class<?>[] paramClass = new Class<?>[args.length];
for(int i=0; i< args.length; i++) {
paramClass[i] = args[i].getClass();
}
Method method = obj.getClass().getDeclaredMethod(methodName, paramClass);
int retryCount = 2;
for(int i=0; i< retryCount; i++) {
try {
return method.invoke(obj, args);
}
catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
I did not find what I needed so there is mine.
The main feature is that it throws the type of Exception you need when maxRetries is reached so you can catch it in the call.
import org.apache.log4j.Logger;
public class TaskUtils {
public static <E extends Throwable> void retry(int maxRetries, Task<E> task) throws E {
retry(maxRetries, 0, null, task);
}
public static <E extends Throwable> void retry(int maxRetries, long waitTimeMs, Logger logger, Task<E> task) throws E {
while (maxRetries > 0) {
maxRetries--;
try {
task.run();
} catch (Exception e) {
if (maxRetries == 0) {
try {
throw e;
} catch (Exception ignored) { // can't happen but just in case we wrap it in
throw new RuntimeException(e);
}
}
if (logger != null)
logger.warn("Attempt " + maxRetries + " failed", e);
try {
Thread.sleep(waitTimeMs);
} catch (InterruptedException ignored) {
}
}
}
}
public interface Task<E extends Throwable> {
void run() throws E;
}
}
Usage :
TaskUtils.retry(3, 500, LOGGER, () -> stmClickhouse.execute(
"ALTER TABLE `" + database + "`.`" + table.getName() + "` ON CLUSTER " + clusterName + allColumnsSql
));
add it into pom.xml
<dependency>
<groupId>org.deking.utils</groupId>
<artifactId>retry</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
new Retry<String>()
.maxOperationWaitTime(30_000)//Max operation wait time during a single operation
.retryIntervalTime(1_000)//Interval time between two operations
.maxRetryTimes(3)//Retry times when operation failed(or timeout) at the first time
.operation(() -> {
//your operation
return "success!";
})
.judgement(t -> (t == null || t.isEmpty()))//add your judgement whether the operation should be retry(Operation should return a value)
.execute();
If you want add retry config annotation on method,and call it:
class RetryTests{
#RetryConfig( maxRetryTimes=1)
public static String TestAnnotation() {
return "aaa";
}
public static void main(String[] args) {
try {
new Retry<String>()
.of(RetryTest.class.getMethod("TestAnnotation"),null)
.judgement(r -> r.equals("aaa"))
.execute();
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}