How to add a folder as a runtime dependency in Gradle - gradle

I want to add a folder, containing some native libraries, as a runtime dependency.
I try the following syntax:
dependencies {
runtime files('path/to/libraries')
}
But instead the content of 'path/to/libraries' is added, while I need to have 'libraries' folder added.
FileCollections interface has filter method, so I tried to create file('path/to') collections and then filter out everything except 'libraries' folder, but the filter method doesn't allow to filter the resulting set, only the input patterns, so it didn't work in my case.
So far I didn't find a way to do that. Maybe I use Gradle in a wrong way, but I do want to have this as a dependency. Any help is appreciated.

Related

TDengine database 3.0.1.7 jdbc connect error [duplicate]

I'm getting a NoSuchMethodError error when running my Java program. What's wrong and how do I fix it?
Without any more information it is difficult to pinpoint the problem, but the root cause is that you most likely have compiled a class against a different version of the class that is missing a method, than the one you are using when running it.
Look at the stack trace ... If the exception appears when calling a method on an object in a library, you are most likely using separate versions of the library when compiling and running. Make sure you have the right version both places.
If the exception appears when calling a method on objects instantiated by classes you made, then your build process seems to be faulty. Make sure the class files that you are actually running are updated when you compile.
I was having your problem, and this is how I fixed it. The following steps are a working way to add a library. I had done the first two steps right, but I hadn't done the last one by dragging the ".jar" file direct from the file system into the "lib" folder on my eclipse project. Additionally, I had to remove the previous version of the library from both the build path and the "lib" folder.
Step 1 - Add .jar to build path
Step 2 - Associate sources and javadocs (optional)
Step 3 - Actually drag .jar file into "lib" folder (not optional)
Note that in the case of reflection, you get an NoSuchMethodException, while with non-reflective code, you get NoSuchMethodError. I tend to go looking in very different places when confronted with one versus the other.
If you have access to change the JVM parameters, adding verbose output should allow you to see what classes are being loaded from which JAR files.
java -verbose:class <other args>
When your program is run, the JVM should dump to standard out information such as:
...
[Loaded junit.framework.Assert from file:/C:/Program%20Files/junit3.8.2/junit.jar]
...
If using Maven or another framework, and you get this error almost randomly, try a clean install like...
clean install
This is especially likely to work if you wrote the object and you know it has the method.
This is usually caused when using a build system like Apache Ant that only compiles java files when the java file is newer than the class file. If a method signature changes and classes were using the old version things may not be compiled correctly. The usual fix is to do a full rebuild (usually "ant clean" then "ant").
Sometimes this can also be caused when compiling against one version of a library but running against a different version.
I had the same error:
Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonGenerator.writeStartObject(Ljava/lang/Object;)V
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:151)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3681)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3057)
To solve it I checked, firstly, Module Dependency Diagram (click in your POM the combination -> Ctrl+Alt+Shift+U or right click in your POM -> Maven -> Show dependencies) to understand where exactly was the conflict between libraries (Intelij IDEA). In my particular case, I had different versions of Jackson dependencies.
1) So, I added directly in my POM of the project explicitly the highest version - 2.8.7 of these two.
In properties:
<jackson.version>2.8.7</jackson.version>
And as dependency:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
2) But also it can be solved using Dependency Exclusions.
By the same principle as below in example:
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
Dependency with unwanted version will be excluded from your project.
This can also be the result of using reflection. If you have code that reflects on a class and extracts a method by name (eg: with Class.getDeclaredMethod("someMethodName", .....)) then any time that method name changes, such as during a refactor, you will need to remember to update the parameters to the reflection method to match the new method signature, or the getDeclaredMethod call will throw a NoSuchMethodException.
If this is the reason, then the stack trace should show the point that the reflection method is invoked, and you'll just need to update the parameters to match the actual method signature.
In my experience, this comes up occasionally when unit testing private methods/fields, and using a TestUtilities class to extract fields for test verification. (Generally with legacy code that wasn't designed with unit testing in mind.)
If you are writing a webapp, ensure that you don't have conflicting versions of a jar in your container's global library directory and also in your app. You may not necessarily know which jar is being used by the classloader.
e.g.
tomcat/common/lib
mywebapp/WEB-INF/lib
For me it happened because I changed argument type in function, from Object a, to String a. I could resolve it with clean and build again
In my case I had a multi module project and scenario was like com.xyz.TestClass was in module A and as well as in module B and module A was dependent on module B. So while creating a assembly jar I think only one version of class was retained if that doesn't have the invoked method then I was getting NoSuchMethodError runtime exception, but compilation was fine.
Related : https://reflectoring.io/nosuchmethod/
Why anybody doesn't mention dependency conflicts? This common problem can be related to included dependency jars with different versions.
Detailed explanation and solution: https://dzone.com/articles/solving-dependency-conflicts-in-maven
Short answer;
Add this maven dependency;
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<rules>
<dependencyConvergence />
</rules>
</configuration>
</plugin>
Then run this command;
mvn enforcer:enforce
Maybe this is the cause your the issue you faced.
It means the respective method is not present in the class:
If you are using jar then decompile and check if the respective version of jar have proper class.
Check if you have compiled proper class from your source.
I have just solved this error by restarting my Eclipse and run the applcation.
The reason for my case may because I replace my source files without closing my project or Eclipse.
Which caused different version of classes I was using.
Try this way: remove all .class files under your project directories (and, of course, all subdirectories). Rebuild.
Sometimes mvn clean (if you are using maven) does not clean .class files manually created by javac. And those old files contain old signatures, leading to NoSuchMethodError.
Just adding to existing answers. I was facing this issue with tomcat in eclipse. I had changed one class and did following steps,
Cleaned and built the project in eclpise
mvn clean install
Restarted tomcat
Still I was facing same error. Then I cleaned tomcat, cleaned tomcat working directory and restarted server and my issue is gone. Hope this helps someone
These problems are caused by the use of the same object at the same two classes.
Objects used does not contain new method has been added that the new object class contains.
ex:
filenotnull=/DayMoreConfig.conf
16-07-2015 05:02:10:ussdgw-1: Open TCP/IP connection to SMSC: 10.149.96.66 at 2775
16-07-2015 05:02:10:ussdgw-1: Bind request: (bindreq: (pdu: 0 9 0 [1]) 900 900 GEN 52 (addrrang: 0 0 2000) )
Exception in thread "main" java.lang.NoSuchMethodError: gateway.smpp.PDUEventListener.<init>(Lgateway/smpp/USSDClient;)V
at gateway.smpp.USSDClient.bind(USSDClient.java:139)
at gateway.USSDGW.initSmppConnection(USSDGW.java:274)
at gateway.USSDGW.<init>(USSDGW.java:184)
at com.vinaphone.app.ttn.USSDDayMore.main(USSDDayMore.java:40)
-bash-3.00$
These problems are caused by the concomitant 02 similar class (1 in src, 1 in jar file here is gateway.jar)
To answer the original question. According to java docs here:
"NoSuchMethodError" Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.
Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
If it happens in the run time, check the class containing the method is in class path.
Check if you have added new version of JAR and the method is compatible.
I fixed this problem in Eclipse by renaming a Junit test file.
In my Eclipse work space I have an App project and a Test project.
The Test project has the App project as a required project on the build path.
Started getting the NoSuchMethodError.
Then I realized the class in the Test project had the same name as the class in the App project.
App/
src/
com.example/
Projection.java
Test/
src/
com.example/
Projection.java
After renaming the Test to the correct name "ProjectionTest.java" the exception went away.
NoSuchMethodError : I have spend couple of hours fixing this issue, finally fixed it by just renaming package name , clean and build ... Try clean build first if it doesn't works try renaming the class name or package name and clean build...it should be fixed. Good luck.
I ran into a similar problem when I was changing method signatures in my application.
Cleaning and rebuilding my project resolved the "NoSuchMethodError".
Above answer explains very well ..just to add one thing
If you are using using eclipse use ctrl+shift+T and enter package structure of class (e.g. : gateway.smpp.PDUEventListener ), you will find all jars/projects where it's present. Remove unnecessary jars from classpath or add above in class path. Now it will pick up correct one.
I ran into similar issue.
Caused by: java.lang.NoSuchMethodError: com.abc.Employee.getEmpId()I
Finally I identified the root cause was changing the data type of variable.
Employee.java --> Contains the variable (EmpId) whose Data Type has been changed from int to String.
ReportGeneration.java --> Retrieves the value using the getter, getEmpId().
We are supposed to rebundle the jar by including only the modified classes. As there was no change in ReportGeneration.java I was only including the Employee.class in Jar file. I had to include the ReportGeneration.class file in the jar to solve the issue.
I've had the same problem. This is also caused when there is an ambiguity in classes. My program was trying to invoke a method which was present in two JAR files present in the same location / class path. Delete one JAR file or execute your code such that only one JAR file is used. Check that you are not using same JAR or different versions of the same JAR that contain the same class.
DISP_E_EXCEPTION [step] [] [Z-JAVA-105 Java exception java.lang.NoSuchMethodError(com.example.yourmethod)]
Most of the times java.lang.NoSuchMethodError is caught be compiler but sometimes it can occur at runtime. If this error occurs at runtime then the only reason could be the change in the class structure that made it incompatible.
Best Explanation: https://www.journaldev.com/14538/java-lang-nosuchmethoderror
I've encountered this error too.
My problem was that I've changed a method's signature, something like
void invest(Currency money){...}
into
void invest(Euro money){...}
This method was invoked from a context similar to
public static void main(String args[]) {
Bank myBank = new Bank();
Euro capital = new Euro();
myBank.invest(capital);
}
The compiler was silent with regard to warnings/ errors, as capital is both Currency as well as Euro.
The problem appeared due to the fact that I only compiled the class in which the method was defined - Bank, but not the class from which the method is being called from, which contains the main() method.
This issue is not something you might encounter too often, as most frequently the project is rebuilt mannually or a Build action is triggered automatically, instead of just compiling the one modified class.
My usecase was that I generated a .jar file which was to be used as a hotfix, that did not contain the App.class as this was not modified. It made sense to me not to include it as I kept the initial argument's base class trough inheritance.
The thing is, when you compile a class, the resulting bytecode is kind of static, in other words, it's a hard-reference.
The original disassembled bytecode (generated with the javap tool) looks like this:
#7 = Methodref #2.#22 // Bank.invest:(LCurrency;)V
After the ClassLoader loads the new compiled Bank.class, it will not find such a method, it appears as if it was removed and not changed, thus the named error.
Hope this helps.
The problem in my case was having two versions of the same library in the build path. The older version of the library didn't have the function, and newer one did.
I had a similar problem with my Gradle Project using Intelij.
I solved it by deleting the .gradle (see screenshot below) Package and rebuilding the Project.
.gradle Package
I had faced the same issue. I changed the return type of one method and ran the test code of that one class. That is when I faced this NoSuchMethodError. As a solution, I ran the maven builds on the entire repository once, before running the test code again. The issue got resolved in the next single test run.
One such instance where this error occurs:
I happened to make a silly mistake of accessing private static member variables in a non static method. Changing the method to static solved the problem.

Gradle Custom String Notation in dependency

I'm creating a global repository for all the artifacts that I'm producing. Right now I've created an S3 bucket as repository where I'm storing the artifacts.
As there is no group (artifacts are global), I ended up duplicating the name as the group so the current notation for a dependency is Name:Name:Version. For this, I've created an extension function that takes two arguments, a name (the dependency that I want to add to the project) and the version.
For example, I would add implementation("Name", "1.0") if I wanted the dependency Name in my project. This is translated to implementation("Name:Name:1.0") and works fine but I feel that it is a little bit ugly and can be confusing, the dependency in the External Libraries tree in IntelliJ shows the dependency as Gradle: Name:Name:1.0, the longer the name is, the uglier it is.
The question is, is it possible to write a custom Notation that let me just do implementation("Name", "1.0") without an extension function so it only shows Gradle: Name:1.0 and everything else is handled in the background?
I have looked at the class ParsedModuleStringNotation and it seems the thing that I would need to change (create my own), but the creation of the objects is hardcoded, I am unsure how to proceed from there.
if you declare S3 repository as flatDir - there is an option for what you are asking
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.dsl.RepositoryHandler.html
flatDir(args)
Adds a resolver that looks into a number of directories for artifacts. The artifacts are expected to be located in the root of the specified directories. The resolver ignores any group/organization information specified in the dependency section of your build script. If you only use this kind of resolver you might specify your dependencies like ":junit:4.4" instead of "junit:junit:4.4".
was able to work as below
repositories {
def s = project.rootDir.toString() + "/lib/"
flatDir dirs: s
mavenCentral()
}
//compileOnly 'javax.jms:jms-api:1.1-rev-1'
compileOnly ':my-jms:1.2'

Deploying BEAN in OSGi plugin

I am currently deploying my custom controls as OSGi plugins and I wanted to do the same thing with my beans. I have tried putting them into the OSGi plugin and it works fine but the only problem I have is the faces-config.
It seems it has to be called faces-config in the OSGi plugin to work but that means i can't use beans in the NSF anymore because it seems to ignore the local faces-config.
Is there a way to change the name of the faces-config in the OSGi plugin?
Something like FEATURE-faces-config.xml?
In the class in your plugin that extends AbstractXspLibrary, you can override "getFacesConfigFiles", which should return an array of strings representing paths within the plugin to additional files of any name to load as faces-config additions. For example:
#Override
public String[] getFacesConfigFiles() {
return new String[] {
"com/example/config/beans.xml"
};
}
Then you can put the config file in that path within your Java source folder (or another folder that is included in build.properties) and it will be loaded in addition to your app's normal faces-config, beans and all.
The NSFs are running as separate, distinct Java applications. The OSGi plugin is running in the OSGi layer, above all those distinct Java applications, as a single code base. Consequently, the faces-config is only at that level.
It's possible to load them dynamically, by using an ImplicitObjectFactory, loaded from an XspContributor. That's what is done in OpenNTF Domino API for e.g. userScope (which is a bean stored in applicationScope of an NSF). See org.openntf.domino.xsp.helpers.OpenntfDominoImplicitObjectFactory, which is referenced in OpenntfDominoXspContributor, loaded via the extension point of type "com.ibm.xsp.library.Contributor".
A few caveats:
You have no control over what happens if you try to register your bean with a name the developer also uses for a different variable in that scope.
Unless you add code to check if the library is enabled, as we do, you'll be adding the bean to every database on the server.
You still need to add the library to the NSF. Unless you also provide a component that those databases will all use, there's no way you can programmatically add it, as far as I know.
It might be easier to skip the bean approach and just add an instance of the Java class in beforePageLoad, page controller class, or however you're managing the backing to the relevant XPage (if viewScope) or application (if sessionScope / applicationScope).

MavenProject: Get the available classes for use on my plugin

I'm loading a Maven project as described here. I'm trying to figure out how I can retrieve the source roots so I can figure out the Java classes I have so my Mojo can use them.
I tried a couple of the methods in there, like getResources or getScriptSources without luck. Any idea?
Thanks in advance!
Edit:
I was asked to elaborate a little bit in what I'm attempting to do, so here it is:
The plugin I'm developing will take the sources in the project and create test cases from those. Unless configured, I want to generate tests for all the classes, and for that, I need to somehow figure out where are my sources so I can configure properly.
Hope that helps.
Here's the repository. I planned on publishing it later but I provided source as requested.
Have you read the plugin developers documentation?
That page will link to Plugins Cookbook which links to Mojo Developer Cookbook which has The maven project, or the effective pom. and gives you access to org.apache.maven.project.MavenProject object via
/** #parameter default-value="${project}" */
private org.apache.maven.project.MavenProject mavenProject;
Alternatively via Java 5 annotations
#Component
MavenProject project;
You can call getCompileSourceRoots() to get a list of the directories that will be used for compilation.
You will also need to do more reading about how to setup inclusion/exclusions. You can use other plugins as examples of how to do this, e.g. maven-compiler-plugin
If you want to use annotations, it is very important to make sure your pom is configured as per using annotations and that you use annotations at the class level as well. Mixing javadoc annotations might not work.
I think the simplest solution would be to define a mojo parameter:
/**
* #parameter default-value="${project.build.sourceDirectory}"
* #required
*/
private File sourceDirectory;
or with new annotation based definition:
#Parameter(required = true, defaultValue="${project.build.sourceDirectory}"}
private File sourceDirectory;
which should give your wished result.

Spring namespaces and placeholder in springs.schemas

Spring-namespaces allows you to define your own structure how spring beans could be configured. Very cool.
I have to use a 3rd party software (Assentis Docbase) which defines in its spring.schemas the following (example below simplified)
http\://com.apress.prospring2/ch07/custom.xsd=custDir:/custom.xsd
Meaning: If user defines in its spring-xml with schema-location: "http://com.apress.prospring2/ch07/custom.xsd" spring will validate this file against custom.xsd.
custDir is a directory OUTSIDE the provided jar. Does anyone have an idea how I can set this custDir to point to a valid path during junit test? I already tried -DcustDir=/pathToXsd/ but it did not work.
If I remove custDir than everything works as expected, but I can not remove it from provided spring.schemas since it is 3rd party software.
Maybe this is an issue how property-files are handled in java but I have no idea.
You may be able to "override" this entry by providing your own custom spring.schemas file with the same entry but with a location to your custom xsd file. The catch is that this is highly dependent on the order in which the spring.schemas are loaded up, but could be worth a try.
Since custDir is not a place holder, you cannot replace it the way you are doing it, I am surprised that the third party schema location is outside of the classpath.
The syntax of spring.schemas I provided in my question is a properitary definition of 3.rd party software. They implemented there own EntityResolver which manually reacts on "custDir:" and starts some magic algorithm. So I came to the following workaround.
You have to create your own my_spring.schemas which must be live in META-INF/. Than you have to make sure that spring loads my_spring.schemas and NOT spring.schemas.
I achieved it with implementing my own TestingContext which is a subclass of ClassPathXmlApplicationContext. In TestingContext I overwrote method protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException and filled it with implementation from org.springframework.context.support.AbstractXmlApplicationContext. The only change I made was to line beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)) to beanDefinitionReader.setEntityResolver(new PluggableSchemaResolver(getClassLoader(), "META-INF/my_spring.schemas). And voila if I use TestingContext my own my_spring.schemas is loaded.
Drawback with this solution is that you have to provide all xsd in your jar because the default name, where spring looks up definitions has been changed.

Resources