How to use the SCIM API war file - java

I'm trying to extend some features to the scim api that are not supported.
I've added the following maven dependencies from WSO2 Nexus repository:
<dependency>
<groupId>org.wso2.carbon.identity.inbound.provisioning.scim</groupId>
<artifactId>identity-inbound-provisioning-scim</artifactId>
<version>5.1.4-SNAPSHOT</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.inbound.provisioning.scim</groupId>
<artifactId>org.wso2.carbon.identity.scim.provide</artifactId>
<version>5.1.4-SNAPSHOT</version>
<type>war</type>
<classifier>classes</classifier>
</dependency>
I've identified that I need to change the org.wso2.carbon.identity.scim.provider.resources.SCIMUserManager (and its UserStoreManager), and also add a new endpoint in the org.wso2.carbon.identity.scim.provider.resources.UserFeature.
However, these are located within org.wso2.carbon.identity.scim.provider but it seems that the war dependency hasn't any classes attached (and the maven 'classifier' tag is in vain), therefore I can't import or inherit those classes.
So, how can I extend the SCIM Api by using the org.wso2.carbon.identity.scim.provider library but managed by Maven?

I may not understand your question well. Anyway, You can change scim endpoint (wso2.war) file and put into repository/deployment/server/webapp directory. Also, you can find the class inside WEB-INF directory.

Related

Incorrect class is getting referenced in the final war file

My project has many jars. Two jars have a specific class with same name. Both the jar contains a class named Response. One of the Response class in jar A has a method abc(). I am creating the reference of this class in a Service class and calling this method abc(). When I generate the war file using maven and run the project in my local system Tomcat which is integrated with the Eclipse, the method is found and there is no exception. But when I deploy the same war file in external AWS Tomcat, I am getting java.lang.NoSuchMethodError. This must be because in the war file, the reference must belong to the class in another jar which does not have the method abc(). I cannot remove these classes as both are used.
Help.
If you want only A's class to be included inside your uber jar, I believe you can exclude the class from jar B to be wrapped up inside you uber jar by using something along the lines of the following directive inside yuor POM file :-
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>${hadoop.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
</exclusion>
</exclusions>
</dependency>
The above directive will include all the dependency jars inside hadoop client core jar except for the commons-math3, so if you want to use a newer version (or say different version) of apache commons-math3, you can add that explicitly as a dependency inside your POM without having to worry about if the commons-math3 from hadoop core library would be wrapped up inside your uber jar

Is it possible to include only the used classes in a war file with maven build?

Say I have this dependency in my pom.xml file:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
When I do a
clean install
all the javaee-api-6.0.jar will be included in the war file under WEB-INF\lib folder.
Is it possible that instead of including the whole jar, only classes that I use and their dependencies are included?
If you're deploying into a Java EE application server, that entire JAR is already provided by the application server, and can be omitted from the WAR file. You can accomplish this by putting it into the provided scope:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
That makes that dependency available for compilation and test execution, but will not package it into the WAR.
In contrast, trying to determine which individual classes you need so you can only include their class files is an ultimately pointless endeveor. The JVM only loads classes when they are used - that is, unused classes are not loaded.
It is generally impossible to identify the used classes at compile time due to reflection. For instance, consider:
System.console().printf("Please specify the implementation class to use");
String className = System.console().readLine();
FooService service = (FooService) Class.forName(className).newInstance();
service.work();
You can get the JVM to log which classes are loaded, but different executions can use different classes ...
It's not a viable option - at least not in maven, although You know which classes You are using, but You don't know what are the dependencies for each class that You imported - so it might be impossible satisfy it's requirements. This is why we are using tools like maven - to ease the process importing a library.
Read some more about reduce size of built project and see what are Your options there
Except for UberJAR, Your biggest chance (IMHO) would be to identify libraries that are provided by the container, and use provided scope for them.
You also could integrate 3rd party tools like ProGuard
You could use exclusions.
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<exclusion>
<groupId>...</groupId>
<artifactId>...</artifactId>
</exclusion>
</dependency>
But I don't think you could exclude at class-levels. This only excludes dependencies useful when there are conflicting dependencies in your project.
It is really not a viable option in my opinion ,as its almost impossible to know internals what all classes are required at runtime until and unless you are seeing the,implementation of all the,3rd part apis that you are using.
I also think the whole idea behind the maven is to ease the development and build process so that you won't have to do any effort in identifying the artifacts that are required at runtime or compile time. Maven will automatically figure out that for you.

java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE from Mashape Unirest in Java application

I have a Maven Java project that uses Mashape Unirest for sending HTTP requests to other URLs. I am currently writing an integration test (using TestNG) that sends a normal HTTP request using Unirest. When I run the integration test through Maven (via the Failsafe plugin), the request is sent out successfully. However, when I try to run the integration test via Eclipse, I keep on getting the following error:
FAILED: getCurrentTimeTest
java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56)
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:72)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:84)
at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:59)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:487)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:147)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:136)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:112)
at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:726)
at com.mashape.unirest.http.options.Options.refresh(Options.java:41)
at com.mashape.unirest.http.options.Options.<clinit>(Options.java:27)
at com.mashape.unirest.http.HttpClientHelper.prepareRequest(HttpClientHelper.java:141)
at com.mashape.unirest.http.HttpClientHelper.requestAsync(HttpClientHelper.java:80)
at com.mashape.unirest.request.BaseRequest.asStringAsync(BaseRequest.java:56)
at ...
I am also able to reproduce this error using a basic Java application script.
I have made sure that the dependencies I am using in my pom.xml file are the latest and greatest, as seen below:
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.3.2</version>
</dependency>
I have also checked out the source code of BasicLineFormatter.java, both from the source file downloaded to Eclipse and from Apache's Httpcore Github repo. In the Github repo, notice how the INSTANCE field is defined for the 4.3.x branch and the trunk branch, but not in older branches like 4.2.x. However, I am indeed using version 4.3.2 in my project, so I should be using a JAR file for Httpcore that has the latest version of BasicLineFormatter. I know that, based on the Maven Dependencies JAR files that are in my project, that I am indeed using the latest versions of these Apache dependencies, not the older versions specified as downstream dependencies of my project.
I have checked other various SOF and blog posts about this issue, such as Mashape Unirest Java : java.lang.NoClassDefFoundError and this blog post too, but they all seem to be talking about solving the NoSuchFieldError problem for Android. However, I'm dealing with a standalone Java application, not an Android application.
I am at a loss in determining how to troubleshoot this issue. Anyone have any idea what I need to do?
UPDATE
Instead of showing my test case, I will reduce the illustration of a reproduction of this problem to just a simple one-liner Java application, because the problem exists with any Java application or test case run through Eclipse, not just one particular test:
System.out.println(Unirest.get("http://www.google.com").asStringAsync().get().getBody());
Normally, this should print the HTML of the Google home page, but I instead get the NoSuchFieldError stack trace.
FIXED!
The problem was that the AWS SDK (it's on my classpath because I'm developing for Elastic Beanstalk) had a conflicting JAR file. Using Oleg's solution (thanks BTW), I printed the following output in a unit test:
jar:file:/some/path/aws-java-sdk/1.7.1/third-party/httpcomponents-client-4.2.3/httpcore-4.2.jar!/org/apache/http/message/BasicLineFormatter.class
I'll have to rearrange my classpath so that AWS SDK is no longer conflicting.
The only plausible explanation to this problem is there is an older version of HttpCore on the classpath (unless you also want to consider a possibility of green men from Mars messing with your computer remotely from a flying saucer).
You can add this snippet to your code to find out what jar the class gets picked up from. This might help find out why that jar is on your classpath in the first place.
ClassLoader classLoader = MyClass.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);
This basically tells me that in my case the jar resides in the local maven repository and likely to have been added to the classpath by Maven
jar:file:/home/oleg/.m2/repository/org/apache/httpcomponents/httpcore/4.3.1/httpcore-4.3.1.jar!/org/apache/http/message/BasicLineFormatter.class
As already mentioned by previous comments, It's mainly because of the conflicting versions of httpcore jar, the static field INSTANCE is been added to BasicLineFormatter class in versions > 4.3.1, Though you might have added the latest version of the httpcore jar in your dependencies, but its highly possible that other (lower) version of jar is getting picked up.
So, first to confirm that, wrong jar is getting picked up, Use the following line of code -
ClassLoader classLoader = <Your Class>.class.getClassLoader();
URL resource = classLoader.getResource("org/apache/http/message/BasicLineFormatter.class");
System.out.println(resource);
If this prints, the lower version of the jar, then it's confirmed that it's picking the lower version of the httpcore jar (May be from other dependencies of your project),
Solution -
Add following maven/gradle dependencies at the top of dependency list (Or above the other project dependency which caused the conflict) -
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
I faced the same exception using unirest:
java.lang.NoSuchFieldError: INSTANCE
at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52)
at com.mashape.unirest.http.options.Options.refresh(Options.java:55)
at com.mashape.unirest.http.options.Options.<clinit>(Options.java:36)
And found it was due to DefaultConnectionKeepAliveStrategy.INSTANCE; and the conflicting jar was apache-httpcomponents-httpclient.jar in my classpath. Adding this post to help anyone who faces similar exception
I got this Exception: Caused by: java.lang.NoSuchFieldError: INSTANCE
Solution:
This happens if you have two different version classes in your classpath…. […], So I first find that class (one version of class), click that class, select build path, then I click remove from build path.
if you are using aws sdk this error occurs because of dependency mismatch.
To avoid this error do the following:
1.Put the dependecies in the required order aws sdk and the end preferably
2.Add shade plugin to the project
This solved my problem
you can refer to my answer in
HTTPClient Example - Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
my case is i have httpclient-4.4.1.jar, and httpcore-4.4.1.jar in my class path, but JVM loaded BasicLineFormatter from httpcore-4.0.jar

How to configure Maven to use GWT module sources for compiling but do not include them in final JAR/WAR?

I have a GWT project and I want to use some other in house GWT libraries as dependencies.
We do not want to include sources in our final build. Most open source GWT libraries include sources in the JAR, but we want to keep sources separate, use them to compile, then throw them away.
Is there a way to do this with Maven?
Set the scope to provided
<dependency>
<groupId>com.you.gwt</groupId>
<artifactId>gwt-ui</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
Brad's answer will fix the problem in a very narrow scenario. Setting the scope to provided totally avoids the jar from being pushed into War's lib. This is not what you would need in use case of the "lib" on to server side code. This usually happens
1) Constants.
2) DTO's/Beans.
3) RPC service interfaces
4) Request Factory proxy declarations
You have to have a mix of approaches.
1) Brad's approach when the "lib" in purely client and has no chance of being used in server clode.
2) Modularize code to have Constants/DTO's/Proxy/RF related interfaces and any such code in a project that generates two artifact jars.
A) One with classes only - to be used to push stuff in to web-inf/lib i.e scope compile/runtime.
B) Another with sources/classess - to be used with gwt compilation i.e scope provided.
Generating two jars might seem redundant. This is the only sane option i have tried. Keen on check whether there is any other option that will be suggested.
There are two kind of library (package in jar file) in GWT:
Server side library like "gwt-servlet.jar" does not contain source code in jar file and you can add maven dependency like this in your pom:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwtVersion}</version>
<scope>runtime</scope>
</dependency>
Client side library like "gwt-user.jar" which contain source code in jar file, this kind of library does not require to package in your war file and you can add maven dependency like this in your pom:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<scope>provided</scope>
</dependency>
Have a nice time.

How make a Maven package using JPA, but independent of service provider; and later how to plug in my service provider by user of this package?

I'm not sure if it's even possible...
I have some design patterns, which I want in my special Maven package (#1) - all these patterns use javax.persistence. I don't want this package to depend on Hibernate or any other implementation of JPA. Just let it depend on JPA API, as it is defined by JCP.
My second Maven package (#2) is to use this first one, and to specify which JPA implementation to use (f.e. Hibernate).
Now, how do I define my pom.xml for both of these packages (let JPA implementer for #2 package be Hibernate)?
JPA defines a package javax.persistence, it contains Annotations, Interfaces and so on. This package is completely Provider independent. It should contains every thing you need to implement provider independent services basd on JPA.
The only thing you need is to put an dependency to an javax.persistence containing maven artifact in your Maven module #1.
There are several maven artifacts containing this javax.persistence package. For example:
<dependency>
<!-- JPA 1.0 -->
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<!-- JPA 2.0 -->
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.0.0</version>
</dependency>
In you Maven Module #2 you need to put an dependency to Module #1 and an dependency to the JPA provider (for example Hibernate) you like to use.
(If the provider you use, use an other dependency to the javax.persistence package, then you need to exclude one of them.)
Assuming that you don't want Hibernate to be in the compilation path (to prevent developers from using vendor specific extensions), but you still want to have it packaged in the final artifact, you should use the <scope>runtime</scope> when defining your JPA implementation.

Categories

Resources