Web Service Client in JBOSS 5.1 with JDK6 - java

This is a continuation of the question here:
JBoss - does app have to be compiled under same jdk as JBOSS is running under?
It's different enough though that it required a new question.
I am trying to use jdk6 to run JBOSS 5.1, and I downloaded the JDK6 version of JBOSS 5.1. This works fine and my EAR application deploys fine. However, when I want to run a web service client with code like this:
public static void main(String[] args) throws Exception {
System.out.println("creating the web service client...");
TestClient client = new TestClient("http://localhost:8080/tc_test_project-tc_test_project/TestBean?wsdl");
Test service = client.getTestPort();
System.out.println("calling service.retrieveAll() using the service client");
List<TestEntity> list = service.retrieveAll();
System.out.println("the number of elements in list retrieved using the client is " + list.size());
}
I get the following exception:
javax.xml.ws.WebServiceException: java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage
at org.jboss.ws.core.jaxws.client.ClientImpl.handleRemoteException(ClientImpl.java:396)
at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:302)
at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:170)
at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:150)
Now, here's the really interesting part. If I change the JDK that my the code above is running under from JDK6 to JDK5, the exception above goes away! It's really strange.
The only way I found for the code above to run under JDK6 was to take the JBOSS_HOME/lib/endorsed folder and copy it to JDK6_HOME/lib. This seems like it shouldn't be necessary, but it is.
Is there any other way to make this work other than using the workaround I just described?

Looks roughly as if you ran into the presence of JAX-WS as an official feature of JDK 1.6. Don't copy things to 'lib', copy them to an 'endorsed' directory (one listed in java.endorsed.dirs). This might be helpful.
If you have an up-to-date 1.6, you can get around this the same way that Apache CXF does. See the documentation for information on how to use CXF in a 1.6 environment.

There are various suggestions and explanations in the respective bug report and elsewhere (e.g. here and here). I don't know how well they work.

Information about this issue you can find in JBoss official Installation And Getting Started Guide:
http://docs.jboss.org/jbossas/docs/Installation_And_Getting_Started_Guide/5/html/Installation_Alternatives.html

Related

Spring initializer class not found by Tomcat when using Java 16

I have a very simple Gradle (7.0-rc-1) script to initialise a single Spring 5 "hello world" endpoint using an embedded Tomcat instance. The original code is taken from a random example I found on the internet.
My example Gradle project can be found here.
I'm not sure how it works but somehow the web server knows to call the WebApplicationInitializer.onStartup(ServletContext) method on startup so that Spring is intialised.
This works correctly on Java 8; but fails when I change the following toolchain specification in the Gradle build definition to Java 16.
java {
toolchain {
// languageVersion = JavaLanguageVersion.of(16)
languageVersion = JavaLanguageVersion.of(8)
}
}
When using Java 8, Spring is intialised correctly and the endpoint works.
When using Java 16, The onStartup() method is not called, so Spring is not initialised and the endpoint doesn't work (though Tomcat is still started and responds with an error).
The logging shows a message like, there is no stacktrace though:
INFO: No Spring WebApplicationInitializer types detected on classpath
What do I need to do to make this work on Java 16?
Note that I don't want to use spring-boot, please don't suggest it.
I've found a workaround that gets Spring configured and responding to the /hello endpoint. But I don't know why it works or if it's the right thing to do.
If someone can answer the question with an explanation of what's going on with Java 16 - I will gladly mark that as the accepted answer.
Workaround
My work around is to programmatically add the ServletContainerInitializer class.
So where before I was just calling the addWebapp() method:
tomcat.addWebapp("", appBase);
I now add my Spring intializer explicitly:
Context appContext = tomcat.addWebapp("", appBase);
appContext.addServletContainerInitializer(new SpringAppConfig(), null);
Updated code on Github.

Include deployment timestamp into JSP page

I'm writing web applications with Java EE 7 using JSP and servlets, deploying to a local Wildfly 10 server.
To help me developing and testing my code, it would be useful to include a little timestamp into the displayed webpage, so that I can directly see when the version I'm looking at in my browser was deployed.
That would prevent me from both forgetting to deploy changes as well as from looking at old cached versions instead of the latest one.
How can I display the date and time when a Java EE web app got deployed to my Wildfly server directly on the webpage?
My IDE is Eclipse Neon for Java EE, if that matters.
This is not deploytime, but starttime of the application. Maybe it is useful for your purpose. You can inject the class and use it to display data on your page.
#Startup
#Singleton
public class Deploytime
{
private LocalDateTime starttime;
#PostConstruct
public void init() {
starttime = LocalDateTime.now();
}
}
Apart from that I can only think of Maven Git Plugin which can generate things like buildtime, commit id, ... into a propery file, which you can also use to display it on the page (if you use git/maven).
There is likely an API to do this too but you can get the server start time from the command line. Assuming that you have your admin user name and password set up (i.e. you've run something like add-user.sh) you could run:
curl --digest "http://user:password#localhost:9990/management/core-service/platform-mbean/type/runtime?operation=attribute&name=start-time"
Of course, this is not Java - you'd either have to do a System.exec on this or use something like HttpClient. Additionally, the big issue here is that you've got to have your admin username and password available to the code.
The Wildfly HTTP Management Docs go into some more detail with a small sample Java snippet.
EDIT:
Sorry - should not have assumed that the server restarts on deployment. You can get deployment time for a web app with:
curl --digest "http://user:password#localhost:9990/management/deployment/test-1.0-SNAPSHOT.war/?operation=attribute&name=enabled-time"
However, that seems more difficult than the other answer of running something at startup. I don't see a deployment time for a webapp as that time would have to be stored somewhere in case of server restarts.

Jboss wildfly 10 strange issue loading libraries

I'm developing a custom application for IBM BPM that uses these libraries: Jace.jar, pe.jar, log4j.jar, stax-api.jar, xlxpScanner.jar and xlxpScannerUtils.jar that are used to call a web service.
When I create a java project and add those libraries, it works fine. It also works ok when I create a dynamic web project using tomcat 8 as server; but when using jboss I don't get the expected result when calling the web service. So, does anybody know how to disable the modules that use these libraries? Or where to find information about it?
I want my application to be server independent.
This is my code:
try {
VWSession vwSession = new VWSession("userName", "userPass", "connPt");
vwSession.isLoggedOn(); /* It's loaded with 'false' value in jboss.
In tomcat it's loaded with 'true' value */
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.FATAL, "Details: ", e);
}
To create an application that is server agnostic, you need to strictly adhere to Java EE specification. Meaning, use only those jars that are bundled as part of the Java EE version you are using. Then too, there are certain deployment descriptors specific to a given application server that would need to be used in some cases. For example - jboss-deployment-structure.xml, ibm-application-bnd.xml, etc.
In your case, xlxpScanner.jar is not a part of the Java EE spec, so making the application server independent is not possible with the current settings. You could look for a replacement of the part of this jar you are using with something Java EE has. In short, get rid of this jar alongwith xlxpScannerUtils.jar.
Alternatively, if you want jboss to run the application properly, add all the jars in a module and give it to the EAR/WAR using jboss-deployment-structure.xml. Details can be found here.

GlassFish: email log handler

We need to send mail from a log handler in GlassFish v3.1.2.2.
We've tried to use smtphandler-0.6 and -0.7 with limited success. We install the jarfile to domain/lib/ext, and configure smtphandler's properties in domain/config/logging.properties. We've tried two ways of satisfying smtphandler's reliance on mail imports: 1) Editing its manifest classpath to point to ../../../../modules/javax.mail.jar, and 2) Putting javax.mail.jar in domain/lib/ext alongside the smtphandler jar. (We prefer the former approach so that the same javamail classes are used throughout the system. But it seems to make no difference, no worky either way.)
With either of these arrangements the behavior is the same:
The handler loads ok as shown by the JVM's verbose:class output.
Sometimes it sends mail for errors and warnings that occur during domain startup (like the expired certificate). Other times it fails as described below before ever sending mail.
It always fails once we've deployed our application and logged some application errors. We can tell that the handler is invoked - that's evidenced by the debugger and some primitive System.out "logging".
The root problem is a NoSuchMethodException: com.sun.mail.smtp.SMTPTransport.[init](Session, URLName). The failure to find the c'tor means the transport object can't be created; that eventually manifests as a NoSuchProtocolException.
We can see that the SMTPTransport class is loaded and that it has the requested c'tor. Our best theory is that class loading is somehow involved, but we've not been able to figure out exactly how. (Yet. We're working that angle now.)
Questions:
Are we deploying the handler to the correct location (domain/lib/ext) ?
Why does it (sometimes) send mail during an (empty, no apps) domain startup, but fail for logs emitted by our application? That's a race condition, surely, but what are those threads doing that occasionally works for a bit then reliably fails?
Are we right to think that all these indications together imply a class loading issue?
We've reproduced these symptoms on GlassFish versions 3.1.2.2 and 4, with JavaMail 1.4.4 and 1.5.
Thanks in advance for any help.
Looks like a bug was reported for this NoSuchMethodException when attempting to install log handler in GlassFish server. This issue was raised with the JavaMail team under Bug K6668 | GH144 - skip unusable Store and Transport classes which is fixed in JavaMail 1.5.3. Upgrading the JavaMail module in glassfish and all other copies deployed should correct the issue. It is also helpful to start glassfish with "glassfish/bin/asadmin start-domain -v" so you can see all bootstrapping messages.
•Are we deploying the handler to the correct location (domain/lib/ext)
Yes. You can deploy to domain/lib/ext but you have to include JavaMail 1.5.3 so you find the correct transport service. Otherwise, you can deploy the jar to the modules dir and add the HK2 metadata to make the smtphandler look like a service. This can be done by including new jar or modifying the existing smtphandler jar.
For GlassFish 3, the file META-INF/inhabitants/default must be added containing the following:
class=smtphandler.SMTPHandler,index=java.util.logging.Handler
For GlassFish 4, the file META-INF/hk2-locator/default must be added containing the following:
[smtphandler.SMTPHandler]
contract={java.util.logging.Handler}
scope=javax.inject.Singleton
The jar then has to be placed in the glassfish/modules folder along with upgrading javax.mail.jar.
Another option is to subclass smtphandler to look like a HK2 log handler service and add a preDestroy method to trigger the email on shutdown. This is described in the Oracle GlassFish Server 3.1 Administration Guide Part I section 7 titled Adding a Custom Logging Handler.
Under GlassFish 4 there are two different ways to locate a handler in the logging.properties. Handlers placed in domain/lib/ext use the standard handlers key in the properties file. Handlers placed in the glassfish/modules as a HK2 Service are loaded using the handlerServices key in the properties file.
#GF3 ext/endorsed or OSGI. GF4 ext/endorsed only.
handlers=smtphandler.SMTPHandler
#GF4 OSGI only, 'handlerServices' should not contain any whitespace characters between handlers.
handlerServices=com.sun.enterprise.server.logging.GFFileHandler,smtphandler.SMTPHandler
•Why does it (sometimes) send mail during an (empty, no apps) domain startup, but fail for logs emitted by our application? That's a race condition, surely, but what are those threads doing that occasionally works for a bit then reliably fails?
Difference in context class loader between messages logged by GF vs your web app. The CCL is used in JavaMail to locate the transport. Patching the 'sendBuffer' method should fix the behavior:
#Override
protected void sendBuffer() {
final Thread thread = Thread.currentThread();
ClassLoader ccl = null;
try {
ccl = thread.getContextClassLoader();
thread.setContextClassLoader(
javax.mail.Transport.class.getClassLoader());
} catch (SecurityException ignore) {
}
try {
super.sendBuffer();
} finally {
try {
thread.getContextClassLoader();
thread.setContextClassLoader(ccl);
} catch (SecurityException ignore) {
}
}
}
•Are we right to think that all these indications together imply a class loading issue?
Yes. The only way to really make this work right is to subclass or patch the smtphandler to look like an HK2 component and modify the CCL.
We need to send mail from a log handler in GlassFish v3.1.2.2.
We've tried to use smtphandler-0.6 and -0.7 with limited success.
Disclaimer: I'm a content developer for MailHandler included with JavaMail project.
An alternative to the smtphandler is the com.sun.mail.util.logging.MailHandler included with the JavaMail reference implementation.
Under GlassFish 4 you have to have glassfish/modules/javax.mail.jar that is JavaMail 1.5.3 or newer. An updated version can be downloaded from the JavaMail API homepage and can be used to replace the version bundled with GlassFish.
Next you have to modify the logging.properties for the domain. Here is a sample configuration you can include to get you started.
#Ensure no whitespace between handler class names.
handlerServices=com.sun.enterprise.server.logging.GFFileHandler,com.sun.mail.util.logging.MailHandler
com.sun.mail.util.logging.MailHandler.subject=com.sun.mail.util.logging.CollectorFormatter
#com.sun.mail.util.logging.CollectorFormatter.format=GlassFish 4.x:{0}{1}{2}{4,choice,-1#|0#|0<... {4,number,integer} more}
#com.sun.mail.util.logging.CompactFormatter.format=[%4$-7.7s] %7$#.140s
com.sun.mail.util.logging.MailHandler.level=WARNING
com.sun.mail.util.logging.MailHandler.filter=com.sun.mail.util.logging.DurationFilter
com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
com.sun.mail.util.logging.MailHandler.mail.smtp.host=some-smtp-host
#com.sun.mail.util.logging.MailHandler.mail.user=some-user
#com.sun.mail.util.logging.MailHandler.authenticator=some-password
com.sun.mail.util.logging.MailHandler.mail.from=app#server.com
#com.sun.mail.util.logging.MailHandler.mail.sender=team#list.com
com.sun.mail.util.logging.MailHandler.mail.to=devs#bugfixers.com
com.sun.mail.util.logging.MailHandler.verify=resolve
com.sun.mail.util.logging.MailHandler.mail.smtp.quitwait=false
com.sun.mail.util.logging.MailHandler.mail.smtps.quitwait=false
com.sun.mail.util.logging.MailHandler.mail.smtp.connectiontimeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtps.connectiontimeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtp.timeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtps.timeout=45000
For GlassFish 3 you have to install JavaMail (javax.mail.jar) under the domain/lib/ext or glassfish/lib/endorsed and test that this doesn't break any of your applications. This classloader configuration also works under GlassFish 4 and allows combining the MailHandler with MemoryHandler which can emulate the behavior of the smtphandler.
Next you have to modify the logging.properties for the domain. You can use the same sample as the GlassFish 4 except that you have to use the standard handlers tag instead of the handlerServices.
handlers=java.util.logging.MemoryHandler
java.util.logging.MemoryHandler.target=com.sun.mail.util.logging.MailHandler
java.util.logging.MemoryHandler.size=512
java.util.logging.MemoryHandler.level=INFO
java.util.logging.MemoryHandler.push=WARNING
com.sun.mail.util.logging.MailHandler.capacity=512
com.sun.mail.util.logging.MailHandler.level=INFO
com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
com.sun.mail.util.logging.MailHandler.filter=com.sun.mail.util.logging.DurationFilter
com.sun.mail.util.logging.DurationFilter.records=512
com.sun.mail.util.logging.DurationFilter.duration=5*60*1000

java.lang.NoClassDefFoundError in NetBeans jersey restful web services on GlassFish for JodaTime library

Hi I am currently using the JodaTime library in my NetBeans restful web services on GlassFish Server using Jackson libraries.
I get a java.lang.NoClassDefFoundError for org/joda/time/ReadablePartial when I try to create an instance of a class that uses the JodaTime library in one of the Resource files.
E.g:
In the studentResource file:
Controller c = new Controller();
Where the Controller class imports and uses JodaTime libraries
I have checked that the libraries I needed are in the project.
In fact, if I run a separate project outside of the restful web services, everything runs smoothly. Is there an additional classpath issue that I have to address?
In case someone stumbles upon the same problem using Spring:
This problem comes up if you are trying to map JSON to a Java object using Jackson either via #RequestBody annotation on controller parameter or manually deserializing using an ObjectMapper().readValue(json, Class.class). Everything works fine on local machine but when deploying application to GlassFish deserialization fails.
Keeg's workaround to copy Joda-Time.jar to glassfish/modules and restarting fixes the issue.
There seems to be a bug open on Jira about this issue:
https://java.net/jira/browse/GLASSFISH-20808
Just in case someone else stumbles upon this problem, we had a similar issue with the combination of Glassfish 3.1.1, Jersey and use of Joda time. Stacktraces like this:
Caused by: java.lang.ClassNotFoundException: org.joda.time.ReadableInstant not found by jackson-mapper-asl [128]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
etc.
The workaround I just found was dumping a copy of our joda-time jar into glassfish/modules. Not exactly pretty, but...
Ok I found the solution. Apparently all I needed to do was to move the jar file up in the list of libraries/jar files. I do that in the library tab in the project's properties. More specifically, the jar file has to be moved above the REST libraries.

Categories