java.lang.linkage error when trying to use jsr 356 - java

I'm trying to implement a jsr 356 websocket connection from within a war deployed in jetty.
I'm using this as a guide: http://aredko.blogspot.com/2013/11/java-websockets-jsr-356-on-jetty-91.html
(I can find lots of tutorials on basically using jsr 356 with an embedded jetty server, but none on building a websocket connection within an existing server - are there any good ones out there?)
Whenever I run the code listed above, I get the following error:
java.lang.LinkageError: loader constraint violation: when resolving method "org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(Lorg/eclipse/jetty/servlet/ServletContextHandler;)Lorg/eclipse/jetty/websocket/jsr356/server/ServerContainer;" the class loader (instance of org/eclipse/jetty/webapp/WebAppClassLoader) of the current class, com/me/stuff/data/DataServer, and the class loader (instance of org/eclipse/jetty/start/Classpath$Loader) for resolved class, org/eclipse/jetty/websocket/jsr356/server/deploy/WebSocketServerContainerInitializer, have different Class objects for the type y.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer.configureContext(Lorg/eclipse/jetty/servlet/ServletContextHandler;)Lorg/eclipse/jetty/websocket/jsr356/server/ServerContainer; used in the signature
which refers to the code
ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);
I'm at a loss to figure this out. I'm using the following lines from gradle to bring in the websocket stuff:
providedCompile (
[ group: 'javax.websocket', name: 'javax.websocket-api', version: '+'],
[ group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '+' ]
)
compile (
[ group: 'org.eclipse.jetty.websocket', name: 'javax-websocket-server-impl', version: '+'],
[ group: 'org.eclipse.jetty.websocket', name: 'javax-websocket-client-impl', version: '+']
)
I see that both the javax-websocket-server-impl jar and the javax.websocket-api jar contain ServerContainer classes...but I'm only including one of those in my war file. Is jetty pulling from its own internal older version? Or am I completely misreading the source of the issue?
The jetty version I have is: jetty-9.2.1.v20140609

The websocket jars should not be in your WAR.
Remove the following jars from your WAR's WEB-INF/lib/ directory.
javax.websocket-api-*.jar - the javax.websocket API jar
javax-websocket-server-impl-*.jar - the jetty server javax.websocket.server.* implementation jar
javax-websocket-client-impl - the jetty javax.websocket.* (client) jar
This is because you are coding/compiling against javax.websocket.* API classes.
The API and the implementation of the API are provided by Jetty itself.
This is no different than when you code against the servlet-api. (namely, that you don't include the servlet-api and the implementation of the servlet-api in your WAR)

Related

Setting up JNA in Gradle Project

I try to import a custom .dll inside my Gradle project. I add the dependencie inside build.gradle
dependencies {
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.6.0'
}
but when I try to run the gradle build I receive this error
..java:170: error: cannot find symbol
CustomLibrary INSTANCE = (CustomLibrary) Native.load("xxx", CustomLibrary.class);
^
symbol: method load()
location: class Native
1 error
Any suggestions?
You have a transitive dependency on an older version of JNA in another dependency.
As you have tagged this with spring boot that is the likely cause. Older Spring Boot versions used a 4.x (I think 4.3) JNA dependency and the syntax has changed.
The POM for Spring Boot uses a property jna.version that you could override if you were using Maven, but I don't think that is (easily) possible using Gradle. However, updating to the latest version of Spring Boot should solve your problem.

updating gradle version for a project that depends on another shared library project doesn't work in a toolchain (kubernetes)

I'm getting this error while trying to commit my changes into gitlab repo and deploy it in kubernetes after upgrading gradle version to 7.4
Also I think the problem in how I include my shared library inside the project it self, that's what I sense from the error output below
Could not determine the dependencies of task ':distTar'.
Could not resolve all task dependencies for configuration ':runtimeClasspath'.
Could not resolve project :vlc-shc.
Required by:
project :
> No matching configuration of project :vlc-shc was found. The consumer was configured to find a runtime of a library compatible with Java 11, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally but:
- None of the consumable configurations have attributes.
build.gradle:
dependencies {
implementation project(':vlc-shc')
}
setting.gradle:
rootProject.name = 'vlc-myProject'
include ('vlc-shc')

My EL Expressions are not being evaluated under a MyFaces 2.3 and Spring Boot 2.0.3 application

I have a MyFaces application running under Spring Boot 2.0.3, all Servlets and Context Listeners are properly registered and configured, and apparently working. Even my index.jsf page is being rendered. The tags are processed correctly on the .xhtml file.
The problem is that all the EL expressions of index.jsf page are not being processed/evaluated. No error is thrown but where I put #{myBean.property} is always being rendered as an empty String. Debugging it I see that the server code of my Managed bean is not being called.
I tried changing the el-api and el-impl libs for many versions, but no one worked. The final version I used is the el-api 2.2 specification, following the page https://myfaces.apache.org/core23/myfaces-impl/dependencies.html
As no error is being thrown, I can't figure out where is the problem. Does anybody has this error? Is it possible to run MyFaces 2.3 under a Spring Boot application packed as a jar file?
Here are the dependencies I am using on Gradle build file:
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile("org.jetbrains.kotlin:kotlin-reflect")
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile('org.springframework.boot:spring-boot-starter-test')
compile 'io.github.microutils:kotlin-logging:1.5.4'
compile group: 'org.apache.myfaces.core', name: 'myfaces-impl', version: '2.3.1'
compile group: 'org.apache.myfaces.core', name: 'myfaces-api', version: '2.3.1'
compile group: 'javax.enterprise', name: 'cdi-api', version: '2.0' //CDI vem embutido no JavaEE 6, mas não no Tomcat 9
compile group: 'org.glassfish.web', name: 'el-impl', version: '2.2'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot
compile 'org.springframework.boot:spring-boot-starter-web:2.0.3.RELEASE'
compile 'org.apache.tomcat.embed:tomcat-embed-jasper:8.5.32'
compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.6'
compile group: 'org.ocpsoft.rewrite', name: 'rewrite-servlet', version: '3.4.2.Final'
}
Here is the Spring configuration, to load Faces servlets:
#Component
open class ConfigureJSF : ServletContextInitializer {
private val logger = KotlinLogging.logger {}
#Throws(ServletException::class)
override fun onStartup(servletContext: ServletContext) {
//necessary to myfaces be enabled and work in spring boot, once servlets are loaded dynamically.
servletContext.setInitParameter("org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true")
servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", "true");
servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true");
servletContext.setInitParameter("javax.faces.DEFAULT_SUFFIX", ".xhtml")
servletContext.setInitParameter("javax.faces.FACELETS_REFRESH_PERIOD", "1")
servletContext.setInitParameter("org.apache.myfaces.EXPRESSION_FACTORY", "com.sun.el.ExpressionFactoryImpl")
servletContext.setInitParameter("org.apache.myfaces.CACHE_EL_EXPRESSIONS", "alwaysRecompile")
}
// Register ServletContextListener, necessary for Myfaces.
#Bean
open fun listenerRegistrationBean1(): ServletListenerRegistrationBean<ServletContextListener> {
val bean = ServletListenerRegistrationBean<ServletContextListener>()
bean.setListener(org.apache.myfaces.webapp.StartupServletContextListener())
return bean
}
#Bean
fun requestContextListener(): RequestContextListener {
return RequestContextListener()
}
//The faces servlet
#Bean
open fun facesServlet(): ServletRegistrationBean<MyFacesServlet> {
logger.info { "Criando Faces Servlet..." }
val servlet = org.apache.myfaces.webapp.MyFacesServlet() ;
val servletRegistrationBean = ServletRegistrationBean(servlet, "*.jsf", "*.xhtml")
servletRegistrationBean.setLoadOnStartup(1)
// servletRegistrationBean.order = 1;
return servletRegistrationBean;
}
Edit:
I copied the dependency configuration of another project that works, and the same result occurred. So, the problem is not with the code I did paste here, and yes, with my environment, which I will start to investigate more detailed on the sequence. My problematic environment contains JDK 8, 9 and 10 and Tomcat 9. My project is targeting JDK 8. Maybe there is some incompatibility here and this is the reason for some compiled annotations not being found, I believe I will discover the problem very soon.
After days trying to solve this problem, changing and combining different codes and environments, from JDK 8 to 10, Tomcat 8 and 9, testing in MacOS and Windows 10,from the JSF 2.1 implementation of MyFaces to the brand new JSF 2.3 implementation supporting CDI, deployed this last one on a WildFly server, I just noticed, on my expensive 32'' high-resolution display, that my Managed Bean was named with indexBeanusing a stranger character i with small dots on its top of, it was a diarised ï that I don't know how it had placed or typed there. That was the reason my managed bean was never found no matter what configuration I used.
I noticed this character on MacOS. On my Windows it seems harder to notice it. I think it's because of font differences, not hardware.
I am ashamed but I will not delete this question. May this can help someone in the future. Programming and life problems are like this: most of the times the error is in the less expected place.
Lesson learned.

Spring Boot 2.0.0 , DataSourceBuilder not found in autoconfigure jar

We are upgrading our existing Spring Boot (1.5) application to 2.0.0.
We connect with multiple databases and use the org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder class.
I added the dependency:
compile group: 'org.springframework.boot',
name: 'spring-boot-autoconfigure',
version: '2.0.0.RELEASE'
However, I am not able to compile the project: This class (DataSourceBuilder) does not exist in the 2.0.0 version jar.
In order to rule out gradle issues, I manually downloaded the jar and added it to the classpath. This class does not exist in the version.
Also extracted and searched the jar but this class is missing.
Can anyone help me resolve it?
The class was moved to another package. Its FQN is now org.springframework.boot.jdbc.DataSourceBuilder: https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/jdbc/DataSourceBuilder.html
Old class (Spring Boot 1.x)
org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder
New class (Spring Boot 2.x)
import org.springframework.boot.jdbc.DataSourceBuilder;

log4j2 configuration file not found with java 9

I had a Java 8 project and my configuration file was in resource folder and everything worked fine. Now I switched to Java 9, added requirement for log4j.api, and configuration file cannot be found anymore.
Do I need to add something else in my module-info file for the logger to find it's config?
For now, it's like this
module project.main {
requires jdk.incubator.httpclient;
requires jackson.databind;
requires jackson.core;
requires jackson.annotations;
requires log4j.api;
}
The Project structure is as:
The build.gradle file is as:
The log4j~faq suggests using at least log4j-api-2.x and log4j-core-2.x. Preferably add these to your build.gradle file:
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.9.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '2.9.0'
And make sure conflicting dependencies are excluded
In the module-info.java further you shall update(this is what I did in a custom maven project)
requires log4j; // not log4j.api
It should work for you then with the same directory structure as well.
Hint: This is where I started debugging it from.
Why do I see a warning about "No appenders found for logger" and "Please configure log4j properly"?
This occurs when the default configuration files log4j.properties and
log4j.xml can not be found and the application performs no explicit
configuration. log4j uses Thread.getContextClassLoader().getResource()
to locate the default configuration files and does not directly check
the file system...
Placed a debug point in the ClassLoader#getResource method and just keep an eye of resources looked for by the library.
Also to bring up the point over resources like resources/foo/bar/log4j.properties as stated in the release notes in JDK-8142968
JDK internal resources, other than class files, in the standard and JDK modules can no longer be located with the
ClassLoader.getResourceXXXAPIs. This may impact code that relies on
using these APIs to get at JDK internal properties files or other
resources.
and seconded by the java-doc of ClassLoader#getResource as well:
Resources in named modules are subject to the encapsulation rules
specified by Module.getResourceAsStream. Additionally, and except for
the special case where the resource has a name ending with ".class",
this method will only find resources in packages of named modules when
the package is opened unconditionally (even if the caller of this
method is in the same module as the resource).

Categories

Resources