I'm trying to create a portlet with liferay 6.2 and using spring. If I create a bean without using constructor-arg or factory-method then everything works fine. But if I use either of these then I get exceptions when the portlet is deployed.
an example:
the exception I'm getting is:
01:28:21,884 ERROR [ContextLoader:323] Context initialization failed
java.lang.IncompatibleClassChangeError: class org.springframework.core.LocalVariableTableParameterNameDiscoverer$ParameterNameDiscoveringVisitor has interface org.springframework.asm.ClassVisitor as super class
I realize that this can be caused by having 2 versions of ams, but im using the spring jars that come with liferay.
You give an option yourself - duplicate classes. But without knowing how you build and what you're doing, there's hardly anything to do apart from asking you to make extra extra extra sure that you don't have duplicate resources on the classpath:
Check your deployed web application (once it's deployed to your application server) and its WEB-INF/lib folder for such duplicates. They might come in only during the buildprocess, e.g. they might not be in your IDE's workspace. Or Liferay might inject them (due to declared dependencies) during deployment.
You'll have to figure out how (and in which phase) those resources get there, then eliminate that option (e.g. through proper maven scope, e.g. "provided")
Related
I've made a trivial RESTful service on a JBoss server that just says "hello" when it receives any request. This part works and it is already deployed.
To go further with my project I need to log. The other applications on the server use log4j configured by a log4j.xml placed on a specific folder on the server.
For an offline project I'm used to have a runnable main method that in this case I would use to execute DOMConfigurator.configure(filepath) (where filepath is the log4j.xml) and I will be expecting to log with those settings.
However, since this is a deployed service (and since I'm not skilled enough to figure it myself) how would I so such a thing?
The question in my opinion could be interpreted in two ways:
How do I run some code "for sure" when I deploy something (in similar way to a main method) ? Do i need something like spring-boot?
How do I setup log4j on a deployed service on JBoss?
(I don't know if one question excludes the other...)
Thanks for the help!
1) If you want to run some code "for sure" you can create #PostConstruct method in one of your beans. Both Spring and EJB support it.
2)As for log4J configuration it should be enough to put it in classpath and add corresponding dependencies, no explicit configuration of path should be needed.
I have a project structure with three jar files. All are loaded into one classpath and then get executed. I am using the spring core, jpa and hibernate. #Services/#Autowired are working fine, as well as Entities and Repositories (all on a mysql database).
Now I want that the project can send and receive messages over network/internet. So I asked some people how I could achieve this without breaking my current structure. And I was told that spring-boot is the architecture for me because I do not need a web server (tomcat or glassfish) for it.
But now I am not sure if this is correct because I did not find any sources that say the same thing. Because of that I tried implementing it in order to verify it myself.
The important changes I made to my project (all pom.xml files and my configuration class) can be found here: http://84.141.90.123:9910/
From what I read I need the #SpringBootApplication annotation for spring boot. This is a equivalent to #Configuration, #ComponentScan, #EnableAutoConfiguration, #EnableWebMvc.
The first two are already in my structure. But when I add the last two annotations, I get different errors:
When I add #EnableAutoConfiguration I get
Caused by: java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
When I add #EnableWebMvc I get
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
From my bad english knollage, the #EnableWebMvc error seems to say that the application needs a web server (tomcat or glassfish).
So is the main statement wrong and I can not start spring boot without a web server?
Because I do not use any xml files and/or property files for spring (they did not worked), I only rely on java code based configuration for spring, jpa and hibernate. And therefore there are only very few tutorials/threads with help. Most of the time they just say add thi or add that to your xml but because I don't have them, it is a little pain in the ass.
Also I compile with aspectj, so I can not use the spring compile parent. And also I am not able to manipulate the main class/method, because the main class is in an outer jar file that is not programmed by me.
So concrete:
Can a spring boot application in a standalone jar run without a web server wrapping it?
If yes, what am I doing wrong? Am I missing a dependency, an annotation or a configuration?
If you want to receive messages over HTTP(ie run a REST API) then you need a web server.
If you just want to send messages over HTTP then you only need a HTTP client.
Spring-boot has the the option of running an embedded web server(tomcat by default), you don't need to run a separate application server.
To work out your issues with your build I would start with generating a project using spring initializr.
You can select the dependencies you want(try using the advanced version link at the bottom), and it will build a maven/gradle project for you with the right structure, build file and compatible dependencies.
Change :
public static void main(String[] args) {
SpringApplication.run(ActiveMqApplication.class, args);
}
to :
public static void main(String[] args) {
new SpringApplicationBuilder(ActiveMqApplication.class)
.web(WebApplicationType.NONE).run(args);
}
I'm modifying a Maven-based Liferay portlet (6.1.1) that uses Service Layer.
My needs are to add an ActiveMQ listener to the portlet (for communication with external products).
I'm trying to use integrated spring engine (3.0.7) to instance the listener.
So, to start, inside ext-sping.xml (auto managed by Liferay) I defined the following beans:
- a connection factory: org.apache.activemq.ActiveMQConnectionFactory
- a caching connection factory (org.springframework.jms.connection.CachingConnectionFactory) with targetConnectionFactory reference to previous bean.
At deploying time the error I get is:
Cannot convert value of type [org.apache.activemq.ActiveMQConnectionFactory] to
required type [javax.jms.ConnectionFactory] for property
'targetConnectionFactory': no matching editors or conversion strategy found
Obviusly org.apache.activemq.ActiveMQConnectionFactory implements javax.jms.ConnectionFactory, infact if I try to set the value by code, the deploy is done succesfully.
In my pom.xml I try to add a depenency both to activemq-core (just activemq) or activemq-all (contains also javax.jms package), but without success.
How it is possible?
Thank you
Possibly a classloader problem - the classloader loading the CachingConnectionFactory is resolving to a different javax.jms.ConnectionFactory to the one loading the ActiveMQ factory.
Run with -verbose on the command line to see which jar(s) classes are being loaded from.
I have a Java EE Enterprise application which comprise of EJB module and JSF based Web module.
I have created EJB Stateless Bean, and now I need to call method of that bean from Web module Managed Bean, but compiler gives me an error.
I'm just starting with Java EE so I really don't have best of idea what should I look into
So based on comments above I have solved this problem.
I went to web module of my application and to lib folder of it.
Right click -> add project
Found my EJB module and selected it. Not sure if this is good idea, but for now it seems it works.
We have a number of web service client applications which interface between our main customer facing application and backend web services. These web service application generate their own JAXWS stub code to directly interface with the web services and implementation code to provide a clean interface between the JAXWS code and any application that wishes to use it. We've had some small problems with these over the last few weeks but most of them have been resolved.
When it was time to integrate these into the customer facing application we encountered numerous problems, mainly focused around JDK1.5 and 1.6 incompatibility. These have been resolved now, however we have hit another problem which we have no resolution for. The web service clients use AOP to set common things like header credentials, exception handling and throttling:
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* MyService.*(..))" />
<aop:aspect id="throttling" ref="throttlingAdvisor">
<aop:around pointcut-ref="pointcut" method="doThrottle" />
</aop:aspect>
<aop:aspect id="errorHandling" ref="errorHandlingAdvisor">
<aop:around pointcut-ref="pointcut" method="handleExceptions" />
Each aspect refers to a POJO bean, these beans include the method stated in the configuration with the method parameter type of org.aspectj.lang.ProceedingJoinPoint, this is used to extract the arguments of the method I'm intercepting.
We have one of these for each of the web service clients (in an applicationContext-webservicename.xml). This xml file is included in the packaged JAR which is included in the customer facing application and imported into the main applicationContext.xml loaded by the web.xml of the customer facing application.
We have a number of unit tests for these web clients, they all pass proving there's nothing wrong with them individually. When all the services are included in the customer facing applications we get a java.lang.NoClassDefFoundError: ProceedingJoinPoint exception when it starts up (we're using tomcat 5.5 with JDK1.5.0_17).
I looked up the JavaDoc for java.lang.NoClassDefFoundError just in case it had a special meaning, looks like the JVM thinks the class does not exist. I then looked for the jar which contains the classes it's claiming it cannot find (aspectjrt-1.5.4.jar and aspectjweaver-1.5.4.jar), there is a duplication of these classes so I tried removing each jar in turn to see what would happen, exactly the same error.
Am I missing a required dependency? Is there a common cause to this problem (I've searched for this yesterday not finding much)? Any help would be most appreciated.
After all this time we managed to find the solution to this problem, we use Bamboo to build our projects when a SVN commit is detected. Although the bamboo environment was set up to match our development machines when it built a dependent project it produced this weird problem.
We're still not sure why it did this, however in the meantime we're manually building and deploying this particular project.
My advice to anyone experiencing a similar problem, just isolate yourself from internal maven repos and rebuild all your projects locally.
Thanks for everyone's help.
Could be a class loader issue. Where are the AspectJ JARs? If you have them in your WEB-INF/lib now, perhaps you could try copying them to the Tomcat common/lib and see if that helps.
It could be that the app server class loader needs them on startup, but the application class loader hasn't gotten them from WEB-INF because it's lower in the class loader hierarchy.
Only add aspectjrt.jar to the server/lib folder, NOT the aspectjweaver.jar. Duplicate classes can also lead to confusion. The runtime jar (the "rt" stands for runtime) is supposed for the runtime. The weaver jar is used for compile/weave time. Are you using LTW or CTW?