Node JS Trireme include module - java

I'm running Node JS with https://github.com/apigee/trireme from Java, inside the JVM. I have a directory that looks as following:
node/
-test_file.js
-test_somemodule.js
-somemodule/
-somemodule/index.js
-somemodule/...
I have no problem running the test_file.js using this code:
#Test
public void shouldRunTestScript() {
try {
NodeEnvironment env = new NodeEnvironment();
// Pass in the script file name, a File pointing to the actual script, and an Object[] containg "argv"
NodeScript script = env.createScript("my-test-script.js",
new File(Settings.getInstance().getNodeDir() + "/my-test-script.js"), null);
// Wait for the script to complete
ScriptStatus status = script.execute().get();
// Check the exit code
assertTrue("Exit code was not 77.", status.getExitCode() == 77);
} catch (NodeException | InterruptedException | ExecutionException ex) {
Logger.getLogger(TriremeTest.class.getName()).log(Level.SEVERE, null, ex);
fail("Trireme triggered an exception: " + ex.getMessage());
}
}
In the file test_somemodule.js I include the index.js.
require('somemodule/index.js');
When I try to run that file, it can't find the file in the require.
I have no knowledge about Node JS, so I'm not familiar with the module loading. I already tried setting NODE_PATH, only to get
Error: Cannot find module 'request'
It seems like I can't obtain the NODE_PATH from Trireme, and if I overwrite it, Trireme fails to run. I'm out of ideas on how I could get an Node JS module loaded in Trimere. Any help appreciated.
Edit: I changed the require to ('./somemodule/index.js'), which works. So setting the NODE_PATH would have done the job too. I just found out the error came from an missing dependency.
"dependencies": {
"request": "^2.49.0",
"tough-cookie": "^0.12.1"
},
I figured out the best way to deal with it is installing Node JS + npm, and invoking npm install some_module in the node/ folder. It automatically downloads some_module and all of its dependencies into my node/ folder.
No more require errors.

I did not specify that the file was in the working directory.
require('./somemodule/index.js');
instead of
require('somemodule/index.js');
did the job. Another possiblity is to set the NODE_PATH environment variable to the node/ folder, so you can require without ./.
I also figured out that the best way to obtain modules is by installing them with npm instead of downloading them from git, because the latter does not download any dependencies.

Related

How to remove local repository by Java code that was cloned by JGit java library?

I clone a remote repository to my local environment using Java JGit library (latest version that is 5.9.0.202009080501-r).
Git git = Git.cloneRepository().setURI(repositoryUrl).setCredentialsProvider(new UsernamePasswordCredentialsProvider(user, password)).setDirectory(targetDir).call();
After using the contents of the repository I want to remove it from my local environment by deleting the directory of this local repository.
FileUtils.deleteDirectory(gitDirectory);
The problem is that I cannot remove the .git directory from the Java code because access is denied on files in the '.git\objects\pack' directory
java.io.IOException: Unable to delete file: 'local repository directory'.git\objects
...
Caused by: java.nio.file.AccessDeniedException: 'local repository directory'.git\objects\pack\pack-*************.idx**
It is the JGit library that locks these files. After stopping the Java program I can delete these files manually. But I want to remove them from the code because on the server there is no way to stop an application just to delete something.
I am investigating this problem for days by now. What I tried so far:
Close everything that the Jgit library provides.
git.close();
git.getRepository().close();
git.getRepository().getObjectDatabase().close();
Git.shutdown();
Some threads state that files are locked by the Garbage collector of the Jgit, I tried to turn it off by configuration parameters
StoredConfig configuration = git.getRepository().getConfig();
configuration.setBoolean( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTODETACH, false );
configuration.setInt( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTOPACKLIMIT, 0 );
configuration.setInt( CONFIG_GC_SECTION, null, CONFIG_KEY_AUTO, 0 );
configuration.save();
Some threads suggested that this problem can be solved by the below configuration of the WindowCacheConfig.
WindowCacheConfig config = new WindowCacheConfig();
config.setPackedGitMMAP(false);
WindowCache.reconfigure(config);
Tried to play around with the with different settings of the JGit garbage collector. I tried multiple combinations and values (true/false) of the below settings. In most cases these settings made it worse because created an additional .bitmap file in the pack directory that was again impoossible to delete.
git.gc().setPreserveOldPacks(false).call();
git.gc().setPrunePreserved(true).call();
git.gc().setAggressive(true).call();
None of the above attempts helped, the result is always the same AccessDeniedException. Any help is appreciated.
Suppose you have this:
File dir = new File( "c:/users/master/documents/test" );
dir.mkdir();
Git git = Git.cloneRepository()
.setDirectory( dir )
.setURI( "http://git.com/scm/devenv/jira.git" )
.call();
// you do your stuff with the cloned files here
You call this when you're done:
git.close();
git = null;
Git.shutdown();
removeRecursively( dir );
Add this method:
private static void removeRecursively(File f) {
if (f.isDirectory()) {
for (File c : f.listFiles()) {
removeRecursively(c);
}
}
f.delete();
}

Read the jar version for a class

For a webservice client I'd like to use Implementation-Title and Implementation-Version from the jar file as user-agent string. The question is how to read the jar's manifest.
This question has been asked multiple times, however the answer seems not applicable for me. (e.g. Reading my own Jar's Manifest)
The problem is that simply reading /META-INF/MANIFEST.MF almost always gives wrong results. In my case, it would almost always refer to JBoss.
The solution proposed in https://stackoverflow.com/a/1273196/4222206
is problematic for me as you'd have to hardcode the library name to stop the iteration, and then still it may mean two versions of the same library are on the classpath and you just return the first - not necessarily the right - hit.
The solution in https://stackoverflow.com/a/1273432/4222206
seems to work with jar:// urls only which completely fails within JBoss where the application classloader produces vfs:// urls.
Is there a way for code in a class to find it's own manifest?
I tried the abovementioned items which seem to run well in small applications run from the java command line but then I'd like to have a portable solution as I cannot predict where my library would be used later.
public static Manifest getManifest() {
log.debug("getManifest()");
synchronized(Version.class) {
if(manifest==null) {
try {
// this works wrongly in JBoss
//ClassLoader cl = Version.class.getProtectionDomain().getClassLoader();
//log.debug("found classloader={}", cl);
//URL manifesturl = cl.getResource("/META-INF/MANIFEST.MF");
URL jar = Version.class.getProtectionDomain().getCodeSource().getLocation();
log.debug("Class loaded from {}", jar);
URL manifesturl = null;
switch(jar.getProtocol()) {
case "file":
manifesturl = new URL(jar.toString()+"META-INF/MANIFEST.MF");
break;
default:
manifesturl = new URL(jar.toString()+"!/META-INF/MANIFEST.MF");
}
log.debug("Expecting manifest at {}", manifesturl);
manifest = new Manifest(manifesturl.openStream());
}
catch(Exception e) {
log.info("Could not read version", e);
}
}
}
The code will detect the correct jar path. I assumed by modifying the url to point to the manifest would give the required result however I get this:
Class loaded from vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar
Expecting manifest at vfs:/C:/Users/user/Documents/JavaLibs/wildfly-18.0.0.Final/bin/content/webapp.war/WEB-INF/lib/library-1.0-18.jar!/META-INF/MANIFEST.MF
Could not read version: java.io.FileNotFoundException: C:\Users\hiran\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0-18.jar!\META-INF\MANIFEST.MF (The system cannot find the path specified)
I checked that path and it seems even the first URL to the jar (obtained via Version.class.getProtectionDomain().getCodeSource().getLocation() ) was wrong already. It should have been C:\Users\user\Documents\JavaLibs\wildfly-18.0.0.Final\standalone\tmp\vfs\temp\tempfc75b13f07296e98\content-e4d5ca96cbe6b35e\WEB-INF\lib\library-1.0.18.jar.
So this could even point to a problem in Wildfly?
It seems I found some suitable solution here:
https://stackoverflow.com/a/37325538/4222206
So in the end this code can display the correct version of the jar (at least) in JBoss:
this.getClass().getPackage().getImplementationTitle();
this.getClass().getPackage().getImplementationVersion();
Hopefully I will find this answer when I search next time...

Intellij: No usages found in Project Files

I'm using IntelliJ 15 and I'm trying to find usages of methods and objects in a .java file packed in a .jar file downloaded through Maven. I now that they're used: I can find them through the simple search (ctrl+f) command, but when I try with the Find Usages command the post-title message is returned.
I've read this post, but it doesn't work.
This an example of a method in a file InstanceManager.class (belonging to .jar file imported with Maven):
private void notifyNewInstance(Instance instance) {
List var2 = this.instanceListeners;
synchronized(this.instanceListeners) {
Iterator var3 = this.instanceListeners.iterator();
while(var3.hasNext()) {
InstanceListener listener = (InstanceListener)var3.next();
try {
listener.newInstanceAvailable(instance);
} catch (Throwable var7) {
LOG.error("Notification of new instance availability failed.", var7);
}
}
}
}
And in the same file is called with this.notifyNewInstance(host); but if I use Find usages on notifyNewInstance I'll receive the error.
UPDATE:
I've tried to Download the source code, but I get the message:
Cannot download sources Sources not found for:
org.apache.flink:flink-runtime_2.10:1.1-20160316.114232-35
Can you help me with that?
You need to get the source code.
Assuming you're attempting to do this on Apache Flink:
Source Code found here
If you only want a particular folder from the source code, you can use the method found here.

Alloy API resulting in java.lang.UnsatisfiedLinkError

I'm currently using the Alloy Analyzer API to build a program, and getting some peculiar behavior. Specifically, if I open a file and parse it (using CompUtil.parseEverything), then make a new Command and call TranslateAlloyToKodkod.execute_command on the parsed file and newly created command using MiniSat with UNSAT core, it runs fine. However, later in execution, my program parses a second input file (also using CompUtil.parseEverything), gets another world, makes a new command, and then I try to call TranslateAlloyToKodkod.execute_command again, it throws the following error:
ERROR: class edu.mit.csail.sdg.alloy4.ErrorFatal: The required JNI library cannot be found:
java.lang.UnsatisfiedLinkError: no minisatproverx5 in java.library.path
edu.mit.csail.sdg.alloy4compiler.translator.TranslateAlloyToKodkod.execute_command(TranslateAlloyToKodkod.java:390)
Does anyone have any idea why this is thrown the second time, but not the first?
To summarize, I have something similar to the following:
Module someWorld = CompUtil.parseEverything_fromFile(rep, null, "someFile.als");
//For the following, "sig" is a sig in someWorld.getAllReachableSigs();
Command command = sig.not();
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.MiniSatProverJNI;
A4Solution ans =
TranslateAlloyToKodkod.execute_command(rep, someWorld, command, options);
//No thrown error
Module someOtherWorld = CompUtil.parseEverything_fromFile(rep, null, "someOtherFile.als");
//For the following, "sig" is a sig in someOtherWorld.getAllReachableSigs();
Command commandTwo = sig.not();
A4Solution ansTwo =
TranslateAlloyToKodkod.execute_command(rep, someOtherWorld, commandTwo, options);
//Thrown error above. Why?
I tried to reproduce this behavior, but I couldn't. If I don't add MiniSat binaries to the LD_LIBRARY_PATH environment variable, I get the exception you mentioned the very first time I invoke execute_command. After configuring LD_LIBRARY_PATH, the exception doesn't happen.
To configure LD_LIBRARY_PATH:
(1) if using Eclipse, you can right-click on one of your source folders, choose Build Path -> Configure Build Path, then on the "Source" tab make sure that "Native library location" points to a folder in which MiniSat binaries reside.
(2) if running from the shell, just add the path to a folder with MiniSat binaries to LD_LIBRARY_PATH, e.g., something like export LD_LIBRARY_PATH=alloy/extra/x86-linux:$LD_LIBRARY_PATH.
Here is the exact code that I was running, and everything worked
public static void main(String[] args) throws Exception {
A4Reporter rep = new A4Reporter();
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.MiniSatProverJNI;
Module someWorld = CompUtil.parseEverything_fromFile(rep, null, "someFile.als");
Command command = someWorld.getAllCommands().get(0);
A4Solution ans = TranslateAlloyToKodkod.execute_command(rep, someWorld.getAllReachableSigs(), command, options);
System.out.println(ans);
Module someOtherWorld = CompUtil.parseEverything_fromFile(rep, null, "someOtherFile.als");
Command commandTwo = someOtherWorld.getAllCommands().get(0);
A4Solution ansTwo = TranslateAlloyToKodkod.execute_command(rep, someOtherWorld.getAllReachableSigs(), commandTwo, options);
System.out.println(ansTwo);
}
with "someFile.als" being
sig A {}
run { some A } for 4
and "someOtherFile.als"
sig A {}
run { no A } for 4
I use alloy4.2.jar as a library in my eclipse plugin project.
A4Reporter rep = new A4Reporter();
Module world = CompUtil.parseEverything_fromFile(rep, null, "civi.als");
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.SAT4J;
options.skolemDepth = 1;
When I use SAT4J, the default solver, the problem mentioned here will not show up. But another exception comes out. The reason is that my civi.als file need Integer model, which located in alloy4.2.jar under the folder /models/util/. But when I run the application, it tries to find the file util/Integer.als directly. That causes the exception. Is it possible to fix that problem?
Besides, I also tried to put the alloy4.2.jar in eclipse plugin project and run my application as an eclipse application (running my application as a plugin). With the default solver, the application has no problem at all. But when I switch to MiniSatProverJNI, the problem mentioned here comes out (I have set the alloy4.2.jar as classpath).

JGit/EGit Loading of translation bundle failed en_US

I am running the following code in a JUnit test to test fetching a git repository. I'm writing a test for each of the basic functionality i need from JGit so that then i can implement them in my application. The problem is that i keep getting the following error on the git.fetch() call below:
Loading of translation bundle failed for [org.eclipse.jgit.JGitText, en_US]
org.eclipse.jgit.errors.TranslationBundleLoadingException: Loading of translation bundle failed for [org.eclipse.jgit.JGitText, en_US]
The code sample is below. I verified that the repository paths and everything seems correct. If i put a breakpoint on the fetch call and then run the same command in MSysGit it works.
try {
String remoteName = "origin";
URIish uri = new URIish(repository.getRepositoryDirectory());
saveRemote(repository2.getRepository(), uri, remoteName);
Git git = repository.getGit();
FetchResult r = git.fetch().setRemote(remoteName).call();
assertNotNull("Did not get any result from fetch.", r);
} catch (JGitInternalException ex) {
fail("Failed to do fetch. " + ex.getMessage());
} catch (InvalidRemoteException ex) {
fail("Failed to do fetch. " + ex.getMessage());
} catch (URISyntaxException ex) {
fail("Failed to do fetch. " + ex.getMessage());
}
Thanks!
Okay I figured this out. I had to copy the file JGitText.properties from the binary distribution into the same package in the source code, rename it to JGitText_en_US.properties, and add a whole bunch of properties to it manually that the code used in JGitText.java but were not defined in JGitText.properties.
I searched through the entire source code and all binary files and related docs and found no reference to these new properties, or the properties file being created anywhere. I don't know why the devs don't have localization files in the source code or at least a way to generate then through a build file or something. I mean they must manually have to add them into their source code and just not commit it.
Anyway this was a very annoying issue, there was no documentation on it anywhere on the net (that google revealed anyway) so I thought i would share this as it might help others who ran into the same problem.
I had the same problem, but my fix was a little different. In my case, the problem was related to the OSGI classloader.
Here's a commit that fixes the issue:
https://github.com/diffplug/jgit/commit/3bcc69bde5567ec57ccd6bd065ded0db49f810fb
And here's the rationale behind it:
Loading a ResourceBundle within an OSGi bundle

Categories

Resources