Solr Plugin Classloader - plugins

I'm writing a solr plugin by extending SearchComponent class. My new class is part of a.jar archive. Also my class depends on a jar b.jar. I placed both jars in my core/lib folder and I declared my new component in solrconfig.xml. The component is invoked correctly up to a point where a class ClassFromB from b.jar attempts to load a classpath resource stopwords.txt from classpath.
The piece of code in class ClassFromB looks like this:
...
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL url = cl.getResource("stopwords.txt"); //with cl.getResource("/stopwords.txt"); I get the same exception
String content = IOUtils.toString(curl.openConnection().getInputStream());
...
The last line above throws a NPE telling me that the resource is not found.
So, the class ClassFromB is loaded because it gets to execute the code up to the last line where it fails. Also I double checked b.jar and I can see the stopwords.txt file right in the root.
What should I do to see that resource from class ClassFromB?

This however worked:
public final class Stopwords {
static {
URL curl = Stopwords.class.getClassLoader().getResource("stopwords.txt");
....
}
....
}

Related

The driver executable does not exist: C:\geckodriver.exe issue in Eclipse IDE

Please help me with this issue that is recurring every time I run my code.
I have extracted Geckodriver files in C Drive but when I run my code, the error that comes up is 'Exception in thread "main" java.lang.IllegalStateException: The driver executable does not exist: C:\geckodriver.exe'.
My code is given below:
package Basics;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Browserinvocation {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.gecko.driver","C:\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();//FirefoxDriver class is used to implement methods present in Webdriver-Invocation of browser
driver.get("https://www.amazon.in/");// Get method to hit the url in browser
}
}
Error in console :
Exception in thread "main" java.lang.IllegalStateException: The driver
executable does not exist: C:\geckodriver.exe at
com.google.common.base.Preconditions.checkState(Preconditions.java:534)
at
org.openqa.selenium.remote.service.DriverService.checkExecutable(DriverService.java:136)
at
org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:131)
at
org.openqa.selenium.firefox.GeckoDriverService.access$100(GeckoDriverService.java:41)
at
org.openqa.selenium.firefox.GeckoDriverService$Builder.findDefaultExecutable(GeckoDriverService.java:141)
at
org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:339)
at
org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:158)
at
org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:120)
at
org.openqa.selenium.firefox.FirefoxDriver.(FirefoxDriver.java:98)
at Basics.Browserinvocation.main(Browserinvocation.java:13)
Above exception occurs whenever Precondition does not find path of relevant driver mentioned in System.setProperty() method by any reason like below:
if path mentioned have different/wrong/single slashes.
Driver file itself is not present at mentioned location.
If path is mentioned in properties file or config file with double quotes.
Just check once before execution.
You should add the path to geckodriver.exe using / rather than \\. Change your line
System.setProperty("webdriver.gecko.driver","C:\\geckodriver.exe");
to the following
System.setProperty("webdriver.gecko.driver","C:/geckodriver.exe");
Your code is running at my side, might be you are not extracting the gecko driver.
Change the path and try it once, it should worked
Please let me know selenium jars version and your firefox browser version
System.setProperty("webdriver.gecko.driver", "C:/Users/sankalp.gupta/Desktop/JAVASEL/geckodriver.exe");
WebDriver driver=new FirefoxDriver();
driver.get("https://www.amazon.in");
System.out.println(driver.getCurrentUrl());
driver.close();
System.setProperty("webdriver.gecko.driver","C:\\geckodriver.exe");
Here remove . in between gecko and driver
Just download geckodriver.exe and move it to drive C:

Load application.conf from folder in deployed Scala app

I have an application that loads configuration from application.conf using ConfigFactory: lazy val myConfig = ConfigFactory.load(pathToConfig)
The application.conf is initially located in src/main/resources
When I deploy my application I want it to load the config from APP_HOME/conf/application.conf
To do so, I excluded the application.conf from the resource folder when building the Rmp and I have added my APP_HOME/conf to the class path.
jar {
exclude '*.conf'
}
and
startScripts {
classpath += files('src/main/resources')
doLast {
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
println('unix script is ' + unixScriptFile.text)
windowsScriptFile.text = windowsScriptFile.text.replace('%APP_HOME%\\lib\\resources', '%APP_HOME%\\conf')
unixScriptFile.text = unixScriptFile.text.replace('\$APP_HOME/lib/resources', '\$APP_HOME/conf')
println('after unix script is ' + unixScriptFile.text)
}
}
The odd thing is that when I modify the $APP_HOME/conf/application.conf and restart the app, the changes are not picked up: ie the old configuration is still being used
Any idea what might cause this or how I can print where the config is being loaded from would be helpful
With many attempts, I got it to work by calling lazy val myConfig = ConfigFactory.load() without specifying the conf file name or path.
Although it solved my issue I still don't understand why calling load with the file name or file path didn't work

Can't load a jks file from classpath

I've created a JKS file with public and private RSA keys. When I load this file using external path (like c:/file.jks), the program executes like a charm. However, if I try load this same file from classpath, I got this exception:
java.io.IOException: Invalid keystore format
This is the code used to load the jks:
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream stream=this.getClass().getResourceAsStream("/lutum.jks") ;
keyStore.load(stream,passe);
the only difference is that I use FileInputStream with full path when loading externally.
What I'm doing wrong?
In general your solution should work, provisionally.
What are those provisions? Make sure that your resource folder is in your classpath. If you aren't sure, add it to the -cp flag passed to java when executing your program, or if you are using Eclipse or some other IDE, make sure it is listed as a member of the classpath for that project.
Next, check out this stackoverflow that relates to your question. While the way you are using the class's getResourceAsStream() method is valid (including the / at the start of the filename causes the class resource loader to defer to the ClassLoader's method) it is perhaps less confusing to use the ClassLoader directly. Another good example is found here.
So, first, check that your resources folder is explicitly part of the classpath. Second, prefer the following construction for finding the resource:
InputStream stream= this.class.getClassLoader().getResourceAsStream("lutum.jks");
Note the missing / from the filename. This is because the ClassLoader will automatically start searching at "project root", and the slash will likely just cause issues (if you deploy to JBoss or Tomcat, for instance, that will probably get interpreted by the classloader as an absolute file system path instead of a relative path).
I hope this helps. If not, comment me with more details on your project and I'll alter my answer accordingly.
I suspect that the two keystores are in fact not the same, and that the keystore on the classpath are somehow corrupt.
Try comparing the two keystores. Just read the files into a byte array with something like this:
public static byte[] streamToByteArray(InputStream is) throws IOException {
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
int b = is.read();
while (b > -1) {
tmp.write(b);
b = is.read();
}
tmp.flush();
return tmp.toByteArray();
}
And then compare them like this:
InputStream cpStream = this.getClass().getResourceAsStream("/lutum.jks");
InputStream fileStream = new FileInputStream("c:/file.jks");
byte[] cpBytes = streamToByteArray(cpStream);
byte[] fileBytes = streamToByteArray(fileStream);
if (Arrays.equals(cpBytes, fileBytes)) {
System.out.println("They are the same.");
} else {
System.out.println("They are NOT the same.");
// print the file content ...
}

Bval ValidationMessages.properties in scala eclipse project

I have a scala project (based around unfiltered and jetty) which uses bval. I've tried everything I can think of to get custom validation messages to load from a properties file, but it just doesn't work. I have a scala class like this:
class AddName{
#NotEmpty(message = "{firstName.notEmpty}")
var firstName: String = ""
#NotEmpty(message = "{lastName.notEmpty}")
var lastName: String = ""
}
and a ValidationMessages.properties file containing the following:
firstName.notEmpty=enter a first name
lastName.notEmpty=enter a last name
But the output from the validation results is {firstName.notEmpty} not matter what I try.
I have tried placing the properties file in the project root, in a resource folder which is exported to the classpath by the run configurations. I've also tried placing it in the target/scala-2.9.1/classes folder and then running the project with sbt compile.

Why is my object not a member of package <root> if it's in a separate source file?

I'm having a problem accessing an object defined in the root package. If I have all my code in one file, it works fine, but when I split it across two files, I can't get it past the compiler.
This works fine:
All in one file called packages.scala:
object Foo
val name = "Brian"
}
package somepackage {
object Test extends App {
println(Foo.name)
}
}
Witness:
$ scalac packages.scala
$ scala -cp . somepackage.Test
Brian
But if I split the code across two files:
packages.scala
object Foo {
val name = "Brian"
}
packages2.scala
package somepackage {
object Test extends App {
println(Foo.name)
}
}
it all fails:
$ scalac packages.scala packages2.scala
packages2.scala:3: error: not found: value Foo
So I try to make the reference to Foo absolute:
...
println(_root_.Foo.name)
...
But that doesn't work either:
$ scalac packages.scala packages2.scala
packages2.scala:3: error: object Foo is not a member of package <root>
If Foo is not a member of the root package, where on earth is it?
I think this is the relevant part in the spec:
Top-level definitions outside a packaging are assumed to be injected into a special empty package. That package cannot be named and therefore cannot be imported. However, members of the empty package are visible to each other without qualification.
Source Scala Reference §9.2 Packages.
But don’t ask me why it works if you have the following in packages2.scala:
object Dummy
package somepackage {
object Test extends App {
println(Foo.name)
}
}
Foo is a member of the root package, but you can't refer to it. It's a generic thing with JVM languages, (see How to access java-classes in the default-package? for Groovy, What's the syntax to import a class in a default package in Java?). It's the same for Scala.
From the Java answer:
You can't import classes from the default package. You should avoid
using the default package except for very small example programs.
From the Java language specification:
It is a compile time error to import a type from the unnamed package.
The reason it works in one single file is because everything is available to the compiler at once, and the compiler copes with it. I suspect that this is to allow scripting.
Moral of the story: don't use the default package if you're not scripting.
Ran into this when trying to import the main App entrypoint into a test. This may be an evil hack, but putting package scala at the top of the entrypoint definition seems to have made the object globally available. This may be evil, but it works.
E.g.
/src/main/scala/EntryPoint.scala
package scala
object EntryPoint extends App {
val s = "Foo"
}
/src/test/scala/integration/EntryPointSuite.scala
package integration
import org.scalatest.FlatSpec
class EntryPointSuite extends FlatSpec {
"EntryPoint" should "have property s" in {
val ep = EntryPoint.main()
assert(ep.s == "Foo")
}
}