Issues with WAS Liberty classloader - java

I have an issue with the WAS Liberty classloader, nothing I do seem to fix it. The issue seems to be with log4j2, which I am using.
I'm running 16.0.0.4 (just upgraded from 8.5.5.9 where this issue also exist). I'm trying to create a webapp using Primefaces 6.0 which connects to Elasticsearch 5.1.1.
I have added the following dependency to maven:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>${library.elasticsearch.version}</version>
</dependency>
Somewhere along the road I need to do the following:
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(HOST), PORT));
Debugging this line hits the following method call in Elasticsearch (class: org.elasticsearch.threadpool.ThreadPool line 203):
logger.debug("created thread pool: {}", entry.getValue().formatInfo(executorHolder.info));
This throws an java.lang.NoSuchMethodError:
org/apache/logging/log4j/Logger.debug(java/lang/String;java/lang/Object;)
Normally we use log4j 2.2, but I have included log4j2 2.7 as described here (Elasticsearch v5.0 uses 2.6.2, v5.1 uses 2.7): https://discuss.elastic.co/t/issue-with-elastic-search-5-0-0-noclassdeffounderror-org-apache-logging-log4j-logger/64262/2
I have also tried to make it "provided". I'm currently building a war file, but I also tried to do it as an ear, same result.
I came accoss this issue on the Elasticsearch 5-alpha: https://github.com/elastic/elasticsearch/issues/19415 Here they note that they wanted to create a server and therefore did not see log4j2 as a consern, but they suggest that you use the REST API instead (although, at the time of writing, this was not usable for Java developers).
So the question is, what do I do? Should I use the REST API (e.g. Jest (https://github.com/searchbox-io/Jest/tree/master/jest)) or ?...
The code I have works fine when running standalone outside Liberty.
UPDATE:
It seems like parts of Liberty does contain log4j v2.2:
class load: org.apache.logging.log4j.core.appender.routing.Route from: file:/C:/deploy/liberty/workarea/org.eclipse.osgi/60/data/cache/com.ibm.ws.app.manager_0/.cache/lib/log4j-core-2.2.jar
...
It loads a lot of classes from this jar, but not the one that I'm having trouble with - this is loaded from an app we have. I tried to bump the version inside our own app, but same issue.

Related

Vaadin 23 not resolving URL's, instead showing errorpage

Problem summary: we've upgraded our Java 17 monolith application with multiple modules from Vaadin 21.0.1 to 23.3.5 and now our application routes don't resolve anymore, instead resulting in 404 Whitelabel errorpages.
This not being our first Vaadin rodeo (originating from Vaadin 7), we followed the Vaadin upgrade guide generator and expanded accordingly upon that.
Steps we took, each having been validated seperately:
Upgraded our backend to use Spring 5.3.18 (coming from 5.3.10). No issue there
Upgraded our frontend to use Spring Boot 2.6.7 (coming from 2.5.4). No issue there
this step was project-specific and not in the guide Removed Vaadin-addons from pom.xml. Also removed those imports from our package.json. Naturally removed all addons-code from application (EnhancedDialog and MultiselectComboBox -> using v23's regular Dialog and MultiSelectComboBox)
Removed webpack.config.js, package-lock.json and the node_modules folder
Raised global (-g) npm version to 9.4.0 (coming from 8.3.3)
Cleared npm with commandline npm cache clear --force
Upgraded the Vaadin flow version to 23.3.5 (coming from 21.0.1)
added the following dependency and reloaded the pom.xml:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>flow-maven-plugin</artifactId>
<version>23.3.3</version>
</dependency>
Invalidated and restarted IntelliJ
ran clean-install Maven command through IntelliJ (with Production flag on/off makes no difference)
-> This results in a 404 whitelabel errorpage.
Next, I made sure that all our views annotated with com.vaadin.flow.router.#Route contained at least the javax.annotation.security.#PermitAll annotation.
I added spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration to our application.properties trying to get a more descriptive message.
-> This results in the Apache Tomcat errorpage with description: "The origin server did not find a current representation for the target resource or is not willing to disclose that one exists."
In both cases, the F12 DevTools are empty and showing nothing more than a 404 for the given URL.
So I continued debugging and validated that our custom security roles were validated correctly, a bit like this answer hinted at.
I'm getting into the breakpoints placed in the configure(HttpSecurity http) method from the WebSecurityConfigurerAdapter, but I'm unable to enter the serviceInit(ServiceInitEvent event) from the VaadinServiceInitListener.
I'm not a pro concerning servletRequests, but when hitting the isFrameworkInternalRequest(HttpServletRequest request) (called during the adapter's configuration), it seems only logical that for REQUEST_TYPE_PARAMETER a value of null is returned.
I was intrigued by these upgrade steps for an even higher Vaadin version, but nothing in there changed a bit for me.
When asked, I'd say that Spring isn't picking up on my views. Even the older #EnableVaadin() annotation did nothing. At this point I can't think straight anymore, even looking into the change of why Vaadin now uses vite.config.ts instead of webpack.config.js. Any pointers to where the issue might lay are immensely appreciated.
all credit to #Knoobie whose concise answer contained the correct solution.
Vaadin 23.3.x requires at least 2.7.x in order to work.
The Vaadin upgrade guide generator, when looking at the steps to migrate from v21 to v23, mistakenly referenced the minimum version of SpringBoot as 2.6.6. They will fix this in the immediate future.

Disable Spring Cloud Kubernetes in local

Small question on how to disable Spring Cloud Kubernetes in local mode please.
The project is a simple SpringBoot + SpringCloud project deployed in Kubernetes.
Hence, there is this dependency in the class path:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
And when we deployed the app in a Kubernetes environment, everything is fine.
However, the same app run in local mode will yield this warning, but most of all, a 20 seconds increased start time.
o.s.c.k.f.Fabric8AutoConfiguration : No namespace has been detected. Please specify KUBERNETES_NAMESPACE env var, or use a later kubernetes version (1.3 or later)
In local, while removing the dependency entirely, things are "back to normal". The message disappears, and the start up time comes back down.
However, commenting and uncommenting the dependency based on the local environment might not be the best solution.
Is there a property to disable Spring Cloud Kubernetes entirely that I can configure in local please?
Thank you
As the documentation says, you can do that by adding:
spring.cloud.kubernetes.enabled=false
that, in turn, could be an environment property that you can enable/disable per environment.
What worked for me was adding the spring.cloud.kubernetes.enabled=false property in the boostrap.properties/yaml file and not in the application.properties/yaml file.
Create the file "bootstrap.properties" into the resources folder
Then add the following lines:
spring.cloud.kubernetes.enabled=false
spring.cloud.kubernetes.discovery.enabled=false

Load WSDl file from Spring Boot jar file?

Sorry if this is a duplicate, I looked at several other questions but none seemed to match or provide workable solutions.
Problem
I am writing a Spring Boot (v2.0.2) app, this app exposes a RESTful API which then calls into a WSDL service. I've generated the WSDL classes with Maven/jaxb plugin and everything works from my dev machine. When deployed to the server I get an error that the WSDL service class can not load the underlying WSDL file. The problem is that when the Java classes are generated it is using the full path from my dev machine (snippet from the generated service class)
try {
URL baseUrl;
baseUrl = com.mytest.WSDLService.class.getResource(".");
url = new URL(baseUrl, "/home/users/me/projects/wsdltest/wsdl/MyWSDL.wsdl");
} catch (MalformedURLException e) {
The WSDL file (MyWSDL.wsdl) is in the spring boot JAR file for my application, it is in a subdirectory off root called 'wsdl'
Question Is there a way that I can load this WSDL from the JAR file without having to modify the generated classes?
Ideal Solution I'm hoping to find a solution that doesn't make me modify the generated files (we intend to do this for several services), ideally I'd like a solution which can be done at build time (in the pom.xml?), if that's possible.
Solutions Tried
A post on here suggested using the "wsdlLocation" tag in my pom.xml and provide a explicit path to the WSDL file, e.g. <wsdlLocation>/wsdl/MyWSDL.wsdl</wsdlLocation>
Tried most of the solutions from this thread
Thanks in advance
I think I was able to find a solution thanks to this SO Thread. Evidently the answer depends on the version of the jaxws tool being used in maven (jaxws-maven-plugin). The project (which I inherited) explicitly asked for version 1.12 (which invoked JAX-WS RI 2.1.7-b01-), using this version of the tools I was able to use the '<wsdlLocation>classpath:wsdl/MyWSDL.wsdl</wsdlLocation>' solution in the thread mentioned. Once I noticed that the pom was using an explicit version I removed that the jaxws was updated (using JAX-WS RI 2.2.10) but then the 'classpath' solution stopped working. I switched to the other option mentioned in the thread '<wsdlLocation>/wsdl/MyWSDL.wsdl</wsdlLocation>'
I did a quick test and this seemed to have solved the problem (in both my dev machine and my test site).
Thank you

Spring Boot application + Jolokia - exception during startup

I'm using Spring Boot 1.5.3.RELEASE and Jolokia 1.3.6 (also happens in later versions).
The Jolokia is integrated by adding a dependency:
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
</dependency>
One of our microservices that all share the same architecture fails to start and I see the exception with the following root-cause during the startup:
Caused by: java.io.FileNotFoundException: JAR entry BOOT-INF/lib/jolokia-core-1.3.7.jar!/META-INF/simplifiers-default not found in <MY_JAR_NAME_GOES_HERE>.jar
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:142)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream (JarURLConnection.java:150)
at java.net.URL.openStream(URL.java:1045)
at org.jolokia.util.ServiceObjectFactory.readServiceDefinitionFromUrl(ServiceObjectFactory.java:90)
This exception doesn't happen when I start the application from the IDE, only when I start with java -jar <MY_JAR>.
I looked at the line that produces exception inside the code of Jolokia, and it looks like this:
reader = new LineNumberReader(new InputStreamReader(new URL(pUrl).openStream(),"UTF8"));
So I conclude (after debugging) that new URL(pUrl).openStream() fails to find a jar entry as specified in the aforementioned exception stack trace. I also understand that in IDE it doesn't happen because it works with different classloaders (Spring Boot application uses LaunchedURLClassLoader).
However, I don't see a bug here in the source code: we have a lot of microservices, all are running with the same configurations and it works as expected, in addition, as far as I know this is the documented way for Jolokia integration.
So I suspect some race condition here or something, but I can't really point out exactly what happens here.
Did anyone encounter such a problem? Is there a workaround?
I was getting exactly the same exception. The problem in my case was that the filename had a + (I'm using reckon Gradle plugin to generate the project version). The solution was to rename the file before running it with java -jar.
I'm facing the same problem, with Spring Boot 1.5.22 and default version of jolokia.
I have another app (same version of SpringBoot, jolokia) that did not have the problem... I did not find any differences between the 2 apps...
But I have use that workaround : instruct Spring Boot to extract jolokia jar in order to skip Spring boot nested jar url process for jolokia jar only.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<requiresUnpack>
<dependency>
<artifactId>jolokia-core</artifactId>
<groupId>org.jolokia</groupId>
</dependency>
</requiresUnpack>
</configuration>
</plugin>
see https://docs.spring.io/spring-boot/docs/1.5.x/reference/htmlsingle/#howto-extract-specific-libraries-when-an-executable-jar-runs
With this workaround, jolokia is happy, the /jolokia endpoint is available and Spring Boot Admin jmx tab is active.

Custom property editors not being registered for NetBeans 7.2 on JRE 1.7

I have a large desktop Java application that is being moved from JRE 1.6 to JRE 1.7. The application uses the NetBeans API for GUI and the SLF4J API with a Log4J backend. The application has two deployment methods, a standalone application (run either by Ant or a Launch4j exe) or a web start via a simple custom HTTP server (Jetty and JNLP servlet).
The application has several NetBeans ModuleInstall components that add property editors onto the Java PropertyEditorManager search path at startup. E.g.
ArrayList<String> editorPaths = new ArrayList<String>();
editorPaths.add(LocationEditor.class.getPackage().getName());
editorPaths.addAll(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
PropertyEditorManager.setEditorSearchPath(editorPaths.toArray(new String[editorPaths.size()]));
When I migrated to Java 1.7 (u9) these editors were no longer being found in the application, either standalone or web start deployment. The application started fine and the editors were accessable when started from Eclipse. Curious to see why the standalone failed I added some logging statements to report the search path and set the log4j.configuration property via the Ant startup script. The editors were now available. I then launched the .exe (which doesn't accept command line parameters so the log4j configuration wasn't set) and the editors were gone again.
So the differentiator appears to be setting the log4j.configuration parameter. I changed the build so the standlong Ant and .exe referenced this and they work. The web start though doesn't pass this value on (it is loaded internally in the code) and still fails to find the editors. I also removed the log4j setting from the Eclipse run command and the editors vanish again.
I tried registering against type specifically rather than using the search path but still had no success. I'm using the search path as one optional overrides another modules editors but I don't know the module startup order, so that one appends its path to the start of the lookup while the others append to the end.
I've also tried removing all SLF4J to Log4J mappings and using the SLF4J-Simple instead. This made no difference. Adding the parameter back in makes the code work again. The spring-aspects dependency is pulling in a single Log4J reference.
I have a working solution for standalone and I'm sure I can get the new trick working for the webstart, but this reeks of a bad hack to get things working. I rather figure out the cause for the editors going missing. No exceptions are reported and removing logging from all ModuleInstall objects does nothing. All the code still executes, and this includes other features the ModuleInstall executes so I know they are running.
I'm using NetBeans RELEASE72 and the other dependencies are:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
Update 1
I've tracked the problem down to our custom logging setup. When this section was removed and the simple logger used the problem didn't occur. When this custom configuration was removed and the slf4j-log4j12 connected again I still got the property editors. However when I enabled the custom logging configuration again the editors failed.
The custom logging configuration ensures we have a logging setup even if nothing is specified by the user. There is also some weird statup process that other users activated where the logging can't be activated until after a weaving process. I suspect that maybe the custom logging setting doesn't work with Java 1.7, or something to do with replacement of default logging handlers redirecting to our custom logging.
In any case it looks like an internal mess, not much the internet can help with.
I'd left the problem and finally came back to it. The problem is that the PropertyEditorManager is now no longer a global singleton, but is a thread local singleton. The search path is registered in a ThreadLocalContext in JDK 1.7, presumably to prevent thread synchronisation issues. However the NetBeans ModuleInstall was being executed on the main thread, and then the property readers were being read on the AWT thread. This meant the AWT thread didn't find any of the property editors.
As a fix I just used the SwingUtilities.invokeLater() to register the property editor path.
I have no idea what caused the other symptons to show.
I have just been tracing a similiar problem;
when I run my NetBeans RCP 7.3 app under java 1.7.0_25
org.netbeans.beaninfo.editors.DateEditor is no longer available to my GUI Property Sheets.
As you suggest, I have worked around the problem by including this code into my GUI module's Installer
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run() {
NodeOp.registerPropertyEditors();
}
});
This solves the problem for now, but it feels kind of hacky ...

Categories