I have an application that uses embedded jetty. When I run this application in Netbeans IDE then I can browse my site # localhost:8080/
When I launch the jar file of my application from command line: java -jar app.jar then browsing localhost:8080/ jetty server says "page not found"
What am I missing here? Can't figure out the problem.
EDIT:
Netbeans project is uploaded to Github
Everything works fine if I run this project in Netbeans.
But when I take the jar file with lib folder and run it in cmd like this: java -jar EmbeddedJettyJspJstl.jar
Then navigating to http://localhost:8080/test I get errors:
org.apache.jasper.JasperException: java.lang.ClassNotFoundException: org.apache.jsp.WEB_002dINF.jstl_jsp
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
My JSP page uses JSTL and looks like it is not locating the jstl libraries?
And this is the code that starts the server:
package server;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* #author lkallas
*/
public class JettyServer {
// Resource path pointing to where the WEBROOT is
private static final String WEBROOT = "/webapp/";
private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
public void start() throws IOException, InterruptedException, URISyntaxException {
Server server = new Server();
// HTTP connector
ServerConnector connector = new ServerConnector(server);
connector.setHost("localhost");
connector.setPort(8080);
connector.setIdleTimeout(30000);
// Set the connector
server.addConnector(connector);
// Setup JMX for web applications
MBeanContainer mbContainer = new MBeanContainer(
ManagementFactory.getPlatformMBeanServer());
server.addBean(mbContainer);
//Setting up web application
WebAppContext webapp = new WebAppContext();
webapp.setAttribute("javax.servlet.context.tempdir", getScratchDir());
webapp.setDescriptor(WEBROOT + "WEB-INF/web.xml");
webapp.setResourceBase(getWebRootResourceUri().toASCIIString());
webapp.setContextPath("/");
webapp.setWar(getWebRootResourceUri().toASCIIString());
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
//For debugging
logger.info("Descriptor file: {}", webapp.getDescriptor());
logger.info("Resource base: {}", getWebRootResourceUri().toASCIIString());
logger.info("WAR location: {}", webapp.getWar());
HandlerList handlerList = new HandlerList();
handlerList.setHandlers(new Handler[]{webapp, new DefaultHandler()});
// This webapp will use jsps and jstl. We need to enable the
// AnnotationConfiguration in order to correctly
// set up the jsp container
Configuration.ClassList classlist = Configuration.ClassList
.setServerDefault(server);
classlist.addBefore(
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
// Set the ContainerIncludeJarPattern so that jetty examines these
// container-path jars for tlds, web-fragments etc.
// If you omit the jar that contains the jstl .tlds, the jsp engine will
// scan for them instead.
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/[^/]*taglibs.*\\.jar$");
// A WebAppContext is a ContextHandler as well so it needs to be set to
// the server so it is aware of where to send the appropriate requests.
server.setHandler(handlerList);
try {
server.start();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
server.dumpStdErr();
}
/**
* Establish Scratch directory for the servlet context (used by JSP
* compilation)
*/
private File getScratchDir() throws IOException {
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File scratchDir = new File(tempDir.toString(), "embedded-jetty");
if (!scratchDir.exists()) {
if (!scratchDir.mkdirs()) {
throw new IOException("Unable to create scratch directory: " + scratchDir);
}
}
return scratchDir;
}
/**
* Get webroot URI.
*
* #return
* #throws FileNotFoundException
* #throws URISyntaxException
*/
private URI getWebRootResourceUri() throws FileNotFoundException, URISyntaxException {
URL indexUri = this.getClass().getResource(WEBROOT);
if (indexUri == null) {
throw new FileNotFoundException("Unable to find resource " + WEBROOT);
}
logger.debug("WEBROOT: {}", indexUri.toURI().toASCIIString());
return indexUri.toURI();
}
}
I have already looked # http://www.eclipse.org/jetty/documentation/current/advanced-embedding.html
There's a number of reasons and causes that could be affecting you.
However you haven't posted any code to help us identify what the specific cause is.
The Jetty Project maintains an example for this setup, btw.
https://github.com/jetty-project/embedded-jetty-uber-jar
Pay attention to your context.setContextPath() (like #Haider-Ali pointed out), and also your context.setBaseResource()
For JSPs in Embedded Jetty you can look at the other example project
https://github.com/jetty-project/embedded-jetty-jsp
Note prior answer about Embedded Jetty and JSP.
Related
tldr; How do I deploy from WebApplicationContext in embedded jetty for a simple automatic test case?
What I have:
A spring application (not spring boot) that uses annotation configuration (no web.xml) and is - for production - build (with gradle) to an ear and deployed on wildfly.
What I ultimately want to do:
Have self-contained (in the applications test package) ui-tests, that can easily be executed (without building and deploying) like any of the other unit or integration tests.
What I have done so far:
The easy part: Setup the actual tests with Selenium WebDriver
The hard part: Start an embedded Jetty with a test WebApplicationContext
My code for the embedded Jetty (yes, I will do some refactoring when I get it running):
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.apache.tomcat.util.scan.StandardJarScanner;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.jsp.JettyJspServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.session.HashSessionIdManager;
import org.eclipse.jetty.server.session.HashSessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class JettyServerFactory {
private Server server = null;
public Server start(WebApplicationContext context) throws Exception {
if (server == null) {
this.server = new Server(9090);
setupServer(context);
server.start();
//server.join();
}
return server;
}
public void stop() throws Exception {
if (server != null) {
server.stop();
}
}
private void setupServer(WebApplicationContext context) throws Exception {
final ServletContextHandler contextHandler = new ServletContextHandler();
// Since this is a ServletContextHandler we must manually configure JSP support.
enableEmbeddedJspSupport(contextHandler);
// Spring Security
enableSpringSecurity(contextHandler, context);
/*
// TODO: Does not seem to have any effect
// Set reference to actual Spring ApplicationContext
ServletContext servletContext = contextHandler.getServletContext();
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
*/
// Set resource base folder
contextHandler.setBaseResource(getResourceBase());
// Add DispatcherServlet to context
final ServletHolder servletHolder = new ServletHolder("default", new DispatcherServlet(context));
servletHolder.setInitParameter("dirAllowed", "true");
contextHandler.setContextPath("/oauth");
contextHandler.addServlet(servletHolder, "/");
// Add context to server
server.setHandler(contextHandler);
}
private Resource getResourceBase() {
File file = new File("src/website/application.war");
//servletHolder.setInitParameter("resourceBase", getWebRootResourceUri().toASCIIString());
final Resource base = Resource.newResource(file);
return base;
}
/**
* Apply existing securityFilterChain to context
*
* #param contextHandler
* #param context
*/
private void enableSpringSecurity(ServletContextHandler contextHandler, WebApplicationContext context) {
FilterChainProxy filter = (FilterChainProxy) context.getBean("springSecurityFilterChain");
FilterHolder filterHolder = new FilterHolder(filter);
contextHandler.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
server.setSessionIdManager(new HashSessionIdManager());
HashSessionManager manager = new HashSessionManager();
SessionHandler sessions = new SessionHandler(manager);
contextHandler.setHandler(sessions);
}
/**
* Setup JSP Support for ServletContextHandlers.
* <p>
* NOTE: This is not required or appropriate if using a WebAppContext.
* </p>
*
* #param servletContextHandler the ServletContextHandler to configure
* #throws IOException if unable to configure
*/
private void enableEmbeddedJspSupport(ServletContextHandler servletContextHandler) throws IOException {
// Establish Scratch directory for the servlet context (used by JSP compilation)
File tempDir = new File(System.getProperty("java.io.tmpdir"));
File scratchDir = new File(tempDir.toString(), "embedded-jetty-jsp");
if (!scratchDir.exists()) {
if (!scratchDir.mkdirs()) {
throw new IOException("Unable to create scratch directory: " + scratchDir);
}
}
servletContextHandler.setAttribute("javax.servlet.context.tempdir", scratchDir);
// Set Classloader of Context to be sane (needed for JSTL)
// JSP requires a non-System classloader, this simply wraps the
// embedded System classloader in a way that makes it suitable
// for JSP to use
ClassLoader jspClassLoader = new URLClassLoader(new URL[0], this.getClass().getClassLoader());
servletContextHandler.setClassLoader(jspClassLoader);
// Manually call JettyJasperInitializer on context startup
servletContextHandler.addBean(new JspStarter(servletContextHandler));
// Create / Register JSP Servlet (must be named "jsp" per spec)
ServletHolder holderJsp = new ServletHolder("jsp", JettyJspServlet.class);
holderJsp.setInitOrder(0);
holderJsp.setInitParameter("logVerbosityLevel", "DEBUG");
holderJsp.setInitParameter("fork", "false");
holderJsp.setInitParameter("xpoweredBy", "false");
holderJsp.setInitParameter("compilerTargetVM", "1.8");
holderJsp.setInitParameter("compilerSourceVM", "1.8");
holderJsp.setInitParameter("keepgenerated", "true");
servletContextHandler.addServlet(holderJsp, "*.jsp");
}
/**
* JspStarter for embedded ServletContextHandlers
*
* This is added as a bean that is a jetty LifeCycle on the ServletContextHandler. This bean's doStart method will
* be called as the ServletContextHandler starts, and will call the ServletContainerInitializer for the jsp engine.
*
*/
public static class JspStarter extends AbstractLifeCycle
implements ServletContextHandler.ServletContainerInitializerCaller {
JettyJasperInitializer sci;
ServletContextHandler context;
public JspStarter(ServletContextHandler context) {
this.sci = new JettyJasperInitializer();
this.context = context;
this.context.setAttribute("org.apache.tomcat.JarScanner", new StandardJarScanner());
}
#Override
protected void doStart() throws Exception {
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(context.getClassLoader());
try {
sci.onStartup(null, context.getServletContext());
super.doStart();
} finally {
Thread.currentThread().setContextClassLoader(old);
}
}
}
private URI getWebRootResourceUri() throws FileNotFoundException, URISyntaxException, MalformedURLException {
String WEBROOT_INDEX = "/application.war/";
URL indexUri = this.getClass().getResource(WEBROOT_INDEX);
if (indexUri == null) {
throw new FileNotFoundException("Unable to find resource " + WEBROOT_INDEX);
}
File file = new File("src/website/application.war");
System.out.println(indexUri.toURI());
System.out.println(file.toURI());
System.out.println(file.getAbsolutePath());
return file.toURI();
}
}
The WebApplicationContext for the test case is simply provided somewhat like this:
...
#WebAppConfiguration
public class ATestClass {
#Autowired
WebApplicationContext context;
...
#Before
public void setupTest() throws Exception {
new JettyServerFactory().start(context);
...
}
...
...
Location of the Resource Base:
Resource placement in the project structure
All static resources like css, js and images are in themes
What does work:
Controllers are hit on requests
Spring Security is active
JSPs are found and rendered (thanks to https://github.com/jetty-project/embedded-jetty-jsp)
What does not work:
All other static resources are missing (css, js, images, etc.). Basically everything from themes
So, what are my questions:
How can I make the missing static resources available?
Is there a completely different/better approach to achieve my ultimate goal? The way, to what I have now, was quite rocky and I'm not sure the missing static content is the last of my problems.
I'm happy to provide additional information/code. But, since this is an actual product, I have some limits on that.
Edits:
Picture of the resource structure
Mind that application.war is just a folder, not actually a war
Resource Config
#EnableWebMvc
#Configuration
public class AppWebMvcConfiguration implements WebMvcConfigurer {
...
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/jsp/", ".jsp");
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
boolean developmentMode = configuration.getBooleanFromNewconfig(false, "oauth2.developmentMode");
if (USE_VERSIONED_RESOURCES) {
registry.addResourceHandler("/themes/**")
.addResourceLocations("/themes/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
.resourceChain(developmentMode ? false : true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
.addTransformer(new CssLinkResourceTransformer());
} else {
registry.addResourceHandler("/themes/**")
.addResourceLocations("/themes/")
.setCacheControl(CacheControl.noCache());
}
}
...
}
Which case is used for the ResourceHandler doesn't matter. Neither works.
I am trying to save a MultipartFile (uploaded to Spring MVC controller) to a linux server on the network (requires authentication). I tried smb using jcifs but the performance is very poor.
Could someone point me to an alternate way of doing this? I searched everywhere for 2 days and have not been able to find a solution that works.
The application server runs linux.
Edit: This is the code I am using. The code works but performs very, very poorly
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;
#Component
public class FileUploadUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadUtil.class);
#Value("${dr.fileuser}")
private String user;
#Value("${dr.filepwd}")
private String pass;
#Value("${dr.sharePath}")
private String drSharePath;
#Value("${dr.fileLocation}")
private String drFileLocation;
#Value("${dr.serverName}")
private String drServerName;
/**
* #param uploadedFile
* #param filename
* #param discId: this is a generated id, used to associate these files with a database record.
* #return
* #throws WW_Exception
* #throws IOException
*/
public String writeFileToServer(MultipartFile uploadedFile, String filename, Integer discId) throws WW_Exception, IOException {
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("",user, pass);
String destDir = StringUtils.cleanPath("smb://" + drServerName + drSharePath + drFileLocation + discId + "/");
LOGGER.info("FILE Destination DIR: {}", destDir);
try{
//create directory structure
SmbFile sfileDir = new SmbFile(destDir, auth);
if(!sfileDir.exists()) {
sfileDir.mkdirs();
}
String destFilePath = StringUtils.cleanPath(destDir + filename);
LOGGER.info("FILE Destination PATH: {}", destFilePath);
SmbFile sfile = new SmbFile(destFilePath, auth);
try (SmbFileOutputStream fos = new SmbFileOutputStream(sfile)){
fos.write(uploadedFile.getBytes());
}
return destFilePath.replace("smb:", "");
} catch(Exception e){
throw e;
}
}
/**
* #param drId: this is a generated id, used to associate these files with a database record.
* #param origFilePath
* #return
* #throws IOException
*/
public String copyFileFromServer(Integer drId, String origFilePath) throws IOException {
LOGGER.info("FILE to get: {}",origFilePath);
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("",user, pass);
String[] imagePathInfo = origFilePath.split("/");
String destFilePath = StringUtils.cleanPath("/weblogs/tmp/" + drId + "/" + imagePathInfo[imagePathInfo.length-1]);
File destDir = new File(StringUtils.cleanPath("/weblogs/tmp/" + drId + "/"));
if(!destDir.exists()) {
destDir.mkdirs();
}
SmbFile origFile = new SmbFile(origFilePath,auth);
try(InputStream in = new SmbFileInputStream(origFile)) {
Files.copy(in, Paths.get(destFilePath), StandardCopyOption.REPLACE_EXISTING);
}
return destFilePath;
}
}
#Jorge,
Based on your comments above as you have root access to the linux server then I all you need to do is a regular old kernel mount. You will need to ensure that you have installed the cifs client (assuming ubuntu):
$ sudo apt install -y cifs-utils
Then you should be able to mount your share with something like:
$ SMB_USERNAME=<your username>
$ SMB_PASSWORD=<your password>
$ SMB_SERVER="//<your host>/<your share>"
$ sudo mount -t cifs -o username=${SMB_USERNAME},password=${SMB_PASSWORD} \
"${SMB_SERVER}" /mnt
Then option 1 would be to modify your code to read and write files to the mounted directory; i.e. /mnt in this case.
Or, option 2, would be to use the community project called Spring Content. This provides an abstraction over storage for resource handling and can inject the controller and service code for you so that you don't need to write it yourself. One of the supported storage modules is the Filesystem Storage module and you would configure this to read and write files to your local /mnt directory which is really your remote share.
So, if you added Spring Content to your project you could remove all of your controller code and not worry about the implementation details. Plus, as Spring Content is an abstraction, in future, you could also shift to any of the other storage mediums supported by Spring Content; S3 for example. Adding it would look something like this:
pom.xml (assuming maven. Spring boot starters also available)
<!-- Java API -->
<!-- just change this depdendency if you want to store somewhere else -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs</artifactId>
<version>0.7.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.7.0</version>
</dependency>
StoreConfig.java
#Configuration
#EnableFilesystemStores
#Import(RestConfiguration.class)
public class StoreConfig {
#Bean
FileSystemResourceLoader fileSystemResourceLoader() throws IOException {
return new FileSystemResourceLoader(new File("/mnt").getAbsolutePath());
}
}
FileStore.java
#StoreRestResource(path="files")
public interface FileStore extends Store<String> {
}
And that's it. The FileStore is essentially a generic Spring ResourceLoader. The spring-content-fs dependency will cause Spring Content to inject a filesystem-based implementation so you don't need to worry about implementing it yourself. Moreover, the spring-content-rest dependency will cause Spring Content to also inject an implementation if an #Controller that forwards HTTP requests onto the method of the FileStore.
So you will now have a fully functional (POST, PUT, GET, DELETE) REST-based file service at /files that will use your FileStore to retrieve (and store) files in /mnt; i.e. on your remote SMB server.
So:
GET /files/some/file.csv
will download file.csv from /path/to/your/files/some/.
And...
curl --upload-file some-other-file.csv /files/some-other-file.csv
will upload some-other-file.csv and store it in /mnt/ on your server.
And:
curl /files/some-other-file.csv
will retrieve it again.
HTH
The injected controller also supports video streaming too, in case that is useful.
Please check the where you trying to save a MultipartFile that file is having the read and write permission linux machine.
I am working in cisco CVP environment. I have created a client in Netbeans for GRC webservices. I am using that jar file inside of my code. First I was getting a problem that when I run that jar on the machine it work perfectly fine but when I load that jar inside of CVP container it didn't work. After doing a lot search i come out that I have to add few jar's inside of CVP tomcat container. I have added these jar's in the tomcat endorsed folder
jaxb-impl.jar
jaxws-rt.jar
stax-ex.jar
steambuffer.jar
After adding these jar my problem was solved.
Now I come with another problem, I have to set connection timeout and request time in my project. Now again same problem I am facing when I run that jar file outside of CVP Tomcat container (on window cmd) it work perfectly fine, but when I run this jar file inside the CVP Tomcat container it didn't reflect. Here is my code.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package goldwsclient;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.ws.BindingProvider;
import ma.iam.wsgold.ws.impl.AppBusinessException_Exception;
import ma.iam.wsgold.ws.impl.FidelioDto;
/**
*
* #author Malik
*/
public class GoldWsClient {
final static String REQUEST_TIMEOUT = "com.sun.xml.internal.ws.request.timeout";
final static String CONNECT_TIMEOUT = "com.sun.xml.internal.ws.connect.timeout";
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try {
FidelioDto fd=GoldWsClient.getInfoFidelioByND("234234234234324");
System.out.println(fd.getCodeFidelio()+" This is code");
System.out.println(fd.getQualite()+"This is the qualite");
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
public static FidelioDto getInfoFidelioByND(java.lang.String nd) throws AppBusinessException_Exception {
ma.iam.wsgold.ws.impl.FidelioWebServiceImplService service = new ma.iam.wsgold.ws.impl.FidelioWebServiceImplService();
ma.iam.wsgold.ws.impl.FidelioWebServiceImpl port = service.getFidelioWebServiceImplPort();
BindingProvider prov = ((BindingProvider)port);
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
#Override
public boolean verify(String hostname, SSLSession session)
{
// ip address of the service URL(like.23.28.244.244)
if (hostname.equals("IP"))
{
return true;
}
return false;
}
});
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "centreAppel_USER");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "azer+654");
Map<String, Object> ctxt = ((BindingProvider) port).getRequestContext();
ctxt.put(CONNECT_TIMEOUT, 500);
ctxt.put(REQUEST_TIMEOUT, 500);
return port.getInfoFidelioByND(nd);
}
}
I'm using in my program the bluecove library.
While running the program via eclipse, all works smooth. I'm now trying to deploy my program, and following this post i'm using fat-jar.
When i run the jar file (created by fat-jar), the library can't be located, and i'm getting the exception BlueCove libraries not available as result of this line local = LocalDevice.getLocalDevice();.
In the fat-jar window i tried also to add bluecove-2.1.0.jar to the Class-Path place, and also with the path \src\JoJoServer\bluecove-2.1.0.jar.
I tried also to place the bluecove's jar file in different folders, such as the src, or an external folder.
Although i know it's not recommended, i tried the option of One-Jar, nevertheless it didn't help.
To run the jar (the one created by fat jar) i simply double click the file.
What i'm missing?
This is the entire code:
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
#Override
public void run() {
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier)Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
I have no clue what could be your problem, but I've tried the process and everything works, so just a summary of what I've did. Maybe you will figure it out by following it...
I don't understand how the posted code could be the entire, I see no class definition. :)
So I've modified it to the main method and it works both from the Eclipse and also by running the JAR generated by the FatJar.
The modified code of the BTTest class:
package test;
import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
public class BTTest {
public static void main(String[] args) throws Exception{
// retrieve the local Bluetooth device object
LocalDevice local = null;
StreamConnectionNotifier notifier;
StreamConnection connection = null;
// setup the server to listen for connection
try {
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.GIAC);
UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
System.out.println(uuid.toString());
String url = "btspp://localhost:" + uuid.toString()
+ ";name=RemoteBluetooth";
notifier = (StreamConnectionNotifier) Connector.open(url);
} catch (BluetoothStateException e) {
System.out.println("Bluetooth is not turned on.");
e.printStackTrace();
return;
}
// ...
}
}
To run or produce it, I have just put the bluecove library in the build path and created the fat jar with a simple way:
http://oi60.tinypic.com/vg1jpt.jpg
Starting the generated jar from command line:
D:\testProjects\bttest>java -jar bttest_fat.jar
BlueCove version 2.1.0 on winsock
0000110100001000800000805f9b34fb
BlueCove stack shutdown completed
Can you post a difference to your process?
I'm in the process of making a proof of concept to dissociate the business code from the gui for the ps3 media server (http://www.ps3mediaserver.org/). For this I've got a project hosted at source forge (http://sourceforge.net/projects/pms-remote/). The client should be a simple front end to configure the server from any location within a network having the rights to connect to the server.
On the server side, all service have been exposed using javax.jws and the client proxy has been generated using wsimport.
One of the features of the current features (actually, the only blocking one), is to define the folders that will be shared by the server. As the client and server are now running as a single application on the same machine, it's trivial to browse its file system.
Problem: I'd like to expose the file system of the server machine through web services. This will allow any client (the one I'm currently working on is the same as the original using java swing) to show available folders and to select the ones that will be shown by the media server. In the end the only thing I'm interested in is an absolute folder path (string).
I thought I'd find a library giving me this functionality but couldn't find any.
Browsing the files using a UNC path and accessing a distant machine doesn't seem feasible, as it wouldn't be transparent for the user.
For now I don't want to worry about security issues, I'll figure these out once the rest seems feasible.
I'd be grateful for any input.
Thanks, Philippe
I've ended up creating a pretty simple web service letting either list all root folders or all child folders for a given path.
It's now up to the client to have a (GUI) browser to access this service.
package net.pms.plugin.webservice.filesystem;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import net.pms.plugin.webservice.ServiceBase;
#WebService(serviceName = "FileSystem", targetNamespace = "http://ps3mediaserver.org/filesystem")
public class FileSystemWebService extends ServiceBase {
#WebMethod()
public List<String> getRoots() {
List<String> roots = new ArrayList<String>();
for(File child : File.listRoots()) {
roots.add(child.getAbsolutePath());
}
return roots;
}
#WebMethod()
public List<String> getChildFolders(#WebParam(name="folderPath") String folderPath) throws FileNotFoundException {
List<String> children = new ArrayList<String>();
File d = new File(folderPath);
if(d.isDirectory()) {
for(File child : d.listFiles()) {
if(child.isDirectory() && !child.isHidden()) {
children.add(child.getAbsolutePath());
}
}
} else {
throw new FileNotFoundException();
}
return children;
}
}
For people wanting to use this, here's the ServiceBase class as well
package net.pms.plugin.webservice;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
public abstract class ServiceBase {
private static final Logger log = Logger.getLogger(ServiceBase.class);
protected boolean isInitialized;
/**
* the published endpoint
*/
private Endpoint endpoint = null;
/**
*
* Start to listen for remote requests
*
* #param host ip or host name
* #param port port to use
* #param path name of the web service
*/
public void bind(String host, int port, String path) {
String endpointURL = "http://" + host + ":" + port + "/" + path;
try {
endpoint = Endpoint.publish(endpointURL, this);
isInitialized = true;
log.info("Sucessfully bound enpoint: " + endpointURL);
} catch (Exception e) {
log.error("Failed to bind enpoint: " + endpointURL, e);
}
}
/**
* Stop the webservice
*/
public void shutdown() {
log.info("Shut down " + getClass().getName());
if (endpoint != null)
endpoint.stop();
endpoint = null;
}
}
From the client, you might be able to leverage the output of smbclient -L. On the server, a suitable servlet might do.