Spring/Java can not find main method - java

I try to write a simple Spring 3 console application. I Cant get this application to run, i always get the error, that there is no main method.
My system is an Ubuntu 12.04 with openjdk-7 installed, and the sts 2.9.2-release.
A simple hello world runs without any problems Edit:(i tested a other project to prove a simple hello world would run).
The Project is managed over maven and i got no errors so far.
I try to reproduce an exsample of a book as follow:
XmlConfigWithBeanFactory.java
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.FileSystemResource;
public class XmlConfigWithBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader rdr = new XmlBeanDefinitionReader(factory);
rdr.loadBeanDefinitions(new FileSystemResource(
"src/xmlBeanFactory.xml"));
Oracle oracle = (Oracle) factory.getBean("oracle");
System.out.println(oracle.defineMeaningOfLife());
}
}
Oracle.java
public interface Oracle {
public String defineMeaningOfLife();
}
BookwormOracle.java
public class BookwormOracle implements Oracle {
public String defineMeaningOfLife() {
return "Encyclopedias are a waste of money - use the Internet";
}
}
xmlBeanFactory.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- oracle bean used for a few examples -->
<bean id="oracle" name="wiseworm" class="BookwormOracle"/>
</beans>
If you want i can also post the maven pom.xml, but i think there is no error all packages are loaded and linked.
I am happy for any hint google and other pages cant help me.
Here is a other example what i am trying to do : http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application
And even this post Java can't find method main did not help me
Do i have to start this application as Java Application or AspectJ/JavaApplication. Is it not possible to start a console application that way from eclipse ? Do i need to publish my files to a server ( "add to server" but this isnt working too)?
Whats confused me most is, that i see the main method :) and it is the same syntax as any hello world application.
Thanks so far...

I used all the java files and XML files and made it run in my system. It's working perfectly after fixing two errors, Next time when you post the question please do post the exception or the error message which you get.
I got two error's when I ran the project
First Error:
which was related to not having "commons-logging" jar file.
I downloaded the jar file and placed it under the build path.
You can find the solution here. You also need to change your pom.xml
Which will be now,
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test.testapp</groupId>
<artifactId>testapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
</project>
Second Error:
The xmlBeanFactory.xml was refering to a different Spring version.
I changed to Spring-2.5.jar and updated my build path.
That's it, now the project runs.

Right click on "XmlConfigWithBeanFactory.java" in the package explorer, and select "Run as Java Application". That should work.

Related

My IDE is not recognizing HTML commands for my servlet [duplicate]

This question already has answers here:
How do I import the javax.servlet / jakarta.servlet API in my Eclipse project?
(16 answers)
Closed 1 year ago.
I am learning how to create a servlet that takes HTML code and makes a program in my browser.
This code was supposed to output a simple welcome message in my browser via HTML. However, My eclipse IDE does not recognize any of the HTML commands in this code. It says that the imports are not accessible and that the HTTP variables can't be resolved to a type. I'm using tomcat version 10.0.12 and Java 13 for the code (I also have java 16 but eclipse only gave me the option to use 13). I've tried uninstalling and reinstalling Tomcat several times and adding servlet-api.jar but none of those changed a thing. I know there's an extra step I'm missing but I can't figure out what it is?
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;
public class WelcomeServlet extends HttpServlet {
#Override
protected void doGet( HttpServletRequest request,
HttpServletResponse response ) throws ServletException, IOException {
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
out.println( "<title>Welcome to Servlets!</title>" );
{...}
out.println( "</html>" );
out.close(); // close stream to complete the page
}
}
You've messed up your imports. It sounds like you're following a tutorial that's 20+ years old, a lot of what you're doing is extremely outdated. The web is a fairly fast moving environment; I strenously advise against using such old tutorials.
The correct import is import javax.servlet.http.HttpServletRequest;.
Some notes on what you're doing that are bad ideas:
Star imports aren't advised; it's a bit too easy to get confused about where things live or which type(s) you are fetching from where. Your IDE manages your imports for you; let it.
You don't want to write HTML inside strings inside your code. Use a templating engine such as Freemarker, Velocity, Thymeleaf, or Google Closure Templates. Alternatively, write static HTML with a ton of javascript (probably with a client-side javascript-based framework) and write your server as an API that doesn't 'answer' in terms of HTML files; it answers in terms of some structured data format such as JSON. Your static (as in, unchanging; any file-serving HTTP service can provide them) HTML+CSS+Javascript does the job of calling your API to get this structured data, and then your HTML+CSS+JavaScript does the job of rendering it into HTML.
Raw servlets is outdated; the API is extremely old and it shows, for example, you can't even use a simple for-each loop to iterate over all parameter names, because the API returns the obsolete Enumeration instead of the more modern Iterator or even Stream. You neither get the benefit of storing intermediate state in fields (because you aren't guaranteed one instance per invocation), but you also don't get to just dump it all in static fields either (as the spec doesn't guarantee that there'll only ever be one instance) - the worst of both worlds. Look into JAX-RS, Jersey, Dropwizard, sparkjava, or other such frameworks.
tl;dr
Your project lacks a JAR containing the definition of the Jakarta Servlet API (a set of interfaces).
Add jakarta.servlet-api as a dependency to your project, to present to your IDE the needed JAR file during development but omitted from your final build’s WAR file.
Details
Your import statements refer to the Jakarta Servlet API. That API is not built into Java. So you must make a Servlet API JAR file available to your IDE while developing.
Typically in Java development we use a tool such as Maven or Gradle to assist our IDE in obtaining external dependencies such as the Servlet API JAR.
If you are using Maven, edit your POM file to specify a dependency for the Servlet API JAR published as part of the Jakarta.ee project, by the Eclipse Foundation.
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
Notice the scope element, with a value of provided. This means the JAR file should be downloaded, made available to your IDE while developing, but should not be copied into your resulting product when you build.
The output of your build will typically be a WAR file (not JAR). The provided scope means we do not want a copy of the Servlet API JAR within that WAR. The reason is that when developing Jakarta EE web apps, we expect to deploy to a compliant application server that carries its own copy of the Servlet API. Every “profile” of Jakarta EE compliant servers are required to include an implementation of the Servlet API.
So your POM will look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>work.basil.example</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>demo</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
And here is the source code for a simple servlet.
package work.basil.example.demo;
import java.io.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
#WebServlet ( name = "helloServlet", value = "/hello-servlet" )
public class HelloServlet extends HttpServlet
{
private String message;
public void init ( )
{
message = "Hello World!";
}
public void doGet ( HttpServletRequest request , HttpServletResponse response ) throws IOException
{
response.setContentType( "text/html" );
// Hello
PrintWriter out = response.getWriter();
out.println( "<html><body>" );
out.println( "<h1>" + message + "</h1>" );
out.println( "</body></html>" );
}
public void destroy ( )
{
}
}
You said:
I've tried uninstalling and reinstalling Tomcat several times
Completely unrelated to your problem, I expect.
The installation of Tomcat comes with an implementation of the Servlet API. But your IDE does not “see” Tomcat during development. Your IDE needs to see the interfaces defined in the Servlet API.
Your IDE does not actually execute your servlet, so it does not need an implementation, it needs only the interfaces. When you run your Servlet from the IDE, Tomcat is invoked externally from the IDE. The IDE attaches a debugger connection to Tomcat to facilitate interactive debugging, but the IDE and Tomcat are actually running as separate distinct processes on the host OS. And as I said, Tomcat comes bundled with its own implementation of those interfaces, so your servlet is able to execute.
You said you are using Java 13. Be aware that Java 13 is no longer supported. You should move to either the latest version of Java (17, as of 2021-11), or to one of the Long-Term Support (LTS) versions (8, 11, 17).
If using Java 11 or 17 rather than 8, I would suggest using Tomcat 10.1.x rather than Tomcat 10.0.x. Tomcat 10.1.x supports Jakarta EE 9.1 and 10, which supports Java 11 and later versus Java 8.
See the Tomcat version comparison page.

OCR tessdata directory is incorrect

I've been following this tutorial for trying to create an OCR and I've copy and pasted all of the necessary code and followed the steps but I keep receiving this error when I run OCRDemo.java:
Error opening data file ./eng.traineddata
Please make sure the TESSDATA_PREFIX environment variable is set to your "tessdata" directory.
Failed loading language 'eng'
Tesseract couldn't load any languages!
So I'm assuming the issue is that TESSDATA_PREFIX has the wrong directory. Currently it is "C:\CodeRepository\OCR\tessdata" and I got that directory and confirmed that directory by literally going into file explorer and copying and pasting it. But I keep getting this error message. I've also tried "OCR\tessdata", "tessdata" but none of them work. Help?
Here's my pom.xml code that has the TESSDATA_PREFIX:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>OCR</groupId>
<artifactId>OCR</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<TESSDATA_PREFIX>C:\CodeRepository\OCR\tessdata</TESSDATA_PREFIX>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>
</project>
From the given link, it looks like it points the readers to incompatible language data files. Try https://github.com/tesseract-ocr/tessdata_fast.
ITesseract instance = new Tesseract();
instance.setDatapath("C:\\Users\\Tux\\Documents\\tessdata");
this worked for me without the need for setting environment variables. I just put the language file in the 'tessdata' folder

Maven with an explicit finalName won't work properly

1. Background
My maven project has a lot of modules and submodules with jars and wars and everything works. I also can deploy it on server without any problem.
I decided to follow this maven naming conversion, I am making some tests with project.name and project.build.finalName to have an appropriate name.
The pattern I defined to create project.name for the root artifact is company-${project.artifactId} and for the modules and sub-modules is ${project.parent.name}-${project.artifactId}:
company-any-artifact-any-module1
company-any-artifact-any-module2-any-submodule1
company-any-artifact-any-module2-any-submodule2
The pattern for project.build.finalName is ${project.name}-${project.version}:
company-any-artifact-any-module1-1.0.jar
company-any-artifact-any-module2-any-submodule1-2.0.jar
company-any-artifact-any-module2-any-submodule2-3.0.war
But instead of producing these files, maven gives me a StackOverflowError.
2. The example to reproduce the error
You can clone this example from github: https://github.com/pauloleitemoreira/company-any-artifact
In github, there is the master branch, that will reproduce this error. And there is only-modules branch, that is a working example that uses ${project.parent.name} to generate the jar finalName as I want.
Let's consider a maven project with one root pom artifact, one pom module and one submodule.
-any-artifact
|
|-any-module
|
|-any-submodule
2.1 any-artifact
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>any-artifact</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>company-${project.artifactId}</name>
<modules>
<module>any-module</module>
</modules>
<!-- if remove finalName, maven will not throw StackOverflow error -->
<build>
<finalName>${project.name}-${project.version}</finalName>
</build>
</project>
2.2 any-module
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>any-artifact</artifactId>
<groupId>com.company</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.company.any-artifact</groupId>
<artifactId>any-module</artifactId>
<packaging>pom</packaging>
<name>${project.parent.name}-${project.artifactId}</name>
<modules>
<module>any-submodule</module>
</modules>
</project>
2.3 any-submodule
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>any-module</artifactId>
<groupId>com.company.any-artifact</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.company.any-artifact.any-module</groupId>
<artifactId>any-submodule</artifactId>
<name>${project.parent.name}-${project.artifactId}</name>
</project>
3. Problem
When try to mvn clean install, maven gives me a StackOverflowError:
Exception in thread "main" java.lang.StackOverflowError
at org.codehaus.plexus.util.StringUtils.isEmpty(StringUtils.java:177)
at org.codehaus.plexus.util.introspection.ReflectionValueExtractor.evaluate(ReflectionValueExtractor.java:194)
at org.codehaus.plexus.util.introspection.ReflectionValueExtractor.evaluate(ReflectionValueExtractor.java:163)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:266)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:429)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:429)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:174)
at org.apache.maven.plugin.PluginParameterExpressionEvaluator.evaluate(PluginParameterExpressionEvaluator.java:143)
It is important to know that the error occurs only when we are working with submodules. If we create a project with a root POM artifact and a jar module, the error don't occur.
4. The question
Why this error occurs only when we are using submodules?
Any suggestion to solve my problem? Should I forget it and set project.name and project.build.fileName manually for each project, following the pattern I want?
IMPORTANT UPDATED:
Some answers just say to use &{parent.name}, but it does not work. Please, it is a question with a bounty, consider test your solution with Maven version 3.3.9, before answering this question.
Maven version 3.3.9
Edit - Adding details to the question with the phase when the error occurs, things are working fine until the prepare-package phase, but the StackOverflow occurs at the package phase on maven lifecycle for the project.
The strict answer to your question is that ${project.parent.name} will not be resolved as part the model interpolation process. And in turn, you have a StackOverflowError, in a completely different place of the code, namely when... building the final JAR of your project.
Part 1: The Model built is wrong
Here's what happens. When you're launching a Maven command on a project, the first action it takes is creating the effective model of the project. This means reading your POM file, reasoning with activated profiles, applying inheritance, performing interpolation on properties... all of this to build the final Maven model for your project. This work is done by the Maven Model Builder component.
The process of building the model is quite complicated, with a lot of steps divided in possibly 2 phases, but the part we're interested in here in the model interpolation part. This is when Maven will replace in the model all tokens denoted by ${...} with a calculated value. It happens after profiles are injected, and inheritance is performed. At that point in time, the Maven project, as represented by a MavenProject object, doesn't exist yet, only its Model is being built. And it is only after you have a full model that you can start constructing the Maven project from it.
As such, when interpolation is done, it only reasons in terms of the information present in the POM file, and the only valid values are the ones mentioned in the model reference. (This replacement is performed by the StringSearchModelInterpolator class, if you want to look at the source code.) Quite notably, you will notice that the <parent> element in the model does not contain the name of the parent model. The class Model in Maven is actually generated with Modello from a source .mdo file, and that source only defines groupId, artifactId, version and relativePath (along with a custom id) for the <parent> element. This is also visible in the documentation.
The consequence of all that, is that after model interpolation is performed, the token ${project.parent.name} will not be replaced. And, further, the MavenProject constructed from it will have a name containing ${project.parent.name} unreplaced. You can see this in the logs, in your sample project, we have
[INFO] Reactor Build Order:
[INFO]
[INFO] company-any-artifact
[INFO] ${project.parent.name}-any-module
[INFO] ${project.parent.name}-any-submodule
Meaning that Maven consider the actual name of the project any-module to be ${project.parent.name}-any-module.
Part 2: The weirdness begins
We're now at a time when all of the projects in the reactor were correctly created and even compiled. Actually, everything should theoretically work just fine, but with only completely borked names for the projects themselves. But you have a strange case, where it fails at the creation of the JAR with the maven-jar-plugin. The build fails in your example with the following logs:
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) # any-submodule ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] company-any-artifact ............................... SUCCESS [ 0.171 s]
[INFO] ${project.parent.name}-any-module .................. SUCCESS [ 0.002 s]
[INFO] ${project.parent.name}-any-submodule ............... FAILURE [ 0.987 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
meaning that something went wrong well after the model was built. And the reason is that the plugin injects the name of the project as a parameter:
/**
* Name of the generated JAR.
*
* #parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}"
* #required
*/
private String finalName;
Notice project.build.finalName as the default value of the generated JAR name for the submodule. This injection, and the interpolation of the variables are done by another class called PluginParameterExpressionEvaluator.
So what happens in this:
The JAR plugin on the any-submodule injects the final name of the project, named ${project.parent.name}-any-submodule.
Thanks for inheritance from the parent projects, and the declaration of <finalName> in your top-most POM project, it inherits <finalName>${project.name}-${project.version}</finalName>.
Maven now tries to interpolate ${project.name} for any-submodule.
This resolves to ${project.parent.name}-any-submodule, due to Part 1.
Maven tries now to interpolate ${project.parent.name} for any-submodule. This works correctly: the MavenProject is built and getParent() will be called on the project instance, returning the concrete Maven parent project. As such, ${project.parent.name} will try to resolve the name of any-module, which is actually ${project.parent.name}-any-module.
Maven now tries to interpolate ${project.parent.name}-any-module, but still on the any-submodule project instance. For PluginParameterExpressionEvaluator, the root "project" on which to evaluate tokens hasn't changed.
Maven now tries to interpolate ${project.parent.name} on any-submodule, which, again, works correctly and returns ${project.parent.name}-any-module.
Maven now tries to interpolate ${project.parent.name} on any-submodule... which works and returns ${project.parent.name}-any-module so it tries to evaluate ${project.parent.name}...
And you can see the endless recursion happening here, which results in the StackOverflowError you have. Is this a bug in PluginParameterExpressionEvaluator? This is unclear: it reasons on model values that were not correctly replaced in the first place. In theory, it could handle the special case of evaluating ${project.parent} and create a new PluginParameterExpressionEvaluator working on this parent project, instead of always working on the current project. If you feel strongly about this, feel free to create a JIRA issue.
Part 3: Why it works without the sub module
With what has been said above, you could now deduce why it works in this case. Let's reason with what Maven needs to do to evaluate the final name, as has to be injected in the Maven Jar Plugin:
The JAR plugin on the any-module injects the final name of the project, named ${project.parent.name}-any-module.
Thanks for inheritance from the parent project, and the declaration of <finalName> in your top-most POM project, it inherits <finalName>${project.name}-${project.version}</finalName>.
Maven now tries to interpolate ${project.name} for any-module.
This resolves to ${project.parent.name}-any-module, same as before.
Maven tries now to interpolate ${project.parent.name} for any-module. Just like before, this works correctly: the MavenProject is built and getParent() will be called on the project instance, returning the concrete Maven parent project. As such, ${project.parent.name} will try to resolve the name of any-artifact, which is actually company-any-artifact.
Interpolation has succeeded and stops.
And you don't have any errors.
As I stated in my answer to Difference between project.parent.name and parent.name ans use of finalName in pom.xml
Let's first look at the basics:
as stated in POM Reference:
finalName: This is the name of the bundled project when it is finally built (sans the file extension, for example: my-project-1.0.jar). It defaults to ${artifactId}-${version}.
name: Projects tend to have conversational names, beyond the artifactId.
So these two have different uses.
name is purely informational and mainly used for generated documentation and in the build logs. It is not inherited nor used anywhere else. It is a human readable String and can thus contain any character, i.e. spaces or characters not allowed in filenames. So, this would be valid: <name>My Turbo Project on Speed!</name>. Which is clearly at least a questionable file name for an artifact.
as stated above, finalName is the name of the generated artifact. It is inherited, so it should usually rely on properties. The only two really useful options are the default ${artifactId}-${version} and the versionless ${artifactId}. Everything else leads to confusion (such as a project named foo creating an artifact bar.jar). Actually, My turbo Project! would be valid, since this is a valid filename, but in reality, filenames like that tend to be rather unusable (try adressing a filename containing ! from a bash, for example)
So, as to why the Stackoverflow happens:
name is not inherited
project.parent.name also is not evaluated during interpolation, since the name is one of the few properties which are completey invisible to the children
parent.name actually used to work in older Maven versions, but more due to a bug (also it is deprecated to access properties without the leading project).
a missing property is not interpolated, i.e. stays in the model as is
Therefore, in your effective pom for any-submodule, the value for finalName is (try it with mvn help:effective-pom) still: ${project.parent.name}-any-submodule
So far so bad. Now comes the reason for the StackOverflow
Maven has an addtional feature called late interpolation that evaluates values in plugin parameters when they are actually used. This allows a pluing to use properties that are not part of the model, but are generated by plugins earlier in the lifecycle (this allows, for instance plugins to contribute a git revision to the final name).
So what happens is this:
edit: made the actual reason for the error clearer (see comments):
The finalName for the jar plugin is evaluated:
#Parameter( defaultValue = "${project.build.finalName}", readonly = true )
The PluginParameterExpressionEvaluator kicks in and tries to evaluate the final name (${project.parent.name}-any-submodule, which contains a property expression ${project.parent.name}.
The evaluator asks the model, which in turn returns the name of the parent project, which is: ${project.parent.name}-any-module.
So the evaluator tries to resolve this, which return ${project.parent.name}-any-module (again), since a property is always resolved against the current project, the cycle begins again.
A StackOverflowError is thrown.
How to solve this
Sadly, you can't.
You need to explicitly specify name (as well as artifactId) for every project. There is no workaround.
Then, you could let finalName rely on it. I would however advise against it (see my answer to Difference between project.parent.name and parent.name ans use of finalName in pom.xml)
The problem in changing the final name that way is that the name of the locally build artifact and the one in the repository would differ, so locally your artifact is named any-artifact-any-module-any-submodule.jar, but the artifact name in your repository would be still any-submodule.jar
Suggestion
If you really need to differentiate that fine, change the artifactId instead: <artifactId>artifact-anymodule-anysubmodule</artifactId>.
Don't use dashes for the shortname to differentiate between levels of your structure.
hint: the path of the module can be still anymodule, is does not need to be the actual artifactId of the module!
While we are at it: use the name for what it was intended, to be human readable, so you might consider something more visually appealling (since this is the name that appears in the build log): <name>Artifact :: AnyModule :: AnySubModule</name>.
It is actually very easy to simply create the name entries automatically using a very short groovy script.
You could also write an enforce rule to enforce the naming of the artifactIds
This is issue with attribute inheritance.
Try to use ${parent.name} instead of ${project.parent.name}.
Look at: Project name declared in parent POM isn't expanded in a module filtered web.xml.
---UPDATE---
Benjamin Bentmann (maven committier) said: "In general though, expressions of the form ${project.parent.*} are a bad practice as they rely on a certain build state and do not generally work throughout the POM, giving rise to surprises".
https://issues.apache.org/jira/browse/MNG-5126?jql=text%20~%20%22parent%20name%22
Maybe you should consider is using ${project.parent.*} is a good way.
change pom.xml in company-any-artifact to below and it will work .
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>any-artifact</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>${project.groupId}</name>
<modules>
<module>any-module</module>
</modules>
<!-- if remove finalName, maven will not throw StackOverflow error -->
<build>
<finalName>${project.groupId}-${project.version}</finalName>
</build>
</project>
change pom.xml in submodule to below
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>any-artifact</artifactId>
<groupId>com.company</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.company.any-artifact</groupId>
<artifactId>any-module</artifactId>
<packaging>pom</packaging>
<!-- <name>${project.parent.name}-${project.artifactId}</name> -->
<modules>
<module>any-submodule</module>
</modules>
<build>
<finalName>${project.parent.name}-${project.artifactId}</finalName>
</build>
</project>
change submodule pom.xml to below
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>any-module</artifactId>
<groupId>com.company.any-artifact</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.company.any-artifact.any-module</groupId>
<artifactId>any-submodule</artifactId>
<!-- <name>${project.parent.name}-${project.artifactId}-${project.version}</name> -->
<build>
<finalName>company-${project.parent.name}-${project.artifactId}-${project.version}</finalName>
</build>
</project>
then the output was : company-any-module-any-submodule-1.0-SNAPSHOT
Interesting! I started off cloning the repo and reproducing the error. I would appreciate any leads that can be taken from any of the steps mentioned below that helped me debug the problem -
Maven Life Cycle Phases
The phase where the issue occurred was the package phase of the lifecycle. Meaning mvn package reproduces the issue with your project.
Went through the stack trace lines in the error. Getting to know its the expression evaluation where it's failing -
#Override
public Object evaluate( String expr ) throws ExpressionEvaluationException {
return evaluate( expr, null ); // Line 143
}
It's also not the finalName attribute which was causing it. Since specifying the default value of the same
<finalName>${artifactId}-${version}</finalName>
works fine with the same project configs.
Then tried changing the packaging of the any-submodule as
<packaging>pom</packaging>
and the error went away. Meaning while packaging as jar , war etc the expression evaluation is different and results in an overflow.
Modifying the any-module or the any-submodule pom.xml content I can say with some confidence that it's the project.parent.name that is causing a recursion in evaluating the expression and causing the stack overflow(How? - is something I am still looking for..). Also, changing
<name>${project.parent.name}-${project.artifactId}</name>
to
<name>${parent.name}-${project.artifactId}</name>
works for me in the sense that I do not get an error but the jar generated is of type -
${parent.name}-any-module-any-submodule-1.0-SNAPSHOT.jar and
${parent.name}-any-submodule-1.0-SNAPSHOT respectively with the change.
Looking for the solution according to the requirement, I am seeking a tail to the recursion that you are using.
Note - Still working on finding an appropriate solution to this problem.

Missing schema definitions in IntelliJ

Having updated to IntelliJ 14.0.3 Community Edition I am working on a new web project, but suddenly IntelliJ does not find the most basic schema definitions anymore. Here are examples: http://i.stack.imgur.com/FVYld.png and http://i.stack.imgur.com/SboLZ.png.
I have tried to 'Fetch External Resource', but with no success.
Using this approach "JSF xmlns URI not registered in IntelliJ IDEA" I imported web-facelettaglibrary_2_2.xsd, but the auto competition had errors and was useless.
I try to get this to work for weeks now and get 'URI is not registered' and 'Cannot resolve symbol' errors all over the place. How IntelliJ can be unaware of these URIs is completely beyond me.
Can someone please help me get my beloved auto competition up and running again?
Update:
I finally got the web-app schema working by adding web-app_3_1.xsd and every file it references and their references as well, namely:
javaee_7.xsd
javaee_web_services_client_1_4.xsd
jsp_2_3.xsd
web-app_3_1.xsd
web-common_3_1.xsd.
All from here: hxxp://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html
I have tried the same (with the firewall blocking all IntelliJ's external connections) and this worked for me:
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"></web-app>
pom.xml
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
From Java EE Schemas download the definition web-app_3_1.xsd. In IntelliJ manually add an external resource and select the file you just downloaded. You can also see it under Settings > Languages & Frameworks > Schemas and DTDs in the list of external schemas.

Wildfly looking in wrong directory

I recently startet working with JBoss' Wildfly 8.1 and the activiti framework.
I created two projects, one with my bpmn.xml file and the classes for the Service Tasks:
Process:
-src/main/
-impl.java
-src/resources/
-diagrams
-myprocess.bpmn.xml
-config
-activiti-context.xml
The other one holds the servlet
WebTest:
-src/main
-testServlet.java
-lib
-process.jar
in my servlet i implemented the init method to get the Activiti processEngine:
#Override
public void init() throws ServletException{
super.init();
engine = ProcessEngines.getDefaultProcessEngine();
}
I build the Webtest.war file and deploy it to
D:/path/to/workingdir/wildfly-8.1.0.Final/**standalone/deployments**/Webtest.war
Then i start up Widlfly using the provided standalone.bat, it starts up correctly and deploys to the context /Webtest, so far so good.
if i now access localhos:8080/Webtest/servlet i get the Exception:
org.activiti.engine.ActivitiException: couldn't initialize process engine from spring configuration resource vfs:/D:/path/to/workingdir/wildfly-8.1.0.Final/bin/content/TEST-1.war/WEB-INF/lib/process.jar/activiti-context.xml: null
the error with :null at the end implies that the file could not be accessed. of course it cannot, there is no bin/content!
my question now is: where does Widlfly get the idea to look at bin/content? it obviously was able to find the config file on itself, i never told spring or activiti to look in the process.jar, so the app finds the configuration in the classpath alright... then it proceeds to reading the file from an entirely different location that does not exist?
I dont know if this is of interesst, but here is my activiti-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"/>
</beans>
thanks for any help or hints!

Categories