Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with tomcat version of GWT 2.11 for class javax.validation.Path #9942

Open
PriyaKolekar opened this issue Mar 20, 2024 · 8 comments
Open

Comments

@PriyaKolekar
Copy link

Hi Team,

We are working on development environment with Tomcat 10 where third-party jar jakarta.validation-api.jar has been updated to tomcat specific version where package structure is changed from javax.validation to jakarta.validation.

When GWT 2.11 with tomcat specific jars(Gwt-servlet and requestfactory-server.jar) are deployed, it is trying to find javax.validation.Path with below stack trace-

Exception while dispatching incoming RPC call java.lang.NoClassDefFoundError: javax/validation/Path
java.base/java.lang.Class.forName(Class.java:467)
  at com.google.gwt.user.server.rpc.SerializationPolicyLoader.loadFromStream(SerializationPolicyLoader.java:217)
  at com.google.gwt.user.server.rpc.jakarta.RemoteServiceServlet.loadSerializationPolicy(RemoteServiceServlet.java:98)
  at com.google.gwt.user.server.rpc.jakarta.RemoteServiceServlet.doGetSerializationPolicy(RemoteServiceServlet.java:437)
  at com.google.gwt.user.server.rpc.jakarta.RemoteServiceServlet.getSerializationPolicy(RemoteServiceServlet.java:251)
  at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.prepareToRead(ServerSerializationStreamReader.java:505)
  at com.google.gwt.user.server.rpc.jakarta.RPC.decodeRequest(RPC.java:241)

As this package has been changed in our environment to jakarta.validation.path, GWT source code is unable to find this class, giving NoClassDefFoundError.

Also we can find several references of javax.validation.Path in gwt-user and other jar source code under GWT 2.11 jars.

My queries are -

  1. Has anyone come across such error, if yes, what is workaround thats working.
  2. As javax packages are outdated and replaced by jakarta, are those references deliberately kept is there a plan to update them. Also, how this failure can be addressed.
  3. One solution I could see for older releases, is to add dependency for gwt-servlet-deps.jar, but that is not viable solution to us, as we are moving away from javax packages due to tomcat upgrade.

Any immediate help will be appreciated.
Thanks!

@FrankHossfeld
Copy link
Member

FrankHossfeld commented Mar 20, 2024

Are you using this dependency on the server side?

<dependency>
    <groupId>org.gwtproject</groupId>
    <artifactId>gwt-servlet-jakarta</artifactId>
    <version>2.11.0</version>
</dependency>

instead of this one:

<dependency>
    <groupId>org.gwtproject</groupId>
    <artifactId>gwt-servlet</artifactId>
    <version>2.11.0</version>
</dependency>

@PriyaKolekar
Copy link
Author

Yes, we are using gwt-servlet-jakarta and requestfactory-server-jakarta versions

@FrankHossfeld
Copy link
Member

Oh, yes, I see: com.google.gwt.user.server.rpc.jakarta.RPC.decodeRequest(RPC.java:241)

@FrankHossfeld
Copy link
Member

Have you tried to add the java.validation.validation-api dependency?

@PriyaKolekar
Copy link
Author

Yes, jakarta.validation-api dependency has been added. But now jakarta.validation-api has also moved packages from javax.validation.Path to Jakarta.validation.Path , so javax.validation.Path is no longer accessible for GWT

@niloc132
Copy link
Contributor

GWT-RPC does not actually use javax.validation (though request-factory does), so there is no requirement that your server use javax.validation at all - if you are seeing this error, it indicates that your own client project's RemoteService types reference javax.validation in some way (very likely as annotations on fields/properties in your DTOs/beans).

On the other hand, GWT's client APIs for validation have been deprecated for many years ("Deprecate JSR 303 Bean Validation support (javax.validation, c.g.g.validation). The code hasn’t been maintained for years."). There are other projects in the ecosystem (the main one here) that can be used instead, with updates to newer versions of the api, including jakarta support.

Assuming what I've said so far is correct, you should be able to update your own project's use of javax.validation to jakarta.validation, and this error will go away. Alternatively, you can keep sending javax.validation-decorated types, and add the validation-api jar to your server, so that it can safely deserialize those types.

Adding jakarta.validation support in a backward-compatible way is tricky - #9844 is filed to track this, but is looking for a volunteer/sponsor to lead it at this time.

@PriyaKolekar
Copy link
Author

@niloc132, thanks for quick response. In continuation with your suggestions, I have below queries -

  1. In gwt-user.jar, several classes under package - "com.google.gwt.validation" refer javax.validation classes. Also com.google.gwt.validation.Validation.gwt.xml inherits javax.validation.Validation. Can you please let me know significance of those classes and where they are actually used.

  2. As in your reply "it indicates that your own client project's RemoteService types reference javax.validation in some way (very likely as annotations on fields/properties in your DTOs/beans).", are there any specific annotations or properties to be looked for. because directly I couldn't find references for "javax.validation" in application source code.

@niloc132
Copy link
Contributor

  1. gwt-user.jar must not be present on your server classpath (likewise, gwt-dev.jar must not be present), so this should be a non-issue for your server code. In your case, using RPC and jakarta, only gwt-servlet-jakarta.jar should be on the server classpath. That still has some validation apis, but they are specific to requestfactory (which is not used for RPC).
  2. Something has a field either typed as javax.validation.Path, or some type that extends from that interface. That's the best I can guess right now with the information provided.

This is the top line in the provided stack trace:

Class<?> clazz = Class.forName(binaryTypeName, false,
contextClassLoader);

The GWT-RPC wiring here is loading the serialization policy from disk, iterating through the classes mentioned in that policy, and examining each class (without initializing it). The class that is failing, according to your error, is javax.validation.Path - by itself not serializable, but it is possible that you have subclasses that are serializable, and that you somehow are referencing those in your shared DTO types. Beyond that, without seeing code, I can't easily guess.

If this is something accidental like using raw generics or a field of type Object/Serializable (against advise of documentation and compiler warnings), your application is written to ask any possible type to be serialized, and either the app will need to be updated to be more specific (and will get smaller compiled output as a result..), or you need to make sure that the classes which the client might be using are also available to the server. If something like this is happening, correcting the code is the best option, but adding javax.validation types to the server classpath will not mean they will be used, only that they will be available. You might also look into excluding any such types, to keep them from being used as potential candidates for serialization, see RemoteService.gwt.xml's rpc.blacklist configuration property:

<!--
Contains regular expressions, optionally prefixed with '+' or '-'.
Each type being considered for serialization is tested against the
list of expressions in order, and if there is a match it is added to the
blacklist (if the prefix is '-' or no prefix is present), or removed (if
the prefix is '+'). If multiple entries in the list match a supplied
class, then the last one 'wins.' For generic types, the regular
expression is applied to just the base class's fully qualified name.
-->
<define-configuration-property name="rpc.blacklist" is-multi-valued="true" />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants