I am new to the Play framework and Java in general. What is wrong with this Global.java file? I get the error no interface expected here on the line public class Global extends GlobalSettings {
import play.*;
import play.libs.*;
import com.avaje.ebean.Ebean;
import models.*;
import java.util.*;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import play.api.Application;
import play.api.GlobalSettings;
public class Global extends GlobalSettings {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
#Override
public void onStart(Application app) {
if(User.find.findRowCount() == 0){
Ebean.save((List) Yaml.load("initial-data.yml"));
}
//Start Spring WS framework
applicationContext.start();
}
#Override
public void onStop(Application app) {
applicationContext.stop();
}
}
I am trying to create a simple SOAP web service within Play Java using the Spring framework. Perhaps I am going about this the wrong way?
Remove the play.api.GlobalSettings import. Do the same for play.api.Application. These...
import play.api.Application;
import play.api.GlobalSettings;
It looks like your project has defaulted to a Scala project rather than a Java one, I think. You should be using the play.GlobalSettings and play.Application objects for a Java Play application, covered by your current play.* import.
Related
I'm trying to mplement custom LockService class like it said in this answer: https://stackoverflow.com/a/15567073/5182320
package liquibase.ext;
import liquibase.exception.DatabaseException;
import liquibase.lockservice.StandardLockService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
#Slf4j
#Configuration
public class TimeoutLockService extends StandardLockService {
#SneakyThrows
#Override
public void waitForLock() {
forceReleaseLock();
}
#Override
public int getPriority() {
return super.getPriority() + 1;
}
#Override
public void init() throws DatabaseException {
super.init();
log.info("Init called");
}
}
Placed the class in the package liquibase.ext
But when I'm running my application it's ignoring this class and still trying to acquire the lock.
I was trying to do something similar and I had a similar issue, where my changes were not pickup, even though it was in package liquibase.ext . I am using liquibase 4.3.5 and the following document helped me.
Starting with 4.0, we switched to the standard java.util.ServiceLoader system to find extension classes.
https://docs.liquibase.com/tools-integrations/extensions/extension-upgrade-guides/lb-4.0-upgrade-guide.html
I had to crate the liquibase.lockservice.LockService file in META-INF/services with my implementation and solve the issue.
I am still a beginner in Spring Framework so I tried to code a program about "introduction" in Spring AOP but I am facing an error while compiling. Please find below the classes in the package concert:
PerformanceImp.java
package concert;
import org.springframework.stereotype.Component;
#Component
public class PerformanceImp implements Performance {
public void perform() {
System.out.println("This is the performance function");
}
}
Performance.java
package concert;
public interface Performance {
public void perform();
}
Encoreable.java
package concert;
public interface Encoreable {
void performEncore();
}
DefaultEncoreable.java
package concert;
import org.springframework.stereotype.Component;
#Component
public class DefaultEncoreable implements Encoreable {
public void performEncore() {
System.out.println("This is the performEncore function");
}
}
EncoreableIntroducer.java
package concert;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;
#Component
#Aspect
public class EncoreableIntroducer {
#DeclareParents(value="concert.Performance+",
defaultImpl=DefaultEncoreable.class)
public static Encoreable encoreable;
}
ConcertConfig.java
package concert;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
#Configuration
#EnableAspectJAutoProxy
#ComponentScan("concert")
public class ConcertConfig {
}
And the main class:
Main.java
package concert;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(ConcertConfig.class);
PerformanceImp pi = (PerformanceImp) context.getBean(PerformanceImp.class);
((Encoreable) pi).performEncore();
pi.perform();
}
}
I am getting the error:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'concert.PerformanceImp' available
Any help please ?
You cannot access the implementation (PerformanceImp) by default, because you enabled AOP, which sets to target interfaces instead of implementation. If you would remove EnableAspectJAutoProxy, you would see the code would work fine.
To understand a bit more about how AOP targeting works, take a look at this Spring Documentation
Spring AOP can also use CGLIB proxies. This is necessary to proxy
classes rather than interfaces. CGLIB is used by default if a business
object does not implement an interface. As it is good practice to
program to interfaces rather than classes; business classes normally
will implement one or more business interfaces. It is possible to
force the use of CGLIB, in those (hopefully rare) cases where you need
to advise a method that is not declared on an interface, or where you
need to pass a proxied object to a method as a concrete type.
So you have two options:
Take the interface when trying to get the bean from the ApplicationContext.
Enable AOP to target concrete classes instead.
To do this point #2, modify your annotation as follows:
#EnableAspectJAutoProxy(proxyTargetClass = true)
Try:
Performance pi = context.getBean("performanceImp", Performance.class);
instead of:
PerformanceImp pi = (PerformanceImp) context.getBean(PerformanceImp.class);
I am trying to create a generic class that will interact with multiple Spring MongoDB repositories. The current code I have compile but blows up with a NULL Exception because both of the repositories are NULL.
Here is my setup, I can't find any documentation that would ensure the autowiring in the wrapper class. Is there something that I am missing that will execute the autowiring. I am using gradle and I added the dependency based off the basic spring mongo project.
Thanks
InstructorDBRepository.java
package courseSystem;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface InstructorDBRepository extends MongoRepository<InstructorDB, String> {
InstructorDB save(InstructorDB saved);
void delete(InstructorDB deleted);
List<InstructorDB> findAll();
}
DBinterface.java
package courseSystem;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
public class DBinterface {
#Autowired
private AcademicRecordDBRepository AcademicRecordRepository;
#Autowired
private InstructorDBRepository InstructorRepository;
public DBinterface() {}
public void deleteAllTables()
{
AcademicRecordRepository.deleteAll();
InstructorRepository.deleteAll();;
}
//Some additional functions
}
The problem seems to be some poor error message.
I've created a dynamic web app project in eclipse and the runtime is TomEE+ 1.7.2
So this is the publisher
package study;
import java.io.IOException;
import java.net.InetSocketAddress;
import javax.ws.rs.ext.RuntimeDelegate;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class StandaloneJaxRsServer {
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(
"localhost", 8765), 8);
HttpHandler requestHandler = RuntimeDelegate.getInstance()
.createEndpoint(new JaxRSApplication(), HttpHandler.class); //<<<<< line 15
server.createContext("/jaxrs/", requestHandler);
server.start();
}
}
this is the app
package study;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath(value="/jaxrs")
public class JaxRSApplication extends Application{
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<>();
set.add(NotSingletonResource.class);
return set ;
}
//
// #Override
// public Set<Object> getSingletons() {
// Set<Object> set = new HashSet<>();
// set.add(new SingletonResource());
// return set ;
// }
}
and this is the resource
package study;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("/notSingletonResource")
public class NotSingletonResource {
private volatile int counter = 0;
#GET
#Produces({MediaType.TEXT_HTML})
public String getHello() {
return "Not singleton resource " + counter++;
}
}
when I try to run StandaloneJaxRsServer.main() I get
Exception in thread "main" java.lang.IllegalArgumentException
at org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl.createEndpoint(RuntimeDelegateImpl.java:104)
at study.StandaloneJaxRsServer.main(StandaloneJaxRsServer.java:15)
However, IllegalArgumentException does not tell much. What am I doing wrong?
The javadoc for the RuntimeDelegate interface states "Throws: IllegalArgumentException - if application is null or the requested endpoint type is not supported.' For a JAX-RS Application, I think you're supposed to use org.apache.cxf.jaxrs.JAXRSServerFactoryBean, and use the result of creating the endpoint to set up a server.
I won't accept my own answer, I just want to keep here some useful information just in case someone needs it.
TomEE+ does not have the libraries to make this work. Instead, what I've did was to remove all the TomEE+ dependencies from my eclipse project, then I've converted it to a maven project just to include this dependency according to #lmiguelmh answer to this question:
Latest Jersey example does not work
Then I've just added these jersey libraries
I'll wait a little bit more before accepting an answer here, because I really would like a better answer. I am following the steps described in the book "Java Web Services, Up and Running", so I think people will really need to know this information.
In a project we use annotions to define aspects.
Unfortunately I can't get eclipse to show a marker next to the advised methods.
In another project we use XML to define the aspects and eclipse shows markers.
Best I post some code to clarify:
First a bean to be advised:
package aop.test;
import org.springframework.stereotype.Service;
#Service
public class Worker {
public void work() {}
}
Then the aspect:
package aop.test;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Service;
#Aspect
#Service
public class WorkerLogger {
#Before("execution(void aop.test.Worker.work())")
public void log() {
System.out.println("working...");
}
}
And finally a main method to prepare the ApplicationContext, get the bean and run the advised method:
package aop.test;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context;
context = new AnnotationConfigApplicationContext();
context.register(AnnotationAwareAspectJAutoProxyCreator.class);
context.scan("aop.test");
context.refresh();
context.getBean(Worker.class).work();
}
}
I tried this in eclipse using the STS plugin and the STS itself. I never get a red arrow next to work() indicating it is advised.
What am I missing?
Have you installed the STS plugin on your Eclipse? It should be available on the Help > Eclipse Marketplace